Skip to content

ci: extend mypy to openfusion/cli.py, fix the type errors it finds - #147

Open
shrdgn wants to merge 1 commit into
mainfrom
claude/mypy-cli-scope
Open

ci: extend mypy to openfusion/cli.py, fix the type errors it finds#147
shrdgn wants to merge 1 commit into
mainfrom
claude/mypy-cli-scope

Conversation

@shrdgn

@shrdgn shrdgn commented Aug 16, 2026

Copy link
Copy Markdown
Owner

What & why

openfusion/cli.py — the CLI/REPL entrypoint, and at 510+ lines the largest hand-written
module in openfusion/ — was the only module in the package excluded from mypy, in both
pyproject.toml's [tool.mypy] (exclude = ["openfusion/cli\\.py"]) and the CI workflow's
own --exclude openfusion/cli.py flag. Running mypy on it directly (as CI never does)
immediately surfaces two real issues, both in _chat_turn's Rich-rendering branch:

cli.py:238: error: Name "content" already defined on line 218  [no-redef]
cli.py:239: error: "object" has no attribute "status"  [attr-defined]
cli.py:254/257/266: error: "object" has no attribute "print"  [attr-defined]
  1. console: object | None = None (the function's third param) is typed as bare object
    instead of rich.console.Console | None, which defeats attribute checking on every
    console.status(...)/console.print(...) call in the branch that uses it. A real typo in
    one of those calls (e.g. a renamed Rich API) would go uncaught by mypy and only surface when
    someone actually ran openfusion chat interactively.
  2. A content variable is assigned in the plain-text branch (content, _ = majority_vote(panel)
    at what's now line 219) and then re-declared with an explicit str | None annotation in the
    Rich-rendering branch below it (line 238) — a redefinition-with-conflicting-type mypy flags
    even though the two branches are mutually exclusive at runtime (the first branch always
    returns before the second is reached).

Fix

  • Added a TYPE_CHECKING-only from rich.console import Console import and typed the param
    as Console | None. rich is already a hard (non-optional) dependency
    (pyproject.toml's dependencies), and the file already does from __future__ import annotations, so this adds zero runtime import cost — the existing lazy from rich.console import Console inside run_chat (kept for CLI startup latency on non-chat subcommands) is
    untouched.
  • Renamed the Rich-rendering branch's content to answer to remove the redefinition.
  • Removed the cli.py exclude from both pyproject.toml and .github/workflows/ci.yml's
    mypy step.

Not touched: [tool.coverage.run]'s separate omit = [..., "openfusion/cli.py"] — that's
about pytest --cov, not mypy, and its own comment explains a different, still-valid
rationale (TTY/stdin mocking noise) unrelated to this change.

How it was tested

  • ruff check . passes
  • pytest -q passes (490 passed, no live network — no new tests needed, this is a
    type-only change with no runtime behavior difference)
  • mypy openfusion/ --ignore-missing-imports --disable-error-code import-untyped (the
    exact CI invocation, now scope-widened) — Success: no issues found in 25 source files
  • Docs updated — not needed, no config/request-surface/defaults changed
  • No secrets, prompts, or response bodies added to logs or metrics
  • Bench number — not applicable, no model-call behavior changed

Notes for reviewers

Found via an automated repo-review scheduled task; verified by hand by running mypy against
cli.py directly (bypassing the exclude) and confirming it was the only module in
openfusion/ carrying one, in both places it's configured.


Generated by Claude Code

cli.py was the only module in openfusion/ excluded from mypy (both
pyproject.toml and the CI workflow). Running it directly surfaced two real
issues: _chat_turn's console: object | None param defeated attribute
checking on every console.print/console.status call in its Rich-rendering
branch, and a content variable was redefined with a conflicting type
across that branch and the plain-text branch. Typed console as
Console | None via a TYPE_CHECKING-only import (rich's runtime import
stays lazy) and renamed the second content to answer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfTJhjkqkDfTMzufuBcLtQ
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