From bc0c7541728ff0095afcc7b2fc25d3ae021fa3c4 Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Tue, 5 May 2026 10:10:36 +0100 Subject: [PATCH 1/8] remove black as dev dependency and upgrade ruff --- .pre-commit-config.yaml | 11 +++++------ CHANGELOG.md | 3 +++ docs/Developer-Setup.md | 7 ------- docs/pyproject.toml.md | 10 +++++----- pyproject.toml | 8 +------- tasks.py | 16 ++-------------- 6 files changed, 16 insertions(+), 39 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e3aa33..e397b5e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,14 +6,13 @@ repos: hooks: - id: trailing-whitespace - id: end-of-file-fixer -- repo: https://github.com/psf/black - rev: "24.4.2" - hooks: - - id: black + - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.1 + rev: v0.15.12 hooks: - - id: ruff + - id: ruff-check + - id: ruff-format + - repo: https://github.com/RobertCraigie/pyright-python rev: v1.1.370 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index 485a9db..6307a88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Remove `black` from `pyproject.toml` and `tasks.py` +- Upgrade `ruff` to `0.15.12` + ### Changed - Upgrade Docker image to use python:3.12-slim-bookworm diff --git a/docs/Developer-Setup.md b/docs/Developer-Setup.md index 179cbce..7e3ed98 100644 --- a/docs/Developer-Setup.md +++ b/docs/Developer-Setup.md @@ -49,7 +49,6 @@ The key part is the symlink to `.venv` so that LSP-pyright and other tool can au - When doing some JS, you obviously need a Node.JS as well - [hatch](https://pypi.org/project/hatch/) installed globally - [Visual Studio Code](https://github.com/microsoft/vscode) with following extensions (more or less related to Python development) - - Black Formater (Microsoft) - Dev Containers (Microsoft) - Docker (Microsoft) - Excalidraw (pomdtr) @@ -77,12 +76,6 @@ This additional Hatch config section ensures that all virtual environments (the On every project, create a local `.vscode/settings.json` to automatically format your code (adjust `typeCheckingMode` depending on your project): ``` json { - "[python]": { - "editor.defaultFormatter": "ms-python.black-formatter", - "editor.codeActionsOnSave": { - "source.organizeImports": "explicit" - } - }, "python.analysis.typeCheckingMode": "strict", "eslint.validate": ["javascript", "typescript", "vue"], "eslint.workingDirectories": [{ "mode": "auto" }], diff --git a/docs/pyproject.toml.md b/docs/pyproject.toml.md index 41b1a82..3e715b6 100644 --- a/docs/pyproject.toml.md +++ b/docs/pyproject.toml.md @@ -20,12 +20,12 @@ Version must be dynamic and set once in code. `module.__about__` usually. ### Linting -- Black (latest available version) +- Ruff (latest available version) - Ruff for import sorting (isort-like) and many other checks - Dedicated hatch environment -- Black and ruff configuration so those works without hatch as well -- Scripts for just black and just ruff checking -- Scripts for black fixing and ruf fixing (accepts params) +- Ruff configuration so those works without hatch as well +- Scripts for just ruff checking +- Scripts for ruff fixing (accepts params) - Scripts for global checking and fixing - Sample ruff configuration @@ -42,4 +42,4 @@ Version must be dynamic and set once in code. `module.__about__` usually. - Dedicated hatch environment - Hatch environment matrix to easily tests on multiple python versions - pytest and coverage configuration so those works without hatch as well -- Scripts for running tests (accepts params), running with coverage and reporting \ No newline at end of file +- Scripts for running tests (accepts params), running with coverage and reporting diff --git a/pyproject.toml b/pyproject.toml index 088769d..8f32529 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,8 +20,7 @@ scripts = [ "invoke==2.2.0", ] lint = [ - "black==24.4.2", - "ruff==0.5.1", + "ruff==0.15.12", ] check = [ "pyright==1.1.370", @@ -75,10 +74,8 @@ skip-install = false features = ["scripts", "lint"] [tool.hatch.envs.lint.scripts] -black = "inv lint-black --args '{args}'" ruff = "inv lint-ruff --args '{args}'" all = "inv lintall --args '{args}'" -fix-black = "inv fix-black --args '{args}'" fix-ruff = "inv fix-ruff --args '{args}'" fixall = "inv fixall --args '{args}'" @@ -89,9 +86,6 @@ features = ["scripts", "check"] pyright = "inv check-pyright --args '{args}'" all = "inv checkall --args '{args}'" -[tool.black] -line-length = 88 -target-version = ['py311'] [tool.ruff] target-version = "py312" diff --git a/tasks.py b/tasks.py index 87cd552..2c72f9c 100644 --- a/tasks.py +++ b/tasks.py @@ -42,11 +42,6 @@ def coverage(ctx: Context, args: str = "", *, html: bool = False): report_cov(ctx, html=html) -@task(optional=["args"], help={"args": "black additional arguments"}) -def lint_black(ctx: Context, args: str = "."): - args = args or "." # needed for hatch script - ctx.run("black --version", pty=use_pty) - ctx.run(f"black --check --diff {args}", pty=use_pty) @task(optional=["args"], help={"args": "ruff additional arguments"}) @@ -59,13 +54,12 @@ def lint_ruff(ctx: Context, args: str = "."): @task( optional=["args"], help={ - "args": "linting tools (black, ruff) additional arguments, typically a path", + "args": "linting tools (ruff) additional arguments, typically a path", }, ) def lintall(ctx: Context, args: str = "."): """Check linting""" args = args or "." # needed for hatch script - lint_black(ctx, args) lint_ruff(ctx, args) @@ -82,11 +76,6 @@ def checkall(ctx: Context, args: str = ""): check_pyright(ctx, args) -@task(optional=["args"], help={"args": "black additional arguments"}) -def fix_black(ctx: Context, args: str = "."): - """fix black formatting""" - args = args or "." # needed for hatch script - ctx.run(f"black {args}", pty=use_pty) @task(optional=["args"], help={"args": "ruff additional arguments"}) @@ -99,12 +88,11 @@ def fix_ruff(ctx: Context, args: str = "."): @task( optional=["args"], help={ - "args": "linting tools (black, ruff) additional arguments, typically a path", + "args": "linting tools ( ruff) additional arguments, typically a path", }, ) def fixall(ctx: Context, args: str = "."): """Fix everything automatically""" args = args or "." # needed for hatch script - fix_black(ctx, args) fix_ruff(ctx, args) lintall(ctx, args) From 525c5588a10f4ce1bfc369e9a13af13b7d3c61b7 Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Tue, 5 May 2026 10:13:51 +0100 Subject: [PATCH 2/8] remove black from CI --- .github/workflows/QA.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/QA.yaml b/.github/workflows/QA.yaml index 4504260..d429ff0 100644 --- a/.github/workflows/QA.yaml +++ b/.github/workflows/QA.yaml @@ -24,9 +24,6 @@ jobs: pip install -U pip pip install -e .[lint,scripts,test,check] - - name: Check black formatting - run: inv lint-black - - name: Check ruff run: inv lint-ruff From 6cb99717069a70026f60c68872040f41859b548d Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Tue, 5 May 2026 10:54:15 +0100 Subject: [PATCH 3/8] fail ruff format on modification --- .github/workflows/QA.yaml | 1 + tasks.py | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/QA.yaml b/.github/workflows/QA.yaml index d429ff0..ba81822 100644 --- a/.github/workflows/QA.yaml +++ b/.github/workflows/QA.yaml @@ -25,6 +25,7 @@ jobs: pip install -e .[lint,scripts,test,check] - name: Check ruff + run: inv fix-ruff --args '--check' run: inv lint-ruff - name: Check pyright diff --git a/tasks.py b/tasks.py index 2c72f9c..2b2d6dc 100644 --- a/tasks.py +++ b/tasks.py @@ -42,8 +42,6 @@ def coverage(ctx: Context, args: str = "", *, html: bool = False): report_cov(ctx, html=html) - - @task(optional=["args"], help={"args": "ruff additional arguments"}) def lint_ruff(ctx: Context, args: str = "."): args = args or "." # needed for hatch script @@ -76,13 +74,12 @@ def checkall(ctx: Context, args: str = ""): check_pyright(ctx, args) - - @task(optional=["args"], help={"args": "ruff additional arguments"}) def fix_ruff(ctx: Context, args: str = "."): - """fix all ruff rules""" + """fix ruff formatting""" args = args or "." # needed for hatch script - ctx.run(f"ruff check --fix {args}", pty=use_pty) + ctx.run("ruff --version", pty=use_pty) + ctx.run(f"ruff format {args}", pty=use_pty) @task( From 1c961a18c3a49e1897550491aa7d230dda398fb3 Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Tue, 5 May 2026 10:55:56 +0100 Subject: [PATCH 4/8] fix ci ruff commands --- .github/workflows/QA.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/QA.yaml b/.github/workflows/QA.yaml index ba81822..cf61b1a 100644 --- a/.github/workflows/QA.yaml +++ b/.github/workflows/QA.yaml @@ -25,8 +25,9 @@ jobs: pip install -e .[lint,scripts,test,check] - name: Check ruff - run: inv fix-ruff --args '--check' - run: inv lint-ruff + run: | + inv fix-ruff --args '--check' + inv lint-ruff - name: Check pyright run: inv check-pyright From 8100c4894d9121c14d35a721952ba4ab037bd740 Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Tue, 5 May 2026 14:47:47 +0100 Subject: [PATCH 5/8] rename inv commands --- .github/workflows/QA.yaml | 10 +++++----- pyproject.toml | 11 +++++------ tasks.py | 40 ++++++++++++--------------------------- 3 files changed, 22 insertions(+), 39 deletions(-) diff --git a/.github/workflows/QA.yaml b/.github/workflows/QA.yaml index cf61b1a..843c384 100644 --- a/.github/workflows/QA.yaml +++ b/.github/workflows/QA.yaml @@ -24,10 +24,10 @@ jobs: pip install -U pip pip install -e .[lint,scripts,test,check] - - name: Check ruff + - name: Check Lint and Formatting run: | - inv fix-ruff --args '--check' - inv lint-ruff + inv format --args '--check' + inv lint - - name: Check pyright - run: inv check-pyright + - name: Type Check + run: inv type-check diff --git a/pyproject.toml b/pyproject.toml index 8f32529..afebbf5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,17 +74,16 @@ skip-install = false features = ["scripts", "lint"] [tool.hatch.envs.lint.scripts] -ruff = "inv lint-ruff --args '{args}'" -all = "inv lintall --args '{args}'" -fix-ruff = "inv fix-ruff --args '{args}'" -fixall = "inv fixall --args '{args}'" +lint = "inv lint --args '{args}'" +format = "inv format --args '{args}'" +fixall = "inv fixall" [tool.hatch.envs.check] features = ["scripts", "check"] [tool.hatch.envs.check.scripts] -pyright = "inv check-pyright --args '{args}'" -all = "inv checkall --args '{args}'" +type-check = "inv type-check --args '{args}'" +analyse-all = "inv analyse-all" [tool.ruff] diff --git a/tasks.py b/tasks.py index 2b2d6dc..1e7c002 100644 --- a/tasks.py +++ b/tasks.py @@ -43,53 +43,37 @@ def coverage(ctx: Context, args: str = "", *, html: bool = False): @task(optional=["args"], help={"args": "ruff additional arguments"}) -def lint_ruff(ctx: Context, args: str = "."): +def lint(ctx: Context, args: str = "."): args = args or "." # needed for hatch script ctx.run("ruff --version", pty=use_pty) ctx.run(f"ruff check {args}", pty=use_pty) -@task( - optional=["args"], - help={ - "args": "linting tools (ruff) additional arguments, typically a path", - }, -) -def lintall(ctx: Context, args: str = "."): - """Check linting""" - args = args or "." # needed for hatch script - lint_ruff(ctx, args) - - @task(optional=["args"], help={"args": "check tools (pyright) additional arguments"}) -def check_pyright(ctx: Context, args: str = ""): +def type_check(ctx: Context, args: str = ""): """check static types with pyright""" ctx.run("pyright --version") ctx.run(f"pyright {args}", pty=use_pty) -@task(optional=["args"], help={"args": "check tools (pyright) additional arguments"}) -def checkall(ctx: Context, args: str = ""): +@task() +def analyse_all(ctx: Context): """check static types""" - check_pyright(ctx, args) + lint(ctx) + format(ctx, "--check") + type_check(ctx) @task(optional=["args"], help={"args": "ruff additional arguments"}) -def fix_ruff(ctx: Context, args: str = "."): +def format(ctx: Context, args: str = "."): # noqa: A001 """fix ruff formatting""" args = args or "." # needed for hatch script ctx.run("ruff --version", pty=use_pty) ctx.run(f"ruff format {args}", pty=use_pty) -@task( - optional=["args"], - help={ - "args": "linting tools ( ruff) additional arguments, typically a path", - }, -) -def fixall(ctx: Context, args: str = "."): +@task() +def fixall(ctx: Context): """Fix everything automatically""" - args = args or "." # needed for hatch script - fix_ruff(ctx, args) - lintall(ctx, args) + lint(ctx, "--select I --fix") # sort imports along with check fixes + format(ctx) From 927510ff61c606a343aada00534e74c11841d0ae Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Tue, 5 May 2026 16:32:56 +0100 Subject: [PATCH 6/8] add subcommand for checking format --- .github/workflows/QA.yaml | 2 +- pyproject.toml | 1 + tasks.py | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/QA.yaml b/.github/workflows/QA.yaml index 843c384..6fe98f0 100644 --- a/.github/workflows/QA.yaml +++ b/.github/workflows/QA.yaml @@ -26,7 +26,7 @@ jobs: - name: Check Lint and Formatting run: | - inv format --args '--check' + inv check-format inv lint - name: Type Check diff --git a/pyproject.toml b/pyproject.toml index afebbf5..ac252c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,6 +76,7 @@ features = ["scripts", "lint"] [tool.hatch.envs.lint.scripts] lint = "inv lint --args '{args}'" format = "inv format --args '{args}'" +check-format = "inv check-format" fixall = "inv fixall" [tool.hatch.envs.check] diff --git a/tasks.py b/tasks.py index 1e7c002..3922d8d 100644 --- a/tasks.py +++ b/tasks.py @@ -72,8 +72,13 @@ def format(ctx: Context, args: str = "."): # noqa: A001 ctx.run(f"ruff format {args}", pty=use_pty) +@task() +def check_format(ctx: Context): + format(ctx, "--check") + + @task() def fixall(ctx: Context): """Fix everything automatically""" - lint(ctx, "--select I --fix") # sort imports along with check fixes + lint(ctx, "--select I --fix") # sort imports along with check fixes format(ctx) From d0aae782aa2b52ca98e1158354cbabb339c0a52c Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Wed, 6 May 2026 09:21:42 +0100 Subject: [PATCH 7/8] merge lint and check environments into qa --- docs/Usage.md | 12 ++++++------ pyproject.toml | 20 ++++++-------------- tasks.py | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/docs/Usage.md b/docs/Usage.md index d0bc67c..7a67fbc 100644 --- a/docs/Usage.md +++ b/docs/Usage.md @@ -13,14 +13,14 @@ If you've not already read it, please check our [Policy](./Policy.md) first. ❯ hatch env show # linting, testing, coverage, checking -❯ hatch run lint:all -❯ hatch run lint:fixall +❯ hatch run qa:analyse-all +❯ hatch run qa:fixall # run tests on all matrixed' envs ❯ hatch run test:run # run tests in a single matrixed' env ❯ hatch env run -e test -i py=3.11 coverage # run static type checks -❯ hatch env run check:all +❯ hatch env run -e qa type-check # building packages ❯ hatch build @@ -39,13 +39,13 @@ If you've not already read it, please check our [Policy](./Policy.md) first. ❯ inv -l # linting, testing, coverage, static type checks -❯ inv lintall +❯ inv analyse-all ❯ inv fixall ❯ inv test ❯ inv coverage -❯ inv checkall +❯ inv type-check # building packages ❯ pip install build ❯ python3 -m build -``` \ No newline at end of file +``` diff --git a/pyproject.toml b/pyproject.toml index ac252c3..1da87b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,10 +19,8 @@ additional-keywords = ["some"] scripts = [ "invoke==2.2.0", ] -lint = [ +qa = [ "ruff==0.15.12", -] -check = [ "pyright==1.1.370", ] test = [ @@ -33,9 +31,8 @@ dev = [ "pre-commit==3.7.1", "debugpy==1.8.2", "great-project[scripts]", - "great-project[lint]", + "great-project[qa]", "great-project[test]", - "great-project[check]", ] [project.scripts] @@ -68,21 +65,16 @@ report-cov = "inv report-cov" coverage = "inv coverage --args '{args}'" html = "inv coverage --html --args '{args}'" -[tool.hatch.envs.lint] -template = "lint" +[tool.hatch.envs.qa] +template = "qa" skip-install = false -features = ["scripts", "lint"] +features = ["scripts", "qa", "test"] -[tool.hatch.envs.lint.scripts] +[tool.hatch.envs.qa.scripts] lint = "inv lint --args '{args}'" format = "inv format --args '{args}'" check-format = "inv check-format" fixall = "inv fixall" - -[tool.hatch.envs.check] -features = ["scripts", "check"] - -[tool.hatch.envs.check.scripts] type-check = "inv type-check --args '{args}'" analyse-all = "inv analyse-all" diff --git a/tasks.py b/tasks.py index 3922d8d..4eb96d1 100644 --- a/tasks.py +++ b/tasks.py @@ -80,5 +80,5 @@ def check_format(ctx: Context): @task() def fixall(ctx: Context): """Fix everything automatically""" - lint(ctx, "--select I --fix") # sort imports along with check fixes + lint(ctx, "--fix") format(ctx) From 66d20e6f8a54e9afc27bb000f20ae5af62e808fa Mon Sep 17 00:00:00 2001 From: Uchechukwu Orji Date: Wed, 6 May 2026 09:24:17 +0100 Subject: [PATCH 8/8] remove lint and check environments in CI --- .github/workflows/QA.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/QA.yaml b/.github/workflows/QA.yaml index 6fe98f0..22c9636 100644 --- a/.github/workflows/QA.yaml +++ b/.github/workflows/QA.yaml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies (and project) run: | pip install -U pip - pip install -e .[lint,scripts,test,check] + pip install -e .[qa,scripts,test] - name: Check Lint and Formatting run: |