From e266ef9efb7f2062e989db87fd8c399e7866c61b Mon Sep 17 00:00:00 2001 From: Jerry Pussinen Date: Thu, 14 Mar 2024 13:12:11 +0200 Subject: [PATCH 1/2] Introduce ruff, ditch flake8, black and friends --- README.md | 5 +- .../.pre-commit-config.yaml | 32 ++++-------- {{cookiecutter.project_slug}}/README.md | 2 +- {{cookiecutter.project_slug}}/pyproject.toml | 49 ++++++++++++------- {{cookiecutter.project_slug}}/setup.cfg | 38 -------------- 5 files changed, 41 insertions(+), 85 deletions(-) delete mode 100644 {{cookiecutter.project_slug}}/setup.cfg diff --git a/README.md b/README.md index 756d389..d99d769 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,7 @@ A [cookiecutter](https://cookiecutter.readthedocs.io/en/latest/README.html) (pro * [Poetry](https://python-poetry.org/docs/) for managing dependencies and packaging * [pre-commit](https://pre-commit.com/) for running all the goodies listed below * [mypy](https://flake8.pycqa.org/en/latest/) for static type checking -* [flake8](https://flake8.pycqa.org/en/latest/) (with multiple plugins) for linting (e.g. style and complexity checks, commented code, etc.) -* [black](https://black.readthedocs.io/en/stable/) for auto-formatting the code -* [isort](https://pycqa.github.io/isort/) for auto-sorting imports -* [autoflake](https://github.com/myint/autoflake) for auto-removing unused imports +* [ruff](https://beta.ruff.rs/docs/) for automatic formatting, linting and automatically fixing some linting errors #### Automation diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index bb125fd..34578a2 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -15,26 +15,17 @@ repos: - id: mixed-line-ending - repo: local hooks: - - id: autoflake - name: autoflake - entry: poetry run autoflake -r -i --remove-all-unused-imports --remove-unused-variables + - id: ruff-format + name: ruff-format + entry: poetry run ruff format + require_serial: true language: system types: [ python ] - - id: isort - name: isort - entry: poetry run isort - language: system - types: [python] - - id: black - name: black - entry: poetry run black - language: system - types: [python] - - id: pyupgrade - name: pyupgrade - entry: poetry run pyupgrade --py37-plus - language: system - types: [python] + - id: ruff + name: ruff + # Add --fix, in case you want it to autofix when this hook runs + entry: poetry run ruff check --force-exclude + require_serial: true - id: mypy name: mypy entry: poetry run mypy . @@ -42,11 +33,6 @@ repos: language: system types: [python] pass_filenames: false - - id: flake8 - name: flake8 - entry: poetry run flake8 - language: system - types: [python] - id: kacl-verify name: kacl-verify entry: poetry run kacl-cli verify diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index b9e22a2..a9b2f2b 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -66,7 +66,7 @@ Find the draft release from the ### Pre-commit -Pre-commit hooks run all the auto-formatters (e.g. `black`, `isort`), linters (e.g. `mypy`, `flake8`), and other quality +Pre-commit hooks run all the auto-formatting (`ruff format`), linters (e.g. `ruff` and `mypy`), and other quality checks to make sure the changeset is in good shape before a commit/push happens. You can install the hooks with (runs for each commit): diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 5432123..e47534a 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -35,40 +35,51 @@ packages = [ python = ">=3.8.1, <4.0" [tool.poetry.dev-dependencies] -autoflake = "*" -black = "*" -flake8 = "*" -flake8-bugbear = "*" -flake8-builtins = "*" -flake8-comprehensions = "*" -flake8-debugger = "*" -flake8-eradicate = "*" -flake8-logging-format = "*" -isort = "*" mkdocstrings = {version = ">=0.18", extras = ["python"]} mkdocs-material = "*" mypy = "*" -pep8-naming = "*" pre-commit = "*" pymdown-extensions = "*" pytest = "*" pytest-github-actions-annotate-failures = "*" pytest-cov = "*" python-kacl = "*" -pyupgrade = "*" -tryceratops = "*" +ruff = ">=0.2.0" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" -[tool.isort] -profile = "black" -src_paths = ["src", "tests"] +[tool.ruff] +target-version = "py38" # The lowest supported version -[tool.black] -target-version = ["py38", "py39", "py310", "py311", "py312"] -include = '\.pyi?$' +[tool.ruff.lint] +# By default, enable all the lint rules. +# Add to the ignore list below if you don't want some rules. +# If you need some ignores for certain modules, see tool.ruff.lint.per-file-ignores below. +# For individual ignore cases, prefer inline `# noqa`s within the code. +select = ["ALL"] +ignore = [ + "ANN", # Type hints related, let mypy handle these. + "D", # Docstrings related, way too strict to our taste + ] + +[tool.ruff.lint.per-file-ignores] +"tests/**" = [ + "S101", # "Use of `assert` detected" + "ARG", # "Unused function argument". Fixtures are often unused. + "S105", # "Possible hardcoded password". +] + +[tool.ruff.lint.mccabe] +max-complexity = 10 + +[tool.ruff.lint.pep8-naming] +classmethod-decorators = [ + "classmethod", + "pydantic.validator", + "pydantic.root_validator", +] [tool.pytest.ini_options] addopts = """\ diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg deleted file mode 100644 index a65d6bb..0000000 --- a/{{cookiecutter.project_slug}}/setup.cfg +++ /dev/null @@ -1,38 +0,0 @@ -[flake8] -ignore = - # Line break occurred before a binary operator (W503) - # https://github.com/psf/black/issues/52 - W503, - # Line too long (E501) - # 1. black does not format comments - # https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#comments - # 2. long links in doc strings are an issue - E501 - # flake8-builtins - # the likelihood of running into an issue when shadowing a buildin - # with a class attribute is very low - A003, - # flake8-bugbear - # fastapi recommends to use `Depend()` as an argument default. - # Unfortunately, exceptions are hardcoded in bugbear. - # https://github.com/PyCQA/flake8-bugbear/issues/62 - B008, - -# pep8-naming -classmethod-decorators = - classmethod, # built-in - validator, # pydantic - root_validator, # pydantic - -enable-extensions= - G, # flake8-logging-format - -per-file-ignores = - # star imports in `__init__.py` files are ok - */__init__.py: F401 - -# Enables maccabe complexity checks -# see https://github.com/PyCQA/mccabe#plugin-for-flake8 -max-complexity = 10 - -exclude = .git,__pycache__,old,build,dist,.venv,.eggs,.tox From 73b011173fc8a5acb6a9c0aaa20e07e3e06cb257 Mon Sep 17 00:00:00 2001 From: Jerry Pussinen Date: Thu, 14 Mar 2024 13:17:37 +0200 Subject: [PATCH 2/2] Fix Ruff config --- {{cookiecutter.project_slug}}/.pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 34578a2..8e81856 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -26,6 +26,8 @@ repos: # Add --fix, in case you want it to autofix when this hook runs entry: poetry run ruff check --force-exclude require_serial: true + language: system + types: [ python ] - id: mypy name: mypy entry: poetry run mypy .