Skip to content

Repair violations from Ruff 0.16's expanded defaults - #33

Merged
jaraco merged 2 commits into
mainfrom
ruff-0.16-defaults
Sep 10, 2026
Merged

jaraco merged 2 commits into
mainfrom
ruff-0.16-defaults

Conversation

@jaraco

@jaraco jaraco commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Ref jaraco/skeleton#210.

Ruff 0.16 broadened its built-in default rule set, and because ruff.toml uses extend-select, this project inherited 19 new violations. All are now repaired; ruff check . and ruff format --check . are clean and the test suite (including mypy) passes.

Changes

Mechanical / no behavior change

  • git.py: startswith called once with a tuple (PIE810); '...'.split() replaced with list literals here and in migrate-config.py (SIM905); Project.tags annotated ClassVar (RUF012); Project.__new__'s first parameter renamed selfcls (PLW0211).
  • compiler.py: nested with statements combined (SIM117). The blind except Exception is deliberate — the function's contract is to report any compile failure as a string — so it carries a noqa and a comment rather than a narrowed clause (BLE001).
  • indent.py, migrate-config.py: unused unpacked variables renamed to _ (RUF059).

Behavior changes worth a look

  • init-azure.py and macos-build-python.py pass check=True: their steps are sequential and dependent (configure → make; create project → create endpoint → create pipeline), so continuing after a failure only produced a confusing second failure (PLW1510).
  • git.py's URLScheme.load and cpython-sync.py's final git commit pass check=False, since a non-zero exit is an expected outcome for both (no configured substitutions; nothing to commit). Both are commented.
  • projects-run.py: the = [] typer defaults become | None = None, matching the style already in update-projects.py, with the two lists joined via itertools.chain (B006). Verified that --tag/--keyword still collect multiple values.
  • github.py: Repo.get_public_key() becomes the Repo.public_key cached property (B019). functools.lru_cache on a method kept every Repo instance alive for the process and shared one key across repos; cached_property caches per instance. This is the one API break — happy to keep the method name via jaraco.functools.method_cache instead if you'd rather not spend a major version on it.

🤖 Generated with Claude Code

Ref jaraco/skeleton#210.

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

jaraco commented Sep 10, 2026

Copy link
Copy Markdown
Owner Author

CI note: everything passes except collateral (diffcov), which requires 100% coverage of changed lines. 19 of the 27 changed lines live in modules that had no coverage to begin with (init-azure, macos-build-python, migrate-config, compiler, indent), so touching them is enough to fail the gate. diffcov is also failing on main right now for the same reason, so this isn't a regression introduced here.

Also worth noting: .pre-commit-config.yaml still pins ruff-pre-commit at v0.12.0, so CI never saw these violations — they only appear with a local Ruff 0.16. I left the pin alone since it's skeleton-managed and jaraco/skeleton#210 declines to take on the bumping burden.

@jaraco jaraco closed this Sep 10, 2026
@jaraco jaraco reopened this Sep 10, 2026
Comment thread jaraco/develop/projects-run.py Outdated
Comment on lines +24 to +33
list[filters.Tag] | None, typer.Option('--tag', '-t', parser=filters.Tag)
] = None,
keyword: Annotated[
list[filters.Keyword],
list[filters.Keyword] | None,
typer.Option('--keyword', '-k', parser=filters.Keyword),
] = [],
] = None,
*,
ctx: typer.Context,
):
selectors = filters.Selectors(tag + keyword)
selectors = filters.Selectors(itertools.chain(tag or (), keyword or ()))

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not loving this change. The prior implementation had a simpler signature and usage. Is there a way we can continue to use degenerate sequences instead of a separate None type?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — reverted to the original signature and tag + keyword body in 8aece41, with a # noqa: B006 on each default.

I did try to keep it lint-clean without the suppression, but typer boxes you in: = () works at runtime (typer replaces it with a list either way, verified) yet mypy rejects a tuple default against a list[...] annotation, and typer can't consume the annotations that would fix that — Sequence[str] raises RuntimeError: Type not yet supported, and tuple[str, ...] raises Type not yet supported: Ellipsis. So list[X] = [] is the only spelling that satisfies both typer and mypy.

The suppression is honest here: typer always supplies the option value, so the default is never bound, let alone mutated — the same reason the skeleton already ignores B008 globally for = typer.Option(...). If you'd rather not carry inline noqas, B006 could join B008 in the skeleton's ignore list on the same rationale; happy to make that change instead.

typer supplies the option values, so the empty lists are never mutated;
suppress B006 rather than complicate the signature with None.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jaraco
jaraco merged commit 0f60a83 into main Sep 10, 2026
32 of 36 checks passed
@jaraco
jaraco deleted the ruff-0.16-defaults branch September 10, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant