Repository navigation
Ratchet the inline noqa comments, so their number can only fall - #75
Merged
Merged
Conversation
The noqa-comments guard should list each `# noqa` comment in a tracked Python file as `<path>: <codes>`, compare them with the rule's baseline file as a count per entry, and fail on a comment the baseline does not list (a new suppression) and on an entry with no comment left (asking for the baseline to shrink). A move within the file still matches. One test checks that this repository's baseline lists every current comment, and the proof fixtures are TOML manifests, so the guard does not count their comments. All fail now: scripts.rules.noqa_comments does not exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- scripts/rules/noqa_comments.py, the noqa-comments quality guard, lists each inline `noqa` comment in a tracked Python file as `<path>: <codes>` (tokenize finds comments only) and compares the counts with the rule's baseline: an unlisted comment fails, and so does an entry with fewer comments left than it lists. - The ratcheted rule emitter.quality.inline-suppressions-only-shrink lists the 140 comments in 49 files in rules/baselines/noqa-comments.txt; the rules guard already refuses a baseline count that grows against the base branch. As a new rule that starts ratcheted with entries, it names #74 in [rule.downgrade]. - run_quality_guards.py runs the guard, the README says how the rule works, and the rules views are rendered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
claude/noqa-ratchet
branch
from
November 3, 2026 21:15
5406846 to
a5bdc0c
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cases - Ruff's `# ruff: ignore[...]`, `# ruff: disable[...]` (its `enable` is not one), `# ruff: file-ignore[...]` and own-line `# ruff: noqa` and `# flake8: noqa` are entries, labelled by form; a file-level `# ruff: noqa` after code, which Ruff does not apply, is not. - Codes are read as Ruff reads them: `BLE001S110` is two codes, a space before the colon still names the codes, and lowercase codes, which Ruff rejects and does not apply, are not counted. - As Anthony decided, the base-branch comparison counts comments only: an added code, a swapped code and a renamed file pass at the same total, a higher total fails, and a comment moved between two versions of a file keeps its entry. Red: 7 of the 8 new form and code tests fail on their assertions (the guard returns no entry for the Ruff forms, one code for the squashed pair, and `(all)` for the other two); the same-total tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The guard counts Ruff's ignore[...], disable[...] and file-ignore[...] comments and an own-line file-level ruff: noqa or flake8: noqa, labelled by form; an enable[...] and a file-level noqa after code, which Ruff does not apply, are not counted. - codes_after reads codes as Ruff's lexer does: BLE001S110 is two codes, a space before the colon still names the codes, and a directive whose codes Ruff rejects, such as lowercase ones, applies nothing and is not counted. - One helper, baseline.baseline_lines, reads every baseline file's entries, for the guard, validation and the ci-scripts baselines, each with an explicit UTF-8 encoding. The tests from b9aa036 pass, as does this repository's baseline, still 140 entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As Anthony decided, the base-branch comparison counts comments only, so a new suppression is allowed when another goes. The message for an unlisted comment should say so: fix the finding, or remove another suppression and list this one, since the total may not grow. Red: the proof test and test_a_new_noqa_comment_fails fail on the old wording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ot grow As Anthony decided, the base-branch comparison stays count only, so the wording now matches what the check does: - The rule statement, README, changelog fragment and the guard's message say the total may not grow: a pull request may add a suppression only by removing another, and the check does not stop a swap at the same total, a rename or a code added to an existing comment. The statement puts `<path>: <codes>` in backticks, so the generated document shows it. - The registry guide says a new justified suppression needs another removed in the same pull request, and raising the total is a person's decision, since the guard refuses a grown baseline count with or without a [rule.downgrade]. - The baseline file's header names Ruff's own forms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
marked this pull request as ready for review
November 3, 2026 21:57
This was referenced Nov 3, 2026
anth-volk
added a commit
that referenced
this pull request
Nov 4, 2026
Count the remaining suppression forms and say the total may not grow (follow-up to #75)
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.
Fixes #73
What this does
The total number of inline suppressions may not grow: a ratcheted rule lists every suppression comment Ruff applies, and its count may only fall against the base branch, so a pull request may add a suppression only by removing another. As Anthony decided in round 1, the comparison counts comments only: it does not stop a swap at the same total, a renamed file, or a code added to an existing comment, once the baseline lists the result. 16.1 · 16 in the plan. It was stacked on #71 (gh stack #76); #71 has merged, and this pull request now targets
main.Starting count: 140 suppression comments in 49 Python files, all
# noqa, on #71's final head6925db1, which is alsomainnow that #71 has merged. The most common codes areBLE001(60),T201(16),PLR0913(15),S105(13),ARG002(12) andTRY004(8). Before #71,mainhad 125 in 42 files, after #69's merge, so #71 added 15 in 7 files. The repository has none of Ruff's own forms.scripts/rules/noqa_comments.py(noqa-comments):<path>: <codes>with the codes sorted, or<path>: (all)for a blanket one. That covers an inline# noqa; Ruff'sruff: ignore[...],ruff: disable[...]andruff: file-ignore[...], labelled by form (anenable[...]is not one); and an own-line file-levelruff: noqaorflake8: noqa(round 1, bug 1). It finds comments withtokenize, so text in a string doesn't count, and neither does a comment that names noqa without the directive.BLE001S110is two codes (bug 3), and# noqa : BLE001namesBLE001. A directive Ruff rejects and does not apply is not counted: lowercase codes, or a file-levelruff: noqaafter code.run_quality_guards.pyruns it.emitter.quality.inline-suppressions-only-shrink:ratcheted, with[rule.baseline]namingrules/baselines/noqa-comments.txt, which holds 140 entries, one per comment.[rule.downgrade]. The tool already supportedratchetedrules and that comparison, so only the guard is new. One helper,baseline.baseline_lines, now reads every baseline file's entries, with an explicit encoding (round 1).[rule.downgrade]naming an open issue. I opened Reduce the emitter's inline noqa comments #74, "Reduce the emitter's inline noqa comments", for that purpose.[rule.downgrade]section naming Reduce the emitter's inline noqa comments #74, and the 140-entry baseline. The tracker task asks for this ratcheted rule, so I added both; change the reason, the issue or the baseline if you prefer.Test-first record
b9bd74fThe tests and proof fixturespython -m unittest scripts.rules.tests.test_noqa_commentsfails to importscripts.rules.noqa_comments.9c76f80The guard, the rule, the baseline and the docsGITHUB_BASE_REF=main, andguard --base-ref origin/claude/ruff-complexitypasses with the notes that the rule is new, starts ratcheted with 140 entries, and that #74 is open.ruff checkandruff format --checkpass on the changed Python files.Review round 1:
d3883aeMerge ofmainmain's release.renderchanged nothing, and the guards pass.b9aa036TestsBLE001S110, and(all)for# noqa : BLE001and lowercase codes. The same-total tests pin Anthony's decision and pass: an added code, a swapped code and a rename pass at the same total, a higher total fails, and a comment moved between two versions of a file keeps its entry.cde122eRuff's forms, Ruff's code reading, one baseline readercde3bbdTest of the count-only messagetest_a_new_noqa_comment_failsexpect the new wording.0deef32The wordingGITHUB_BASE_REF=main, andguard --base-ref origin/mainpasses.ruff checkpasses on the changed Python files.No other test was run.
CI
No workflow, trigger or script changes. The guard runs in the existing "Rules registry" job (
pr.yaml'srulesjob, throughrun_quality_guards.py). The proof test runs in that job'sunittest discover -s scripts/rules/tests. The downgrade's issue lookup uses that step's existingGH_TOKEN, which the step'senv:sets fromgithub.token. No new environment variable or secret.Release
The fragment is
changelog.d/noqa-ratchet.changed.md, a patch bump: no shipped code changes, so the wheels are unchanged.🤖 Generated with Claude Code