Repository navigation
Conversation
Every pull request ran the full pre-commit suite twice: on pre-commit.ci, configured by the ci: block in .pre-commit-config.yaml, and in the Format job of the Run pre-commit workflow. The two disagree, because they resolve the hooks differently. The flake8 hook declared flake8-bugbear and flake8-print with no versions, and each service caches its own hook environment, built at a different time. When flake8-bugbear 26.10.27 added B045, the Actions job installed it on its next cache miss and started failing unrelated pull requests, while pre-commit.ci kept passing from an older cached environment. Keep pre-commit.ci as the formatting gate and reduce the workflow to the one hook pre-commit.ci does not run: check-manifest, which is manual-stage. Pin the two flake8 plugins so local runs, pre-commit.ci and the workflow resolve to the same tools. Pinning flake8-bugbear at 26.10.27 turns on B045, which flags five nested loops that reuse an enclosing loop's control variable. Rename the inner variables. The enumerate index in model_to_dot was only ever read by the inner loop that shadowed it, so drop it. No behaviour changes. Also drop the python-version matrix from the workflow, which has had no effect since fastmachinelearning#741 removed the setup-python step it fed.
The flake8 hook duplicated ruff's E, W and F checks; what it added was flake8-bugbear. Select B in ruff, plus PLE0100, PLE0101, PLW0129 and RUF024 for the bugbear checks ruff has no B code for, and drop the flake8 hook together with its pinned plugins. Ignore B028 and B905, which flake8-bugbear did not report on this tree and which need a decision at each call site, and chain the four re-raised exceptions B904 reports. Point ruff's include at test/, where the tests are, instead of the nonexistent tests/.
Member
Author
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.
Description
Stacked on #1599. This branch contains #1599's commit; the change proposed here is the last commit,
a75ae54. Rebase onto
mainonce #1599 merges. Opened as a draft until then.This removes the flake8 hook from
.pre-commit-config.yaml. The hook ran pycodestyle and pyflakes, which ruffalready runs as
E,WandF, plus two plugins. flake8-print checks onlyT201, and that code was in--extend-ignore. That left flake8-bugbear as the hook's only contribution, and since #1599 it has cost twopins that must be moved by hand, because pre-commit.ci's
autoupdatebumpsrev:but neveradditional_dependencies. This PR moves the bugbear coverage into ruff and drops the hook, its environment andboth pins.
What was compared
I measured this rather than reading it off the rule tables. The tools were the pinned versions, ruff 0.16.10
and flake8 7.4.1 with flake8-bugbear 26.10.27 and flake8-print 5.0.0, run over every tracked
.pyfile.main. No finding flake8 currently makes is lost.Badded reports 97 findings:B905×64,B028×29 andB904×4. The flake8 hook reportsnone of them, for two reasons:
B904andB905are among bugbear's opinionatedB9checks, which bugbear leaves off unless they areselected explicitly.
B028is on by default in bugbear, but bugbear only matcheswarnings.warn(...). Every hit here is abare
warn(...)imported withfrom warnings import warn, which ruff matches and bugbear does not.Coverage rule by rule: bugbear 26.10.27 has 47 checks enabled by default, not counting
B9. 35 of them have astable ruff
Bcode. For each of the other 12, I wrote a snippet, confirmed that the flake8 hook flags it,and ran ruff on it:
B001except:E722, already selectedB041F601, already selectedB037returnoryieldin__init__PLE0101/PLE0100, added hereB046dict.fromkeysRUF024, added hereB044asserton an always-true valuePLW0129(added) covers strings and f-strings,F631covers tuples; generators, lambdas, lists and dicts are not checkedB036except BaseExceptionwithout re-raisingB045B040add_note()that is never raisedB042__init__not passing all args tosuper()B043delattrwith a constant nameB047exceptclause unreachable after a broader oneB049@abstractmethodnot the innermost decoratorThe four codes added in the third column report nothing on the tree. Ruff does have broader rules close to
B036andB045, but neither is a like-for-like replacement, so neither is added:BLE001reports 33 hits here, because it also flagsexcept Exception.PLW2901reports 93 hits, because it also flags reassigning a loop variable inside its own body.B045is the one with a recent track record: #1599 fixed five instances of it. After this PR, nothing checksfor it.
Changes
pyproject.toml,lint.select: addsBand the four stand-in codes above.pyproject.toml,lint.ignore: addsB028andB905, with a comment. Neither is a mechanical fix.B028, the rightstackleveldepends on how far eachwarn()sits from user code.B905,strict=Falseon all 64zip()calls would only be noise, whilestrict=Truechangesbehaviour wherever the lengths can differ.
Enabling either is a separate decision.
E741 ignore: the hook's per-file
E741ignore forbit_exact.pyneeds no carrying over, because theglobal
lint.ignore = ["E741"]already covers it.B904fixes: the fourraisestatements insideexceptblocks now chain withfrom e:ahlslookup inAlteraBackend.buildkerassurgeonimport inreduce_modelortoolsimports inknapsack.pyThe original exception still appears in the traceback, which now says "direct cause" where it said
"during handling".
Ruff's file scope:
includelistedtests/**/*.py, but the tests live intest/; it now saystest/**/*.py. Under pre-commit this made no difference. Pre-commit passes file names, and ruff appliesonly
excludeto names it is given, so the 109 test files were already linted. A plainruff check .,however, skipped them.
Two scope differences from flake8 remain, both deliberate:
hls4ml/templates/**, so the threevivado_accelerator/*/python_drivers/axi_stream_driver.pyfiles that flake8 linted are no longer linted. They are clean under the new rules. Widening the scope
would also reformat all three, because the same
excludeapplies to ruff-format.docs/conf.py, which the flake8 hook excluded. It is clean..agents/contributing-changes.md: no longer describes a flake8 hook or pinned plugins, and the cleanupsweep no longer cites
flake8-print.Type of change
io_type, Strategy, or config attributeAffected areas
Backends: Altera (exception chaining in
AlteraBackend.buildonly)hls4ml.model)Frontends:
Components:
hls4ml/templates/Configurations affected and exercised
No configuration axis is involved.
io_typeNew configuration axis introduced by this PR (if any): none
Impact on generated HLS
Numerical behaviour: bit-exact vs
main. No code on the conversion path is touched.Tests
No test is added. Most of the change is lint configuration. The
B904edits only set__cause__onexceptions that are raised when an optional dependency or tool is missing.
Test configuration: macOS (Darwin 25.6.0), pre-commit 4.6.0, ruff 0.16.10, and flake8 7.4.1 under Python
3.12 for the comparison.
pre-commit run --all-files: every default-stage hook passes.pre-commit run --hook-stage manual --all-files:check-manifestfails locally for environmentreasons. Four submodules are uninitialised (
hls4ml/contrib/Coyote,hls4ml/templates/catapult/ac_*),and an untracked
hls4ml/templates/vitis/nnet_utils/nnet_conv1d_latency.h.bak~predates this change.This PR adds, moves and renames no files.
p-clang-formatrunssed -i.bakand does not remove the backups. Any all-files run thereforeleaves
.bakfiles underhls4ml/templates/, andcheck-manifestthen fails on them locally. That is notaddressed here.
test/pytest/test_agent_docs.py: passes (38 passed, 1 skipped).AI assistance disclosure
Tool(s) and model(s): Claude Code (Claude Opus 5.5)
Where it was used: the whole change. That covers the flake8 and ruff comparison and the per-rule probes, the
pyproject.tomland.pre-commit-config.yamledits, the fourB904fixes, the agent-doc update and thisdescription.
If anything other than None is ticked, confirm all of the following:
it. I have read and understood every line and can explain and defend it
in review.
no invented APIs, config keys, pragmas or citations.
actually performed, not from agent output.
my knowledge it does not reproduce third-party code that would conflict
with it.
Checklist
Required:
pre-commiton the files I edited.test/pytestcovering this change (a bug fix shouldadd a test that fails on
mainand passes here).commented-out blocks or unrelated changes.
If applicable:
docs/updated.Release note
🤖 Generated with Claude Code