Modernize tools, drop from __future__ import annotations, and fix lint CI#10
Merged
Conversation
The lint CI pointed mypy at directories that don't exist (src/packages/tests) while the real code lives in tools/, the code carried no annotations (so mypy --strict and ruff's ANN/D rules failed), the mypy config loaded a pydantic plugin that isn't a dependency, and coverage_diff's sphobjinv import was unresolved for the type checkers. Tooling: - Point mypy at tools/ + noxfile.py in the workflow and the noxfile - Declare sphobjinv as a dependency so `uv sync` resolves it; tell mypy it ships no py.typed marker - Drop the unused pydantic.mypy plugin - Curate a ruff ignore list for select=ALL: formatter conflicts, the TC family (it assumes stringized annotations), and per-file allowances for CLI print / boolean-trap / arg-count / broad-except / url-open Code: - Remove `from __future__ import annotations` from all three tools - Add full type annotations; PEP 695 `type` aliases for the record and version-key shapes - pathlib over os.path/glob/open; itertools.pairwise over zip(x, x[1:]); a dict comprehension for the union build - Name the magic comparison values and add docstrings - Drop the now-dead sys.stdlib_module_names guard and an unused _markdown_summary parameter ruff (format + check), mypy --strict, ty, and prek all pass; the three tools still run end-to-end (introspect -> merge -> coverage diff). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rh5G5LSDPMWLgX3cYLWUnk
The stdlib-introspect matrix runs these scripts on Python 3.10-3.15, but the previous commit (and #8) left them using newer syntax that 3.10-3.13 cannot parse: - PEP 695 `type X = ...` aliases -> `TypeAlias` - PEP 758 parenthesis-free `except A, B:` -> parenthesized Add tools/ruff.toml pinning target-version = py310 (extending the root config) so Ruff lints these files at the matrix floor rather than the repo's dev requirement -- otherwise UP040 demands the `type` statement back. That lower target re-enables PERF203 (a no-op once exceptions are zero-cost), so ignore it for the tools' I/O retry/parse loops. The rest of the modernization (annotations, pathlib, itertools.pairwise, docstrings, dropped __future__ import) is already 3.10-compatible and stays. Verified: ruff/mypy/ty/prek pass on the 3.14 dev env; all three tools compile on 3.10, and stdlib_introspect + merge_summary run there. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rh5G5LSDPMWLgX3cYLWUnk
Only stdlib_introspect.py runs across the introspect matrix (3.10-3.15); merge_summary.py and coverage_diff.py run on the aggregate/coverage jobs' "3.x", so they don't need legacy support. The previous commit pinned all of tools/ to py310 via tools/ruff.toml, which over-applied the floor. Ruff's target-version is directory-scoped, not per-file, so instead of a directory config this scopes the one genuine conflict precisely: - stdlib_introspect.py keeps `TypeAlias` and ignores UP040 (which would demand the 3.12 `type` statement) for that file only. Its `except (ValueError, TypeError)` becomes `contextlib.suppress(...)` -- 3.10-safe, idiomatic (SIM105), and not something the py314 formatter rewrites into the parenthesis-free PEP 758 form. - merge_summary.py and coverage_diff.py go back to PEP 695 `type` aliases and lint at the repo's py314 default. Drop tools/ruff.toml and the PERF203 ignore (a no-op once try/except is zero-cost, which is where these two now lint). Verified: ruff/mypy/ty/prek pass; stdlib_introspect compiles and runs on 3.10, while the other two use modern-only syntax and run on 3.14. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rh5G5LSDPMWLgX3cYLWUnk
There was a problem hiding this comment.
Pull request overview
This PR modernizes the tools/ scripts (types, pathlib, small refactors), removes from __future__ import annotations, and updates the lint workflow/nox session so CI type-checks the directories that actually exist. It also adds sphobjinv as a dependency to satisfy type-checking/runtime needs for coverage_diff.py.
Changes:
- Fix lint CI failures by updating mypy targets (workflow + nox) and adjusting tool config/deps (notably
sphobjinv). - Modernize
tools/stdlib_introspect.py,tools/merge_summary.py, andtools/coverage_diff.pywith fuller typing,pathlib, and other cleanup. - Update lockfile to reflect the new dependency set.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Adds sphobjinv and its transitive dependencies to the lock. |
tools/stdlib_introspect.py |
Removes future import; adds typing/pathlib refactors while keeping 3.10 compatibility. |
tools/merge_summary.py |
Modernizes aggregation/typing and uses pathlib/pairwise. |
tools/coverage_diff.py |
Modernizes typing/pathlib; adjusts HTTP handling and inventory loading. |
pyproject.toml |
Declares sphobjinv dependency; refines ruff ignores; removes mypy plugin and adds overrides. |
noxfile.py |
Updates mypy invocation to check tools/ and noxfile.py. |
.github/workflows/python-ci.yaml |
Updates mypy invocation to check tools/ and noxfile.py. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- CodeQL (implicit-string-concatenation-in-list): the line-wrapped prose strings in the report() blocks are now extracted to named locals (no_cells, deltas_intro, core_breakdown), matching the no_versions / intro style already used elsewhere. No behavior change; clears the alert and the missing-comma ambiguity. - Copilot (coverage_diff.http_get): guard `attempts < 1` with a ValueError so a bad argument no longer falls through to the end-of-function AssertionError, which is now genuinely unreachable. ruff/mypy/ty pass; merge_summary and coverage_diff still run end-to-end. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rh5G5LSDPMWLgX3cYLWUnk
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
Gets the
Python lint and testworkflow green, removesfrom __future__ import annotations, and gives the threetools/scripts a modernization pass — while keepingstdlib_introspect.pyrunnable on the 3.10–3.15 introspect matrix.Fixing the lint CI
The lint job was failing for several reasons:
src/ packages/ tests/) — repointed at the real code,tools/+noxfile.py(in the workflow and the noxfile).pydantic.mypyplugin that isn't a dependency → removed.coverage_diff.pyimportssphobjinv, unresolved for the type checkers → declared it as a project dependency (souv syncresolves it), told mypy it ships nopy.typed, and silenced ty's false positive on its attrs-generated constructor.select = ["ALL"]+ unannotated code produced 243 ruff errors → fixed the code and curated a small, justifiedignore/per-file-ignoreslist (formatter conflicts, the TC family which assumes stringized annotations, and per-file allowances for CLIprint/ boolean-trap / arg-count / broad-except / url-open).Modernization
from __future__ import annotationsfrom all three tools.typealiases for the record / version-key shapes.pathliboveros.path/glob/open;itertools.pairwiseoverzip(x, x[1:]); a dict comprehension for the union build;contextlib.suppressovertry/except/pass.sys.stdlib_module_namesguard and an unused parameter.Python-version scoping
stdlib_introspect.pyruns across thestdlib-introspectmatrix (Python 3.10–3.15), whilemerge_summary.pyandcoverage_diff.pyrun on the aggregate/coverage jobs'"3.x". So:stdlib_introspect.pystays 3.10-compatible:TypeAlias(with a per-fileUP040ignore) andcontextlib.suppressinstead of aexcept (A, B)tuple that the py314 formatter would rewrite into the 3.14-only PEP 758 form.merge_summary.py/coverage_diff.pyuse modern-only syntax and lint at the repo's 3.14 default.requires-python = ">=3.14"is the dev/tooling floor; only this one script carries the older runtime floor.Verification
--strict, ty, and prek all pass on 3.14.stdlib_introspect.pycompiles and runs on Python 3.10 (17,129 records);merge_summary.pyandcoverage_diff.pyrun on 3.14.3.13→3.14deltas) → coverage diff (gap computed against livedocs.python.orginventories).🤖 Generated with Claude Code
https://claude.ai/code/session_01Rh5G5LSDPMWLgX3cYLWUnk
Generated by Claude Code