Follow-up to #42.
Issue #42 set up ruff (lint + format) with pre-commit and CI, but mypy was dropped from that issue's scope due to the size of the gap between the codebase and a clean mypy run.
Current state
With a starting config of:
[tool.mypy]
python_version = "3.10"
disallow_untyped_defs = true
ignore_missing_imports = true
explicit_package_bases = true
mypy_path = "."
mypy . reports 3002 errors across 225 of 299 source files. Breakdown by error code:
| Code |
Count |
Notes |
no-untyped-def |
1928 |
missing type annotations — dominant category |
assignment |
401 |
often implicit-Optional defaults (def f(x: str = None)) |
union-attr |
267 |
.attr access on X | None |
attr-defined |
238 |
some may be real bugs worth investigating |
var-annotated |
48 |
|
arg-type |
40 |
|
return-value |
28 |
|
index, operator, misc, dict-item, etc. |
~36 |
|
Note: explicit_package_bases = true + mypy_path = "." is required to resolve scripts/projection_explorer.py (imported as both scripts.projection_explorer and projection_explorer — no __init__.py in scripts/).
Proposed approach: incremental adoption
Fixing ~3000 errors in one pass isn't practical. Instead:
- Add the
[tool.mypy] config above, but without disallow_untyped_defs initially (cuts ~1928 errors).
- Add
[[tool.mypy.overrides]] blocks with ignore_errors = true for the modules/packages that still fail, enumerated explicitly (e.g. gently.harness.bridge, benchmarks.*, etc.) — captured as a checklist below.
- Wire
mypy . into CI (.github/workflows/lint.yml) and the mypy pre-commit hook — it passes immediately because failing modules are excluded.
- New modules and PRs touching excluded modules are expected to clean up that module's overrides entry and remove it from the ignore list as part of the change.
- Periodically (or via follow-up issues per subsystem), pick off modules from the ignore list —
gently/harness/bridge.py alone accounts for ~25 errors and is a good first target given it's a single large file.
Tasks
Acceptance Criteria
mypy . passes in CI and pre-commit (via the override list)
- The policy for adding new code / shrinking the ignore list is documented in
CONTRIBUTING.md
Follow-up to #42.
Issue #42 set up
ruff(lint + format) with pre-commit and CI, but mypy was dropped from that issue's scope due to the size of the gap between the codebase and a clean mypy run.Current state
With a starting config of:
mypy .reports 3002 errors across 225 of 299 source files. Breakdown by error code:no-untyped-defassignmentdef f(x: str = None))union-attr.attraccess onX | Noneattr-definedvar-annotatedarg-typereturn-valueindex,operator,misc,dict-item, etc.Note:
explicit_package_bases = true+mypy_path = "."is required to resolvescripts/projection_explorer.py(imported as bothscripts.projection_explorerandprojection_explorer— no__init__.pyinscripts/).Proposed approach: incremental adoption
Fixing ~3000 errors in one pass isn't practical. Instead:
[tool.mypy]config above, but withoutdisallow_untyped_defsinitially (cuts ~1928 errors).[[tool.mypy.overrides]]blocks withignore_errors = truefor the modules/packages that still fail, enumerated explicitly (e.g.gently.harness.bridge,benchmarks.*, etc.) — captured as a checklist below.mypy .into CI (.github/workflows/lint.yml) and themypypre-commit hook — it passes immediately because failing modules are excluded.gently/harness/bridge.pyalone accounts for ~25 errors and is a good first target given it's a single large file.Tasks
[tool.mypy]config (dropdisallow_untyped_defs, keepignore_missing_imports,explicit_package_bases,mypy_path)[[tool.mypy.overrides]]withignore_errors = truemypyto.pre-commit-config.yamland.github/workflows/lint.ymlmypyto thedevdependency group inpyproject.tomlCONTRIBUTING.mdto document the incremental-typing policygently/harness/bridge.py(~25 errors, mostly implicit-Optional and missing return types) as a first incremental cleanupAcceptance Criteria
mypy .passes in CI and pre-commit (via the override list)CONTRIBUTING.md