Skip to content

Adopt ruff 0.16 and its default rule set#356

Merged
tony merged 8 commits into
masterfrom
ruff-0.16
Jul 26, 2026
Merged

Adopt ruff 0.16 and its default rule set#356
tony merged 8 commits into
masterfrom
ruff-0.16

Conversation

@tony

@tony tony commented Jul 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Migrate the linter floor to ruff>=0.16.0 in the dev and lint dependency groups so contributors and CI see the same diagnostics
  • Adopt ruff 0.16's curated default rule set by switching [tool.ruff.lint] select to extend-select, taking the enabled-rule count from 351 to 565

Changes

Dependencies

pyproject.toml: ruff floor raised to >=0.16.0 in the dev and lint groups. uv.lock: relocked, ruff 0.15.22 -> 0.16.0.

Lint configuration

select is now extend-select, with every entry on its own line carrying the name of the linter it selects. An explicit select replaces ruff's default rule set rather than extending it, so the project was silently opting out of the 413 rules ruff 0.16 recommends as its baseline. There is no DEFAULT token that a select list could name — leaving select unset is the only way to get defaults-plus-extras — so the file carries a comment saying so, to stop the key being reintroduced.

Findings fixed

PIE810 (multiple-starts-ends-with) in tests/test_install_widget.py: the docs-only package filter chained two startswith calls against the same name with or. str.startswith takes a tuple of prefixes, so this is one call.

Findings ignored

S102 (exec-builtin) in docs/conf.py: the Sphinx config reads the package's version metadata by exec'ing __about__.py, which keeps the docs build off an import of the package it documents. The input is a file in this repository, not user data, so the flake8-bandit warning has nothing to warn about. Scoped per-file, not globally.

Design decisions

Floor, not pin: >=0.16.0 rather than ==. The lockfile already reproduces the exact version for this repo; the floor exists to keep a contributor on an older ruff from producing a passing local run that fails CI.

extend-select, not wider prefixes: expanding the existing select to whole prefixes (PL, S, D, …) was measured elsewhere in this ecosystem and rejected — it is one to two orders of magnitude noisier than the curated default set, because it drags in every rule in each family rather than the subset ruff recommends.

One commit per decision: the config change, the fix, and the ignore each land alone, so the rationale for each rule is recoverable from git log rather than buried in a batch.

Test plan

  • uv run ruff check . — clean
  • uv run ruff format --check . — clean, now including Markdown code blocks
  • uv run mypy — clean
  • uv run py.test — full suite green, including doctests over src/, tests/, and docs/

tony added 2 commits July 26, 2026 13:22
why: uv's global `exclude-newer = "3 days"` supply-chain cooldown hides
ruff 0.16.0 (released 2026-07-23) from the resolver, so the version
floor in the next commit cannot resolve.

what:
- Add `ruff = false` to `[tool.uv.exclude-newer-package]`

Temporary. Revert before merge - the cooldown clears on its own and the
`ruff>=0.16` floor is what actually holds the version.
why: ruff 0.16.0 stabilizes rules inside prefixes this project already
selects and starts formatting Python code blocks in Markdown. Pinning a
floor keeps contributors and CI on the same diagnostics instead of
splitting on whatever ruff each machine resolved.

what:
- Raise `ruff` to `>=0.16.0` in the `dev` and `lint` dependency groups
- Relock `uv.lock`: ruff 0.15.22 -> 0.16.0

https://astral.sh/blog/ruff-v0.16.0
@codecov

codecov Bot commented Jul 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.98%. Comparing base (19a7bc1) to head (931f44e).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #356   +/-   ##
=======================================
  Coverage   88.98%   88.98%           
=======================================
  Files          12       12           
  Lines         690      690           
=======================================
  Hits          614      614           
  Misses         76       76           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

tony added 6 commits July 26, 2026 13:26
why: The unreleased entry tracks dev-tooling floors so contributors know
which ruff their local run must match.

what:
- Add `#### Ruff 0.16 lint floor (#356)` under `### Development`
why: ruff 0.16.0 published 2026-07-23T19:10Z and has now cleared uv's
3-day supply-chain cooldown, so the resolver reaches it unaided. The
`ruff>=0.16.0` floor is what holds the version; leaving the exemption
would permanently opt ruff out of the cooldown guard.

what:
- Drop `ruff = false` from `[tool.uv.exclude-newer-package]`
- Relock: the setting is recorded in `uv.lock`, so removing it forces a
  re-resolve. ruff stays at 0.16.0 and no other package moves.

This reverts commit bf2852c.
why: ruff 0.16 ships a curated 413-rule default set as its recommended
baseline. An explicit `select` replaces that set rather than extending
it, so this project was running 351 rules and silently opting out of the
default set. `extend-select` layers the project's own linters on top of
the default set instead of in place of it.

what:
- Replace `select` with `extend-select`, same entries, one per line
- Note in the file why `select` stays unset

Enabled rules go from 351 to 565.
https://docs.astral.sh/ruff/linter/#rule-selection
why: `str.startswith` accepts a tuple of prefixes, so the docs-only
package filter needs one call rather than a chain of `or`ed calls
against the same name.

what:
- Pass `("gp-", "sphinx")` to a single `startswith`

https://docs.astral.sh/ruff/rules/multiple-starts-ends-with/
why: `docs/conf.py` reads the package's version metadata by exec'ing
`__about__.py` so the docs build does not import the package it is
documenting. The input is a file in this repository, not user data, so
the flake8-bandit warning has nothing to warn about here.

what:
- Per-file-ignore S102 for `docs/conf.py`

https://docs.astral.sh/ruff/rules/exec-builtin/
why: The unreleased entry tracks dev-tooling changes, and adopting
ruff's default rules changes what a contributor's local `ruff check`
reports.

what:
- Add `#### Ruff's default rule set (#356)` under `### Development`
@tony tony changed the title Require ruff>=0.16.0 Adopt ruff 0.16 and its default rule set Jul 26, 2026
@tony
tony merged commit 8ef8f33 into master Jul 26, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant