Skip to content

Adopt the fleet Python lint/type config for the hub's utility scripts - #388

Merged
ptr727 merged 6 commits into
developfrom
python-lint-config
Jul 22, 2026
Merged

Adopt the fleet Python lint/type config for the hub's utility scripts#388
ptr727 merged 6 commits into
developfrom
python-lint-config

Conversation

@ptr727

@ptr727 ptr727 commented Jul 22, 2026

Copy link
Copy Markdown
Owner

The hub's stdlib-only utility scripts (spec/, host-setup/) had no ruff or type-checker config, so Pylance ran in a strict default and flagged unknown types on JSON-loaded data (entry: Unknown, etc.). This adopts the fleet's Python style.

Changes

  • pyproject.toml (new, config-only — the "uvx scripts" profile: no [project], no uv.lock): [tool.ruff] (py313, line-length 100, isort) + [tool.pyright] (standard mode, include spec + host-setup). Mirrors finmod.
  • spec/audit.py: annotate gh() -> Any (it returns parsed JSON, which is Any) — this clears every gh-result Optional access at once; annotate the _HISTORY_CACHE dict; narrow item (dict | None) in the interface/verbatim dispatch branches, which only run when item is non-None.

Why standard mode

finmod uses typeCheckingMode = "standard", which does not report unknown types — so the Pylance noise vanishes with the config, no hand-annotating JSON data. The genuine "possibly None" errors (3 after the config) are fixed above.

Verification

uvx ruff check and uvx pyright are both clean (0 errors). spec/audit.py --selftest and spec/validate.py are unchanged — the annotations carry no behavior.

Note: line-length = 100 drives the ruff formatter only; E501 is not in ruff's select, so the scripts' intentionally-long finding strings are not reflowed.

🤖 Generated with Claude Code

The hub's stdlib-only utility scripts (spec/, host-setup/) had no ruff or
type-checker config, so Pylance ran in a strict default and flagged unknown types
on JSON-loaded data. Add a config-only pyproject.toml mirroring the fleet's
Python style - ruff (py313, line-length 100, isort) and pyright standard mode -
the "uvx scripts" profile (no [project], no uv.lock).

Under standard mode the unknown-type noise is gone; the real errors that remain
are three genuine "possibly None" accesses, fixed minimally:
- annotate gh() -> Any (it returns parsed JSON, which is Any) - clears every
  gh-result Optional access at once;
- annotate the _HISTORY_CACHE dict;
- narrow `item` (dict | None) in the interface/verbatim dispatch branches, which
  only run when item is non-None.

ruff and pyright are both clean; audit --selftest and validate.py are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 14:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This pull request adopts the fleet-wide Python lint and type-check configuration for the hub's stdlib-only utility scripts and adjusts spec/audit.py annotations to reduce type-checker noise around JSON-shaped data.

Changes:

  • Add a config-only pyproject.toml with Ruff (py313 + import sorting) and Pyright (standard mode) settings scoped to spec/ and host-setup/.
  • Update spec/audit.py typing (notably gh() -> Any and additional narrowing) to align with the new type-checking baseline.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
spec/audit.py Adds/adjusts type annotations to reduce Pyright findings and narrow Optional paths.
pyproject.toml Introduces Ruff and Pyright configuration for hub utility-script linting/type checking.

Comment thread spec/audit.py
Comment thread spec/audit.py Outdated
…#388)

- gh() also returns None on an empty response body, not only a 404; say so.
- Type _HISTORY_CACHE as dict[str, list[str]] (rel_path -> past revision
  contents) instead of a bare dict.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 14:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

spec/audit.py:64

  • The gh() implementation can return None (404 when ok404, or an empty response body), so the return annotation should include None. Using -> Any makes the type hint contradict both the docstring and the actual return value, and it can hide real None-handling bugs at call sites.
def gh(path, ok404=False) -> Any:
    """GET a REST path via gh, returning parsed JSON, or None on a 404 (when ok404) or an empty response body.

Comment thread spec/audit.py Outdated
Comment thread pyproject.toml Outdated
#388)

Per the Scripts-profile decision (mypy is the CODESTYLE-mandated type checker;
pyright/pylance is editor-only):

- pyproject.toml: add [tool.mypy] (the gate, clean) alongside [tool.pyright]
  standard (tames Pylance) and [tool.ruff]. Config only, the Scripts profile.
- CODESTYLE.md Scripts profile: state that the pyproject may carry a [tool.pyright]
  editor block (the same mypy-gate/pyright-editor split the Project profile uses).
- CODESTYLE.md: correct the tool-pinning guidance. A uvx <tool>@<ver> pin in a
  run: step is not Dependabot-trackable, so CI runs uvx ruff@latest / mypy@latest
  per the fleet rule (pin only what Dependabot auto-updates, else run latest, never
  a manual pin that goes stale). Also recast two clause-joining semicolons in the
  edited bullet.
- audit.py: reword the _HISTORY_CACHE comment for grammar (Copilot).

ruff, mypy, and pyright are all clean; audit --selftest unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 15:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread spec/audit.py
The interface/verbatim dispatch guarded with `if item and ...`, relying on dict
truthiness. Use an explicit `is not None` - it is what narrows item for the type
checker and reads as intent, not an empty-dict edge case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 15:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

spec/audit.py:64

  • gh() can return None (404/empty body), but the return annotation is Any. That prevents pyright/mypy from helping catch accidental None dereferences at new call sites and makes the signature less self-documenting than the docstring. Consider annotating the real return type (Any | None) and using an explicit cast/assert at the specific call sites where you intentionally treat the JSON as unchecked.
def gh(path, ok404=False) -> Any:
    """GET a REST path via gh, returning parsed JSON, or None on a 404 (when ok404) or an empty response body.

Comment thread CODESTYLE.md
CODESTYLE now says CI runs uvx ruff@latest / mypy@latest (a uvx run-step pin is
not Dependabot-trackable), but spec/project-types.json python.scripts.uvx still
asserted "CI pins exact tool versions". The spec audits downstream repos, so
update the assertion to match the latest-not-pinned rule.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 15:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread pyproject.toml Outdated
AGENTS.md bans file-header summary comment blocks. Replace the three-line summary
with a single terse note for the one non-obvious point - why there is no
[project] (the Scripts profile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 15:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 09ce86c into develop Jul 22, 2026
7 checks passed
@ptr727
ptr727 deleted the python-lint-config branch July 22, 2026 15:28
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.

2 participants