Skip to content

Address/cleanup pyright type issues throughout the codebase #137

@speediedan

Description

@speediedan

One-line plan

Iteratively enable and fix pyright type errors file-by-file: run pyright on a small set, fix non-invasive typing issues (annotations, stubs, TypedDicts, small signature tweaks), commit often, skip hard files with a TODO + # type: ignore comment, and expand the pyright scope until the target coverage of files with zero pyright errors grows.

Checklist (requirements extracted)

  • Add/adjust pyright type checking problems across the codebase. — Planned
  • Add missing annotations throughout the codebase (prefer non-invasive type-only changes). — Planned
  • Parcel the work into pieces (incremental PRs). — Planned
  • Allow skipping files that are too hard to fix now; proceed elsewhere. — Planned
  • Iteratively expand number of files under type checking (currently only lightning.py). — Planned
  • Avoid substantial code refactors; if required, note them and continue elsewhere. — Planned
  • Increase number of files covered with no pyright errors over time. — Planned

Tiny contract (what success looks like)

  • Inputs: existing repo checked out, virtualenv used for dev (e.g., it_latest), pyright installed and runnable, pre-commit hooks available.
  • Outputs per PR: a small set of files (3–10) with pyright errors fixed; CI still green (lint/pytest where applicable); PR links to Address/cleanup pyright type issues throughout the codebase #137 and shows which files gained zero-error status.
  • Error modes: if a file needs structural refactor to type clean, skip and add a clear TODO and # type: ignore to unblock progress.

Edge cases to watch

  • Files that import optional heavy ML packages (transformers, torch) — pyright can choke on runtime-only imports. Use forward references, TYPE_CHECKING guards, or stub types.
  • Circular imports revealed by adding type hints — prefer string annotations or move types to types.py/_types.py.
  • Large union/Any churn — use narrow incremental types, not full rework.
  • We can ignore all files under tests directory for now, we want to initially focus on the source code itself
  • Tests or CI that require heavy ML installs — don't run full test suite unless environment prepared; use pyright and fast unit tests only.

Prioritized incremental workflow

  1. Setup (once)
    • Ensure pyright CLI is available (repo already uses it in docs; use pyright).
  2. Baseline: run pyright only on the current checked file(s)
    • Command (run in repo root, sanity check this by inspecting environment setup used in our ci_test-full.yml or copilot-instructions.md or build_it_env.sh if you run into issues):
      pyright src/interpretune/adapters/lightning.py --outputjson > /tmp/pyright_lightning.json
    • Save the error list to the PR description or branch notes.
  3. Pick a small batch of files (3–8) — prefer modules with few dependencies: utils, config/, base/components/cli.py, adapters/transformer_lens.py (example).
  4. For each file in the batch:
    • Run pyright for exactly that file to get errors.
    • Fix errors that are annotations-only:
      • Add missing parameter/return annotations.
      • Add from __future__ import annotations where helpful.
      • Replace -> Any with a narrower type if obvious, else keep Any but add # TODO: refine.
      • Use if TYPE_CHECKING: imports for typing-only imports to avoid heavy runtime imports.
      • Add TypedDict or Protocol for common dict-shaped objects where helpful.
      • Add # type: ignore[reportGeneralTypeIssues] on very stubborn statements, with a TODO referencing #137.
    • Avoid changing runtime behavior. If code must be altered significantly (refactor), log it and skip the file for now.
  5. Commit each small batch with message:
    • chore(types): pyright fixes for {path1, path2} — progress on #137
  6. Open a PR per batch, include:
  7. Expand pyright scope:
    • Update pyrightconfig.json incrementally to include more folders (see recommended snippet below).
    • Re-run pyright for the expanded scope; repeat fixes.

Recommended pyright config (incremental)

Add a pyrightconfig.json at repo root (or update it) to explicitly include paths and control strictness. Example snippet to start incrementally:
{
"typeCheckingMode": "basic",
"include": [
"src/interpretune/adapters/lightning.py"
],
"exclude": [
"src/interpretune//_parity/",
"tests/**",
],
"reportMissingTypeStubs": false
}

  • When ready, add more files to include in small batches or change to "typeCheckingMode": "strict" per-package only after fixes.

Quick actionable commands (copyable)

  • Activate env and run pyright on a single file:
    pyright src/interpretune/adapters/lightning.py
  • Run ruff and pre-commit:
    ruff check src/interpretune --select I,F,E,W
    pre-commit run --all-files
  • Run pytest for a small test file:
    pytest tests/core/test_some_module.py -q

How to mark skipped / hard files

  • If you cannot fix a file without large refactors, add a single-line suppression at the top of the file or beside the offending statement:
    • Add a comment with a reason and reference: # type: ignore[reportGeneralTypeIssues] # TODO(#137): needs refactor; skipping for now
    • Also add a TODO in the PR listing these files, so they’re visible to reviewers.

Small typing patterns & tips

  • Prefer string annotations and from __future__ import annotations.
  • Use if TYPE_CHECKING: for heavy imports used only for typing.
  • Add minimal local types.py or typing.py with common shared TypedDicts/Protocols to avoid repeated complex signatures.
  • Use typing.Any only as a temporary stopgap with a TODO.
  • Prefer -> None or explicit return types rather than implicit None.

PR and branch conventions

  • Branch name: types/pyright-<short-area>-<n> e.g. types/pyright-adapters-01
  • PR title: chore(types): pyright fixes for <area> — progress on #137
  • PR body should include:
    • Files changed list (3–10)
    • pyright errors before and after (counts)
    • Test/lint status (commands run and outputs)
    • A short risk note: “type-only changes; no runtime behavior modified” OR list of refactors if any.
  • Label PR: type-checking, incremental, link to issue Address/cleanup pyright type issues throughout the codebase #137.

Quality gates (per PR)

  • Local: run pyright on included files -> zero errors for those files.
  • Lint: ruff check . or pre-commit run --all-files.
  • Tests: run fast unit tests that touch changed files (if available).
  • CI: ensure GitHub Actions run passes for repo (CI will run full checks).

Recording progress and metrics

  • Maintain a small file scripts/pyright_progress.md or keep a PR comment with a table:
    • Date | PR | Files added under pyright | Files with zero errors (cumulative) | Notes
  • For each PR, include the pyright summary (json) attached or pasted.

Example minimal change pattern

  • Before: un-annotated function
    def foo(bar):
    ...
  • After (safe, minimal):
  from typing import Any
  def foo(bar: Any) -> None:
      ...

  # TODO(#137): refine `Any` for bar

When a file seems to need substantial refactor

Small utilities to add (optional low-risk PR)

  • Add src/interpretune/_types.py with shared common types (e.g., common NamedTuple/TypedDict definitions).
  • Add a pyrightconfig.json (as above) and a short CONTRIBUTING_TYPES.md with the conventions in this playbook.

Final notes & next steps for Copilot

  • START: run pyright for the current checked file(s) and capture the errors.
  • PICK: choose the first small batch (3–5 files) that appear easiest (utils, config, small adapters).
  • IMPLEMENT: make only type/annotation edits; avoid runtime changes.
  • COMMIT/PR: follow branch/PR conventions and link to Address/cleanup pyright type issues throughout the codebase #137.
  • ITERATE: expand pyrightconfig.json include list by batch.

Requirements coverage summary (mapping to checklist above)

  • Add/adjust pyright type checking problems — Planned (will be executed iteratively)
  • Add missing annotations — Planned (prefer small, non-invasive edits)
  • Parcel into pieces — Done in plan (batch approach described)
  • Skip problematic files — Done in plan (skip + TODO + type: ignore)
  • Iteratively expand pyright scope — Done in plan (pyrightconfig.json snippet + workflow)
  • Avoid substantial code changes — Enforced (guidance: skip, note, create follow-up)
  • Grow the number of files with zero pyright errors — Planned (metrics & PRs suggested)

Metadata

Metadata

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions