Skip to content

chore(deps): bump ruff from 0.16.6 to 0.16.8 - #38

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/pip/ruff-0.16.8
Closed

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/pip/ruff-0.16.8

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Sep 22, 2026

Copy link
Copy Markdown
Contributor

Bumps ruff from 0.16.6 to 0.16.8.

Release notes

Sourced from ruff's releases.

0.16.8

Release Notes

Released on 2026-09-16.

Bug fixes

  • Visit functional TypedDict keyword arguments correctly (#28584)
  • [flake8-simplify] Detect nested async with under sync parent (SIM117) (#27821)
  • [flake8-simplify] Preserve operand order in SIM109 fix (#27824)
  • [pyupgrade] Preserve required parentheses in multiline UP040 fixes (#28164)
  • [pyupgrade] Skip TypeVarTuple and ParamSpec conversions with bounds or constraints (UP040, UP046, UP047) (#28505)

Rule changes

  • Add support for __lazy_modules__ (#28459)
  • Recognize PEP-728 TypedDict class keywords (#28533)
  • Recognize quoted types in typing.TypeForm (#28507)
  • Support conditional assignment to __lazy_modules__ (#28491)
  • [flake8-type-checking] Prefer lazy imports over TYPE_CHECKING on Python 3.15 and later (TC001, TC002, TC003) (#28541)
  • [pyupgrade] Make the fix for UP040 always unsafe (#28526)
  • [pyupgrade] Stop recommending deprecated ByteString aliases (UP035) (#28498)
  • [ruff, flake8-use-pathlib] Recognize the parent_mode argument (RUF064, PTH103) (#28528)
  • [ruff] Detect \Z in pytest.raises() match patterns (RUF043) (#28598)

CLI

  • Use rule name and code in formatter incompatibility warnings (#28571)

Configuration

  • [flake8-tidy-imports] Add extend-banned-api (#28644)

Contributors

Install ruff 0.16.8

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.8/ruff-installer.sh | sh
</tr></table> 

... (truncated)

Changelog

Sourced from ruff's changelog.

0.16.8

Released on 2026-09-16.

Bug fixes

  • Visit functional TypedDict keyword arguments correctly (#28584)
  • [flake8-simplify] Detect nested async with under sync parent (SIM117) (#27821)
  • [flake8-simplify] Preserve operand order in SIM109 fix (#27824)
  • [pyupgrade] Preserve required parentheses in multiline UP040 fixes (#28164)
  • [pyupgrade] Skip TypeVarTuple and ParamSpec conversions with bounds or constraints (UP040, UP046, UP047) (#28505)

Rule changes

  • Add support for __lazy_modules__ (#28459)
  • Recognize PEP-728 TypedDict class keywords (#28533)
  • Recognize quoted types in typing.TypeForm (#28507)
  • Support conditional assignment to __lazy_modules__ (#28491)
  • [flake8-type-checking] Prefer lazy imports over TYPE_CHECKING on Python 3.15 and later (TC001, TC002, TC003) (#28541)
  • [pyupgrade] Make the fix for UP040 always unsafe (#28526)
  • [pyupgrade] Stop recommending deprecated ByteString aliases (UP035) (#28498)
  • [ruff, flake8-use-pathlib] Recognize the parent_mode argument (RUF064, PTH103) (#28528)
  • [ruff] Detect \Z in pytest.raises() match patterns (RUF043) (#28598)

CLI

  • Use rule name and code in formatter incompatibility warnings (#28571)

Configuration

  • [flake8-tidy-imports] Add extend-banned-api (#28644)

Contributors

0.16.7

Released on 2026-09-10.

Preview features

  • [ruff] Add rule for default values on method receivers (RUF077) (#26700)

... (truncated)

Commits
  • 62914c4 Bump version to 0.16.8 (#28648)
  • c47e0cd [ty] Bound aliased intersection expansion during inference (#28546)
  • ff4747b renovate: update uv hashes correctly with setup-uv (#28621)
  • 94efeaa [ty] Compact reachable binding and declaration histories (#28349)
  • 50020fb [ty] Avoid storing constraint nodes twice (#28375)
  • 446bb68 [ty] Compare bound-method receivers before signatures (#28384)
  • 304ab86 [flake8-type-checking] Prefer lazy imports over TYPE_CHECKING on 3.15+ (`...
  • d940b24 [ty] Watch script dependencies in CLI watch mode (#28125)
  • fe9f065 [flake8-tidy-imports] Add extend-banned-api (#28644)
  • 31131db [ty] Support type[A & B] (#27124)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [ruff](https://github.com/astral-sh/ruff) from 0.16.6 to 0.16.8.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.16.6...0.16.8)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.16.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file python Pull requests that update python code labels Sep 22, 2026
cdeust added a commit that referenced this pull request Sep 26, 2026
Two gaps let #22/#32/#37/#38 merge green while CI kept testing the lock's
stale pins: ruff check ran without ruff format --check next to it, and
nothing compared requirements-dev.txt against requirements-dev.lock.

- Add a "ruff format --check plugins tests" CI step alongside the
  existing "ruff check" step.
- Add tools/check-lock-drift.py: parses top-level name==version pins out
  of both files and fails with the exact mismatch (package, .txt version,
  .lock version) when they disagree. Wired into CI right after the lock
  install step. Deterministic: no subprocess re-compile, no network, no
  wall-clock dependency, comparable to the check the issue itself used to
  diagnose the drift.
- tests/test_check_lock_drift.py covers the parser and the drift
  comparison directly, plus main()'s exit codes, plus a live check that
  the real requirements-dev.{txt,lock} pair in this repo is current.

Investigated whether dependabot could regenerate the lock itself instead
of a CI guard: it cannot, for this repo's file layout. dependabot-core's
pip-compile lockfile matcher hard-requires the lockfile name to end in
`.txt` (python/lib/dependabot/python/pip_compile_file_matcher.rb,
`return false unless name.end_with?(".txt")`,
https://github.com/dependabot/dependabot-core/blob/main/python/lib/dependabot/python/pip_compile_file_matcher.rb),
and even then needs either a `--output-file=<name>` pragma in the
lockfile matching pip-compile's own header, or a same-basename `.in`
manifest (https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference,
"pip and pip-compile" section, https://raw.githubusercontent.com/github/docs/main/data/reusables/dependabot/supported-package-managers.md).
requirements-dev.lock has neither: it is a `.lock` file, produced by
`uv pip compile -o requirements-dev.lock` (not `--output-file=`), from
a source file that is itself named `.txt` rather than `.in`. Making
dependabot manage this lock natively would require renaming
requirements-dev.txt -> requirements-dev.in and requirements-dev.lock
-> requirements-dev.txt, which changes the CI install path and is a
separate, deliberate decision, not a drive-by rename bundled into this
fix. This CI guard is the substitute until that decision is made.

Gate evidence: check-lock-drift.py against the real files exits 0; a
scratch copy with `ruff==0.16.6` desynced to `0.15.20` exits 1 and names
the exact mismatch. Full suite: 80 passed, coverage 93% (fail_under 80).

Fixes #39.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cdeust added a commit that referenced this pull request Sep 26, 2026
…uture drift (#41)

* fix(deps): regenerate requirements-dev.lock from requirements-dev.txt

The lock was stuck at ruff==0.15.20 while requirements-dev.txt declared
0.16.6 (dependabot #22, #32), so CI's pip install --require-hashes -r
requirements-dev.lock never installed the version the source file bumped
to. Regenerated with the exact command recorded in the lock's own header:
uv pip compile requirements-dev.txt --generate-hashes --universal
--python-version 3.11 -o requirements-dev.lock.

Verified in a fresh venv: pip install --require-hashes -r
requirements-dev.lock installs coverage==7.16.0, pytest==9.1.1,
ruff==0.16.6, matching requirements-dev.txt exactly.

Fixes #39 (partial: lock/tool drift).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(lint): resolve ruff 0.16.6 check findings outside PR #40's scope

CI installed ruff from the drifted lock (0.15.20), so the 0.16.6 rules
requirements-dev.txt already declared never ran. Root-cause fixes, no
noqa and no rule disabling in pyproject/ruff config:

- SIM115 (subagent_usage.py, transcript.py): merge open() into the with
  statement instead of a bare fh = open(...) guarded by try/finally.
- PLW1510 (measure_refine_overhead.py, test_refine_gate.py,
  test_release_tools.py, test_statusline_layout.py): add explicit
  check=False to subprocess.run calls that inspect returncode themselves
  and intentionally tolerate nonzero exits.
- I001/RUF100/FURB122 (oklch2srgb.py, test_measure_refine_overhead.py,
  test_portable_packaging.py, test_statusline_transcript.py,
  test_subagent_usage.py): ruff check --fix for import sorting, an
  unused noqa, and fh.write loops replaced with fh.writelines.
- EXE001 (transcript.py, oklch2srgb.py): chmod +x. Both carry a
  documented direct-invocation usage line; the shebang was already
  correct, only the executable bit was missing.

Boy-scout (coding-standards.md section 4/14): the SIM115 rewrite of
parse_transcript_usage pushed subagent_usage.py past the nesting-depth
cap, and touching measure_refine_overhead.py surfaced a pre-existing
cap violation in collect_prompts. Both extracted into small per-record
helpers (_keyed_usage_record plus _dedupe_by_message, _extract_prompt)
instead of suppressing the check.

Excludes plugins/context-guard/hooks/{stop-context-guard.py,
subagent-tracker.py} and tests/test_context_guard_hooks.py: PR #40
already fixes and formats these.

ruff check plugins tests (0.16.6): 0 findings outside the excluded
files (verified after this commit). tests/test_subagent_usage.py:
18 passed.

Fixes #39 (partial: check findings).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(fmt): ruff format 0.16.6 the remaining non-excluded files

Whitespace/wrapping only. AST identity verified with ast.dump()
sha256 before/after for every file this change touches:

  checkpoint_protocol.py  d8580ec5ac68b969...  ==  d8580ec5ac68b969...
  refine_gate.py          2ecd82bd5d017134...  ==  2ecd82bd5d017134...
  subagent_usage.py       (already conforming after the lint commit)
  transcript.py           00b15845a3e03a60...  ==  00b15845a3e03a60...
  oklch2srgb.py           3bf05ec6c2f4fcc6...  ==  3bf05ec6c2f4fcc6...
  test_measure_refine_overhead.py  5341f190...  ==  5341f190...
  test_refine_gate.py     1cd22849c777a1da...  ==  1cd22849c777a1da...
  test_release_tools.py   c2a7efb4e3d79189...  ==  c2a7efb4e3d79189...
  test_statusline_layout.py        8067ac60...  ==  8067ac60...
  test_statusline_transcript.py    b0f5db46b508...  ==  b0f5db46b508...
  test_subagent_usage.py  00153473a94361a0...  ==  00153473a94361a0...

(full sha256 pairs computed against a from-scratch reconstruction:
git-blob original -> reapply the lint fixes from the prior commit ->
hash -> ruff format -> hash again; identical both times for all 11
files.)

Note: for 9 of the 11 files above, the lint-fix commit that precedes
this one already carried ruff-format's output (a scratch-reconstruction
mixup applied format before the copy-back), so this commit's diff is a
no-op for those files and only reformats checkpoint_protocol.py and
refine_gate.py, which had no check findings. ruff format --check
plugins tests: clean outside plugins/context-guard/hooks/{stop-context-
guard.py,subagent-tracker.py} and tests/test_context_guard_hooks.py
(PR #40's scope).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(deps): add ruff format check and a lock-drift guard (issue #39)

Two gaps let #22/#32/#37/#38 merge green while CI kept testing the lock's
stale pins: ruff check ran without ruff format --check next to it, and
nothing compared requirements-dev.txt against requirements-dev.lock.

- Add a "ruff format --check plugins tests" CI step alongside the
  existing "ruff check" step.
- Add tools/check-lock-drift.py: parses top-level name==version pins out
  of both files and fails with the exact mismatch (package, .txt version,
  .lock version) when they disagree. Wired into CI right after the lock
  install step. Deterministic: no subprocess re-compile, no network, no
  wall-clock dependency, comparable to the check the issue itself used to
  diagnose the drift.
- tests/test_check_lock_drift.py covers the parser and the drift
  comparison directly, plus main()'s exit codes, plus a live check that
  the real requirements-dev.{txt,lock} pair in this repo is current.

Investigated whether dependabot could regenerate the lock itself instead
of a CI guard: it cannot, for this repo's file layout. dependabot-core's
pip-compile lockfile matcher hard-requires the lockfile name to end in
`.txt` (python/lib/dependabot/python/pip_compile_file_matcher.rb,
`return false unless name.end_with?(".txt")`,
https://github.com/dependabot/dependabot-core/blob/main/python/lib/dependabot/python/pip_compile_file_matcher.rb),
and even then needs either a `--output-file=<name>` pragma in the
lockfile matching pip-compile's own header, or a same-basename `.in`
manifest (https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference,
"pip and pip-compile" section, https://raw.githubusercontent.com/github/docs/main/data/reusables/dependabot/supported-package-managers.md).
requirements-dev.lock has neither: it is a `.lock` file, produced by
`uv pip compile -o requirements-dev.lock` (not `--output-file=`), from
a source file that is itself named `.txt` rather than `.in`. Making
dependabot manage this lock natively would require renaming
requirements-dev.txt -> requirements-dev.in and requirements-dev.lock
-> requirements-dev.txt, which changes the CI install path and is a
separate, deliberate decision, not a drive-by rename bundled into this
fix. This CI guard is the substitute until that decision is made.

Gate evidence: check-lock-drift.py against the real files exits 0; a
scratch copy with `ruff==0.16.6` desynced to `0.15.20` exits 1 and names
the exact mismatch. Full suite: 80 passed, coverage 93% (fail_under 80).

Fixes #39.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(deps): rename to the .in/.txt pair dependabot's uv ecosystem manages

Fixing the drift guard in CI (dd60499) was a substitute for the real gap:
dependabot could never regenerate the old requirements-dev.lock, so every
future bump would keep needing a manual lock rebuild. Move to the naming
dependabot-core's uv ecosystem actually recognizes for a compiled lockfile.

requirements-dev.txt (human-edited manifest) -> requirements-dev.in.
requirements-dev.lock (uv-compiled, hash-locked) -> requirements-dev.txt,
recompiled with:
  uv pip compile requirements-dev.in --generate-hashes --universal
  --python-version 3.11 --output-file=requirements-dev.txt
which embeds a --output-file=requirements-dev.txt pragma in the header.

Re-read uv/lib/dependabot/uv/requirements_file_matcher.rb at a pinned
dependabot-core commit before making this change:
https://github.com/dependabot/dependabot-core/blob/f3a79fa0711aca171b2174b855d9f21b16237961/uv/lib/dependabot/uv/requirements_file_matcher.rb
compiled_file?(file) requires the candidate lockfile to end in .txt, then
matches it to its manifest via EITHER the --output-file= pragma above OR a
same-basename .in file. requirements-dev.txt now satisfies both. Also
read uv/lib/dependabot/uv/file_fetcher.rb at the same commit: its own
required_files_message is "Repo must contain a requirements.txt, uv.lock,
requirements.in, or pyproject.toml" -- confirming this plain .in/.txt pair
needs no pyproject.toml or uv.lock to be picked up by the uv ecosystem.

Changed .github/dependabot.yml's pip entry to package-ecosystem: "uv":
the pip ecosystem's own matcher (python/lib/dependabot/python/pip_compile_file_matcher.rb)
has the identical .txt-only rule, but its resolver shells out to
pip-tools' pip-compile, not uv, and would not reproduce this lock's
format. The docs table lists uv as v0.11 supported
(https://raw.githubusercontent.com/github/docs/main/data/reusables/dependabot/supported-package-managers.md);
the installed compiler here is uv 0.11.3.

Updated every reference to the old names: .github/workflows/ci.yml and
release.yml install steps, tools/check-lock-drift.py (+ its test, now
comparing .in vs .txt), README.md, CONTRIBUTING.md, .bestpractices.json.
Grepped the tree for both old filenames afterward; only remaining hit is
a historical "used to install from ... requirements-dev.lock" sentence in
check-lock-drift.py's own docstring, describing the bug this fixes.

Added --no-deps to every --require-hashes install site touched by this
commit, per this repo's no-deps-gate hook (ADR-1062): a fully hash-pinned
closure should not ask pip to re-derive dependencies.

Gates: fresh venv install from the new requirements-dev.txt with
--require-hashes --no-deps gives coverage==7.16.0, pytest==9.1.1,
ruff==0.16.6 (as requirements-dev.in declares). Drift guard: 0 on the real
.in/.txt pair, 1 with the exact mismatch on a scratch copy desynced to
ruff==0.15.20. Full suite: 80 passed. ruff check and ruff format --check
plugins tests: same 8/3 findings as before this commit, all in PR #40's
three excluded files.

Verified PR #40 (fix/context-guard-smoke-and-structure) at its current
tip aec0f18: ruff check and ruff format --check are both clean under
0.16.6 for all three files this PR excludes. The 4 findings measured
earlier in tests/test_context_guard_hooks.py are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(review): address REQUEST CHANGES on PR #41

Three blocking findings from a fresh code review, each fixed with a test
that is red before the fix and green after.

1. plugins/context-guard/tools/subagent_usage.py::parse_transcript_usage
   (SIM115 rewrite in 8a53bd8): the with-statement rewrite widened the
   except (OSError, TypeError, ValueError) to cover the whole record loop,
   so a malformed per-record usage payload (e.g. input_tokens: "abc")
   silently returned a zeroed Usage() instead of raising. Restored the
   original exception scope, guarding only open(), by extracting
   _open_transcript(path) so the open() call still satisfies SIM115 (it is
   the head expression of its own with statement) while the record loop's
   ValueError/TypeError propagates as before. Test
   test_parse_raises_on_malformed_record_usage: raw output confirms red
   against 8a53bd8's subagent_usage.py (prints the zeroed Usage, no raise)
   and green against this commit (pytest.raises(ValueError) passes).

2. tools/check-lock-drift.py _PIN_RE/_parse_pins: extras syntax
   (pkg[extra]==1.0) broke the name-character class, silently dropping the
   pin from both sides of the comparison. coverage[toml]==7.16.0 in the
   manifest vs. coverage[toml]==5.0.0 in the lock is real, > 1 major
   version drift; before this fix find_drift() reported nothing and the
   guard printed "matches every pin", exit 0 -- precisely the silent-drift
   failure mode this tool exists to prevent. _PIN_RE now accepts an
   optional [..] extras group. Also added _parse_manifest_pins: every
   non-blank, non-comment, non-option (-e/-r/...) line in
   requirements-dev.in that _PIN_RE still can't match now raises
   ValueError naming the file line, instead of being silently skipped;
   main() catches it and exits 1 with the message. Raw before/after on the
   extras repro and on an unparseable-manifest-line repro are in this
   commit's test run output (tests/test_check_lock_drift.py).

3. Same file, _parse_pins/_parse_manifest_pins: name comparison was
   case-only (.lower()), so Foo-Bar and foo_bar were treated as different
   packages -- a false "absent from the lock" for the identical PEP 503
   identity at the same version. Added a _normalize() helper implementing
   PEP 503 (https://peps.python.org/pep-0503/#normalized-names):
   re.sub(r"[-_.]+", "-", name).lower(). Mutation-tested: removing the
   .lower() call fails 4 tests, removing the re.sub separator collapse
   fails 2 tests (test_normalize_lowercases,
   test_normalize_collapses_separators,
   test_desynced_separator_variant_is_recognized_as_the_same_package,
   test_separator_variant_with_real_drift_is_still_caught) -- both
   mutants independently killed, both restored to the correct
   implementation before this commit.

Non-blocking: added the one-directional-by-design note to
check-lock-drift.py's module docstring (manifest -> lock only; a compiled
--universal lock legitimately carries transitives like iniconfig,
packaging, pluggy, pygments that never appear in the manifest, so the
reverse direction would false-positive on every compile).

Boy-scout: chmod +x tools/gen-bundle-sbom.py. Seen while running this
task's own gate command (ruff check/format --check ... tools, the first
time tools/ was in scope for either), same class of fix as the two files
corrected the same way in 0d992fe (documented direct-invocation usage,
shebang already correct, only the executable bit missing).

Gates, fresh venv from requirements-dev.txt with --require-hashes
--no-deps (coverage==7.16.0 pytest==9.1.1 ruff==0.16.6): full suite 103
passed. ruff check plugins tests tools and ruff format --check plugins
tests tools: both clean. check-lock-drift.py: 0 on the real
requirements-dev.in/.txt pair, 1 with the exact mismatch on a scratch
ruff==0.15.20 desync and on a coverage[toml] extras desync.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: lint and format-check tools/ too

tools/ holds check-lock-drift.py, the guard this PR adds; it sat outside
CI's own ruff gate. Both commands are clean on tools/ today.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@cdeust

cdeust commented Sep 26, 2026

Copy link
Copy Markdown
Owner

Superseded by #43 (uv ecosystem, updates the hashed lock).

@cdeust cdeust closed this Sep 26, 2026
@dependabot @github

dependabot Bot commented on behalf of github Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot
dependabot Bot deleted the dependabot/pip/ruff-0.16.8 branch September 26, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant