Repository navigation
Ruff config enforces almost nothing, inviting out-of-scope lint sweeps #161
Description
Summary
The Ruff setup enforces almost nothing, and the gap is wide enough that contributors reasonably assume the opposite. This produces large "lint cleanup" diffs that CI neither requires nor rejects.
Current state
.github/workflows/python-package-version-test.yml runs:
- name: Lint with ruff
run: |
python -m ruff check pyreason/scriptsand pyproject.toml configures only:
[tool.ruff.lint]
# Ignore ambiguous variable name errors (E741) in interpretation files
[tool.ruff.lint.per-file-ignores]
"pyreason/scripts/interpretation/*.py" = ["E741"]There is no select, so Ruff falls back to its default rule set: E4, E7, E9, F — a narrow slice of pycodestyle plus pyflakes. Everything else is off, including the rules most people expect a Ruff gate to cover:
I001import sortingUPpyupgradeSIMflake8-simplifyRUF012mutable class attributes needingClassVarB/BLEflake8-bugbear and blind-except
Two smaller scope gaps in the same command:
- Only
pyreason/scriptsis linted.pyreason/__init__.pyandpyreason/pyreason.pyare not, nor aretests/orexamples/. - Note the empty
[tool.ruff.lint]table above[tool.ruff.lint.per-file-ignores]— it currently holds nothing but the comment.
Why it matters
A contributor who runs ruff check --fix locally with a stock editor config gets a very different result from CI, and produces a sweeping diff believing it was required to get the build green.
This happened in #160: an import-sorting, SIM, UP, RUF012 and BLE001 sweep touched ~45 files alongside a ~12-line performance change. None of it was needed — CI was already passing — and it was reverted so the actual optimization could be reviewed. Without a config change the same thing will recur, and any convention applied by hand will drift straight back since nothing holds it in place.
Suggested resolution
Decide explicitly, in either direction — both are defensible, but the current state is neither:
Option A — enforce a real rule set. Add select to [tool.ruff.lint], land the one-time sweep as its own standalone PR (never mixed with behavioral changes), and consider adding ruff format --check. Worth starting conservative, e.g. ["E4", "E7", "E9", "F", "I", "UP"], and growing it, since SIM and B are noisier on numba-heavy code.
Option B — document the narrow gate. Keep the default rules and add a CONTRIBUTING.md note saying only E4/E7/E9/F are enforced and broader autofixes should not be submitted. Cheaper, and honest about what the gate does.
Either way, worth deciding whether the lint command should cover pyreason/ rather than just pyreason/scripts.
One constraint on Option A: interpretation.py and interpretation_parallel.py are asserted byte-identical except the parallel= decorator by tests/unit/dont_disable_jit/test_parallel_consistency.py. Any autofix must land on both files identically or that test fails.
Activity
ColtonPayne commentedon Aug 14, 2026
Closing — resolved by pinning ruff, and correcting the diagnosis above.
The issue body is wrong on its central claim. It states that with no
select, Ruff falls back toE4/E7/E9/F. That was true until Ruff 0.16.0 (2026-07-23), which expanded the default rule set from 59 rules to 413 — the first change to that default since v0.1.0. This repo sets noselectand the workflow installed ruff unpinned, so it inherited all 413 and reports ~289 findings.So the premise was inverted: the lint sweep in #160 was not unnecessary churn, it was a correct and required response to a breaking upstream change. #160's run history shows exactly that —
Lint with rufffailing on 2026-07-27 and 07-28, four days after 0.16.0 shipped, then green once the sweep landed.This was never scoped to one PR.
mainhas not run CI since 2026-05-13 and fails identically, so every PR opened after 0.16.0 was broken on arrival regardless of contents.Resolution: pin to
ruff==0.15.22, the last release with the old default, so lint results depend on the code rather than on when the job ran. One side effect worth recording: 0.16 also dropped 18 rules from the defaults including E741, so the existingper-file-ignoresentry is dead config under 0.16 but live again under this pin — keep it.Adopting the broader 413-rule set is still worth doing deliberately: add an explicit
select, land the cleanup as its own reviewed PR, and unpin. Worth a fresh issue if someone wants to take it, rather than reopening this one under a false premise.