fix(ci): pin the ruff version and state the lint rule set explicitly - #10
Merged
Conversation
main is currently RED on CI, and no commit caused it. The lint gate runs `ruff check src tests examples` after `pip install -e ".[dev]"`, where the extra declared an open-ended `ruff>=0.1`. CI therefore installs whatever ruff shipped most recently, and `[tool.ruff]` set only line-length/target-version — so the ENFORCED RULE SET was whatever that version happened to default to. ruff 0.16.0 widened those defaults (I/RUF/SIM/PL/UP). The result: 40 findings appeared at once — 17 import-sort (I001), 7 RUF022, plus SIM/PL/UP — in files no open PR had touched, retroactively failing work that was green when written. Verified by running 0.16.0 against unmodified `main`: 40 errors, the same failure seen on PR #8, which is therefore blocked by this and not by its own diff. Two changes, because there are two independent causes: - `ruff>=0.5,<0.17` — bound the tool on both sides so the gate is reproducible. Floor 0.5 because the rule set below uses the `[tool.ruff.lint]` table. - `[tool.ruff.lint] select = ["E4","E7","E9","F"]` — state the enforced set explicitly so it is a property of this repo, not of the installed ruff. This is the load-bearing half: without it, the next default-widening release moves the gate again regardless of any version pin. These four are what the project has actually been enforcing (ruff's historical default). Adopting import sorting or the RUF/SIM/UP families is a deliberate choice for its own commit, with its ~40 fixes reviewed — not a side effect of a dependency resolving forward. No source file is touched here. Verified: ruff 0.16.0 (what CI installs) and local ruff 0.15.15 BOTH report "All checks passed" against this commit — the point is that they now agree. pytest 1654 passed; the one failure (test_version_matches_package_metadata) is a stale editable install on the dev host, reproduces on unmodified main, and CI installs fresh. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
mainis red on CI right now, and no commit caused it.The lint step runs
ruff check src tests examplesafterpip install -e ".[dev]", and the extra declared an open-endedruff>=0.1. So CI installs whatever ruff shipped most recently. Meanwhile[tool.ruff]set onlyline-lengthandtarget-version— no rule selection — which means the enforced rule set was whatever that ruff version happened to default to.ruff 0.16.0 widened those defaults (
I,RUF,SIM,PL,UP). Overnight, 40 findings appeared:I001(import sorting)RUF022RUF010SIM114,PLR0402UP035,RUF100,RUF059,RUF012,PLW1510All in files no open PR had touched — retroactively failing work that was green when written.
Proof it is not any branch's fault: running ruff 0.16.0 against unmodified
mainproduces the same 40 errors. The last green CI on main was 2026-07-01, before 0.16.0 existed.This also blocks #8, whose 4 failing checks are this and not its own diff.
The fix — two changes, two independent causes
ruff>=0.5,<0.17— bound the tool on both sides so the gate is reproducible. Floor is 0.5 because the rule set below uses the[tool.ruff.lint]table.[tool.ruff.lint] select = ["E4","E7","E9","F"]— state the enforced set explicitly, so it is a property of this repo rather than of the installed ruff. This is the load-bearing half: without it, the next default-widening release moves the gate again no matter what version is pinned.Those four are what the project has actually been enforcing (ruff's historical default): pyflakes plus the pycodestyle errors that catch real mistakes.
What this deliberately does NOT do
No source file is touched. Adopting import sorting or the
RUF/SIM/UPfamilies is a real improvement, but it is a deliberate choice deserving its own commit with its ~40 fixes reviewed — not something that should arrive as a side effect of a dependency resolving forward. 30 of the 40 are--fix-able and 5 need--unsafe-fixes, so it is a reviewable change whenever you want it.Verification
All checks passedAll checks passedThe point is not that either passes; it is that they now agree, which is what pinning the rule set buys.
pytest: 1654 passed. The single failure,test_version_matches_package_metadata, is a stale editable install on the dev host (metadata 0.25.0 vs source 0.26.0); it reproduces on unmodifiedmainand CI installs fresh.After this merges
#8 needs a rebase onto
mainto pick up the pin, and should then go green.