From 73d3dc48412c20da6c9e34fc137ed39a2e7adf30 Mon Sep 17 00:00:00 2001 From: Jens Troeger Date: Thu, 3 Aug 2023 06:50:47 +1000 Subject: [PATCH 1/2] feat: introduce the Ruff pre-commit hook to replace a bunch of other code formatters and linter hooks --- .flake8 | 52 ------------------------ .pre-commit-config.yaml | 61 +++-------------------------- Makefile | 12 +++--- pyproject.toml | 42 +++++++++++++++++++- tests/integration/test_something.py | 8 ++-- 5 files changed, 55 insertions(+), 120 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 8f61d111..00000000 --- a/.flake8 +++ /dev/null @@ -1,52 +0,0 @@ -# Unfortunately, Flake8 does not support pyproject.toml configuration. -# https://github.com/PyCQA/flake8/issues/234 -# -# More details regarding Flake8 and Black interplay: -# https://github.com/psf/black/blob/main/docs/guides/using_black_with_other_tools.md#flake8 -[flake8] - -# Enable a few additional checks. -# -# https://github.com/PyCQA/flake8-bugbear#how-to-enable-opinionated-warnings -# B9: Bugbear's extended opinionated checks -# -# https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes -# W504: line break after binary operator (Black compliant) -extend-select = B9, W504 - -# Disable several warnings that don't play nice with PEP8 or Black, -# or that are a bit of a nuisance in general. -# -# http://www.pydocstyle.org/en/latest/error_codes.html -# D105: Missing docstring in magic method -# -# https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes -# E203: whitespace before ‘,’, ‘;’, or ‘:’ (not Black compliant) -# E501: line too long (managed better by Bugbear's B950) -# W503: line break before binary operator (not Black compliant) -# -# https://github.com/peterjc/flake8-rst-docstrings#configuration -# RST307: Error in "XXX" directive -ignore = D105, E203, E501, RST307, W503 -per-file-ignores = - -# More assorted goodness. -max-line-length = 120 -show-source = true - -# Ensure that Flake8 warnings are silenced correctly: -# https://github.com/plinss/flake8-noqa#options -noqa-require-code = true - -# Ensure that Sphinx extensions of .rst are recognized: -# https://github.com/peterjc/flake8-rst-docstrings#configuration -rst-roles = class, func, ref -rst-directives = envvar, exception -rst-substitutions = version - -# Ensure that Sphinx docstrings use Numpy format for docstrings: -# https://github.com/PyCQA/flake8-docstrings -# -# For details on the Numpy format: -# https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html -docstring-convention = numpy diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9f0d551d..dc482e03 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,50 +21,14 @@ repos: name: Check conventional commit message stages: [commit-msg] -# Sort imports. -- repo: https://github.com/pycqa/isort - rev: dac090ce4d9ee313d086e2e89ab1acb8c2664fa1 # frozen: 9.0.0a3 +# Ruff formats and lints code. +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: 3b3f7c3f57fe9925356faf5fe6230835138be230 # frozen: v0.15.17 hooks: - - id: isort - name: Sort import statements - args: [--settings-path, pyproject.toml] - stages: [pre-commit] - -# Add Black code formatters. -- repo: https://github.com/ambv/black - rev: c6755bb741b6481d6b3d3bb563c83fa060db96c9 # frozen: 26.3.1 - hooks: - - id: black - name: Format code + - id: ruff-format args: [--config, pyproject.toml] -- repo: https://github.com/asottile/blacken-docs - rev: dda8db18cfc68df532abf33b185ecd12d5b7b326 # frozen: 1.20.0 - hooks: - - id: blacken-docs - name: Format code in docstrings - args: [--line-length, '120'] - additional_dependencies: [black==26.3.1] - -# Upgrade and rewrite Python idioms. -- repo: https://github.com/asottile/pyupgrade - rev: 75992aaa40730136014f34227e0135f63fc951b4 # frozen: v3.21.2 - hooks: - - id: pyupgrade - name: Upgrade code idioms - files: ^src/package/|^tests/ - args: [--py310-plus] - -# Similar to pylint, with a few more/different checks. For more available -# extensions: https://github.com/DmytroLitvinov/awesome-flake8-extensions -- repo: https://github.com/pycqa/flake8 - rev: d93590f5be797aabb60e3b09f2f52dddb02f349f # frozen: 7.3.0 - hooks: - - id: flake8 - name: Check flake8 issues - files: ^src/package/|^tests/ - types: [text, python] - additional_dependencies: [flake8-bugbear==25.11.29, flake8-builtins==3.1.0, flake8-comprehensions==3.17.0, flake8-docstrings==1.7.0, flake8-logging==1.8.0, flake8-mutable==1.2.0, flake8-noqa==1.4.0, flake8-print==5.0.0, flake8-pyi==25.5.0, flake8-pytest-style==2.2.0, flake8-rst-docstrings==0.4.0, pep8-naming==0.15.1] - args: [--config, .flake8] + - id: ruff-check + args: [--config, pyproject.toml, --fix, --exit-non-zero-on-fix] # Run Pylint from the local repo to make sure venv packages # specified in pyproject.toml are available. @@ -89,17 +53,6 @@ repos: types: [text, python] args: [--explicit-package-bases, --config-file, pyproject.toml] -# Check for potential security issues. -- repo: https://github.com/PyCQA/bandit - rev: 92ae8b82fb422a639f0ed8d99e96cea769594e08 # frozen: 1.9.4 - hooks: - - id: bandit - name: Check for security issues - args: [--configfile, pyproject.toml] - files: ^src/package/|^tests/ - types: [text, python] - additional_dependencies: ['bandit[toml]'] - # Enable a whole bunch of useful helper hooks, too. # See https://pre-commit.com/hooks.html for more hooks. - repo: https://github.com/pre-commit/pre-commit-hooks @@ -146,8 +99,6 @@ repos: - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks rev: 4380fbb73a154b5f5624794c1c78d9719ccc860f # frozen: v2.16.0 hooks: - - id: pretty-format-ini - args: [--autofix] - id: pretty-format-yaml args: [--autofix] # Commenting this out because https://github.com/pappasam/toml-sort/issues/11 diff --git a/Makefile b/Makefile index b1827425..25941f54 100644 --- a/Makefile +++ b/Makefile @@ -161,12 +161,10 @@ audit: python -m pip_audit --skip-editable --desc on --fix --dry-run # Run some or all checks over the package code base. -.PHONY: check check-code check-bandit check-flake8 check-lint check-mypy check-actionlint -check-code: check-bandit check-flake8 check-lint check-mypy check-actionlint -check-bandit: - pre-commit run bandit --all-files -check-flake8: - pre-commit run flake8 --all-files +.PHONY: check check-code check-ruff check-lint check-mypy check-actionlint +check-code: check-ruff check-lint check-mypy check-actionlint +check-ruff: + pre-commit run ruff --all-files check-lint: pre-commit run pylint --all-files check-mypy: @@ -259,7 +257,7 @@ dist-clean: rm -fr dist/* rm -f requirements.txt clean: dist-clean - rm -fr .coverage .hypothesis/ .mypy_cache/ .pytest_cache/ + rm -fr .coverage .hypothesis/ .mypy_cache/ .pytest_cache/ .ruff_cache/ rm -fr docs/_build/ # Remove code caches, or the entire virtual environment. diff --git a/pyproject.toml b/pyproject.toml index 246a424d..4a8c08f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ hooks = [ test = [ "faker ==40.19.1", "hypothesis >=6.21.0,<6.152.10", - "pytest >=9.0.3,<10.0.0", + "pytest >=9.0.3,<9.1.0", "pytest-benchmark ==5.2.3", "pytest-cases ==3.10.1", "pytest-custom_exit_code ==0.3.0", @@ -175,6 +175,7 @@ ignore_missing_imports = true # https://pylint.pycqa.org/en/latest/user_guide/configuration/index.html +# https://github.com/astral-sh/ruff/issues/970 [tool.pylint.main] fail-under = 10.0 load-plugins = [ @@ -274,3 +275,42 @@ markers = [ "integration: more complex application-level integration tests.", "performance: performance tests.", ] + + +# https://docs.astral.sh/ruff/formatter/ +# https://docs.astral.sh/ruff/linter/ +[tool.ruff] +line-length = 120 + +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 88 + +# https://docs.astral.sh/ruff/configuration/ +# https://docs.astral.sh/ruff/rules/ +[tool.ruff.lint] +exclude = ["docs/*"] +select = [ + "E", # pycodestyle + "F", # pyflakes + "I", # isort + "UP", # pyupgrade + "B", # flake8-bugbear + "A", # flake8-builtins + "C4", # flake8-comprehensions + "LOG", # flake8-logging + "T20", # flake8-print + "PYI", # flake8-pyi + "PT", # flake8-pytest-style + "N", # pep8-naming + "S", # flake8-bandit +] +ignore = [ + "E203", # E203: whitespace before ‘,’, ‘;’, or ‘:’ (not Black compliant) + "E501", # E501: line too long (managed better by Bugbear's B950) +] + +[tool.ruff.lint.per-file-ignores] +"tests/*" = [ + "S101", # S101 Use of `assert` detected +] diff --git a/tests/integration/test_something.py b/tests/integration/test_something.py index acd464f6..b3bebaf1 100644 --- a/tests/integration/test_something.py +++ b/tests/integration/test_something.py @@ -3,8 +3,7 @@ # Copyright (c) 2021-2026 CODEOWNERS # This code is licensed under MIT license, see LICENSE.md for details. -# https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess -import subprocess # nosec B404 +import subprocess import pytest @@ -13,7 +12,6 @@ def test_package() -> None: """Test the Something command.""" # For testing we disable this warning here: - # https://bandit.readthedocs.io/en/latest/plugins/b603_subprocess_without_shell_equals_true.html - # https://bandit.readthedocs.io/en/latest/plugins/b607_start_process_with_partial_path.html - completed = subprocess.run(["something"], check=True, shell=False) # nosec B603, B607 + # https://docs.astral.sh/ruff/rules/start-process-with-partial-path/ + completed = subprocess.run(["something"], check=True, shell=False) # noqa: S607 assert completed.returncode == 0 From 19ab96c563bd99f7553c75d0157a30dc252796c7 Mon Sep 17 00:00:00 2001 From: Jens Troeger Date: Tue, 16 Jun 2026 18:39:51 +1000 Subject: [PATCH 2/2] chore: remove obsolete configurations --- pyproject.toml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4a8c08f8..d21804fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,18 +80,6 @@ Documentation = "https://github.com/jenstroeger/python-package-template/wiki" Issues = "https://github.com/jenstroeger/python-package-template/issues" -# https://bandit.readthedocs.io/en/latest/config.html -# Skip test B101 because of issue https://github.com/PyCQA/bandit/issues/457 -[tool.bandit] -tests = [] -skips = ["B101"] - - -# https://github.com/psf/black#configuration -[tool.black] -line-length = 120 - - # https://github.com/commitizen-tools/commitizen # https://commitizen-tools.github.io/commitizen/bump/ [tool.commitizen] @@ -134,15 +122,6 @@ exclude = [ ] -# https://pycqa.github.io/isort/ -[tool.isort] -profile = "black" -multi_line_output = 3 -line_length = 120 -skip_gitignore = true -filter_files = true - - # https://mypy.readthedocs.io/en/stable/config_file.html#using-a-pyproject-toml [tool.mypy] # mypy_path =