Conversation
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 Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #63 +/- ##
=======================================
Coverage 96.89% 96.89%
=======================================
Files 5 5
Lines 129 129
=======================================
Hits 125 125
Misses 4 4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
why: The unreleased entry tracks dev-tooling floors so contributors know which linter version the repo's diagnostics assume. what: - Add a `### Development` bullet for the `ruff>=0.16.0` floor
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 ea200b3.
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 - Name the linter behind `FA100` instead of describing the rule Enabled rules go from 351 to 565. https://docs.astral.sh/ruff/linter/#rule-selection
why: `docs/conf.py` collects the project's title, copyright, and URLs by exec'ing the package's `__about__.py` into a dict, because `g/__init__.py` re-exports only `__version__`. The input is a tracked 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 ruff floor entry covered the version bump but not the rule selection change that rides with it. what: - Note that lint runs on ruff's default set plus this project's linters - Name the scoped per-file ignore and why it exists
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.
Summary
ruff>=0.16.0floor in thedevandlintdependency groups so contributors and CI resolve the same linter and see the same diagnostics.uv.lockonto ruff 0.16.0.selectbecomesextend-select, so this project's linters layer on top of ruff's curated default set instead of replacing it. Enabled rules go from 351 to 565.S102on theexecindocs/conf.py— and it is intentional.Changes
pyproject.toml —
ruffraised to>=0.16.0in[dependency-groups] devandlint;[tool.ruff.lint] selectrenamed toextend-selectwith a comment recording whyselectstays unset;S102per-file-ignored fordocs/conf.py.uv.lock — ruff 0.15.22 -> 0.16.0.
CHANGES — entries for the floor bump and the rule-set adoption.
Design decisions
Why
extend-selectrather than a widerselectruff 0.16 ships a curated default rule set as its recommended baseline. An explicit
selectreplaces that set rather than extending it, so this project was silently opting out of everything ruff considers a sensible default. There is no token that names the default set from insideselect— ruff's selector grammar has noDEFAULT— so the only way to get defaults-plus-extras is to leaveselectunset and layer the project's linters throughextend-select.The alternative of naming whole prefixes (
PL,S,PYI, ...) inselectwas rejected: it drags in the full contents of each family rather than the curated subset, which is far noisier for no added signal.Every
extend-selectentry stays on its own line with a trailing comment naming the linter it selects.FA100's comment now namesflake8-future-annotationsrather than describing the rule.The one finding
S102 (
exec-builtin) indocs/conf.py. Sphinx collects the project's title, copyright, and URLs by exec'ing the package's__about__.pyinto a dict, becauseg/__init__.pyre-exports only__version__. The exec'd input is a tracked file in this repository, not user data, so the flake8-bandit warning has nothing to warn about here. Scoped as a per-file-ignore ondocs/conf.pyrather than repo-wide, with the reason recorded in the config.No code changes were needed: nothing else in
src/,tests/, ordocs/trips a default rule.ruff 0.16 rule stabilizations
ruff 0.16.0 stabilizes several rules that live inside prefixes this project already selects, notably RUF036, RUF063, and RUF068, plus behavior changes to UP019 and the
B/SIM/TRYfamilies. None of them fire here.ruff 0.16.0 also formats Python and pycon code blocks inside Markdown by default. All Markdown under the repo (including
docs/) is picked up byruff formatand came back already formatted, so there is no churn.CHANGEShas no.mdextension and is not in scope forruff format; it stays on theprettierpath in theformat_markdownmake target.See https://astral.sh/blog/ruff-v0.16.0 for the full release notes.
Test plan
uv run ruff check .— all checks passeduv run ruff format --check .— every file already formatteduv run mypy .— no issues founduv run py.test— passes in a normal checkoutNote on running the suite from a linked worktree:
tests/test_cli.py::test_command_line[g-cmd-inside-git-dir]and[g-cmd-help-inside-git-dir]fail there becausefind_repo_typerequires.gitto be a directory, and a linked worktree's.gitis a file. Both fail identically at the base commit, so this is not a regression from this branch, and CI's plain checkout is unaffected.