Gradually introduce mypy type checking (Phases 1-3)#48
Merged
pskeshu merged 8 commits intoJun 15, 2026
Conversation
…t#46) Adds a lenient [tool.mypy] config with an explicit ignore_errors override list for the 113 modules that don't yet pass, runs mypy in the lint CI job and as a pre-commit hook, and adds mypy to the dev dependency group. New code is held to the standard; the override list shrinks as modules are cleaned up. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Annotates two implicit-Optional defaults and fixes a str/Path arg-type mismatch in create_timelapse_video. Removes the file from the mypy override list before it's even added. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Changes def f(x: T = None) to def f(x: T | None = None) to match PEP 484 / mypy's no_implicit_optional, matching the pattern already applied to bridge.py in gently-project#42. Removes 14 modules from the mypy ignore_errors override list (113 -> 99) that are now fully clean.
…errors The four ContextStore mixins (_intentions, _plans, _understanding, _ml_pipelines) call methods/attributes defined on the host class or sibling mixins (_conn, _tx, _now, _gen_id, get_plan_items, create_campaign, etc.), which mypy couldn't see on the mixins themselves. Add gently/harness/memory/_protocols.py declaring a StoreProtocol with these members and have each mixin inherit from it for typing only. Also fixes the remaining errors this didn't cover: two untyped dict literals in _plans.py needed explicit dict[str, Any] annotations, and three _ml_pipelines.py methods returning an Optional lookup right after an insert now assert the row exists. All four mixins are now mypy-clean; removes them from the ignore_errors override list (99 -> 95).
…y overrides Adds ctx_get(context, key) and retypes the require_* helpers in harness/tools/helpers.py to accept context: dict | None and return non-Optional success values, eliminating the dominant union-attr/arg-type pattern across the tool modules. Applies the same fix to memory_tools' local _get_memory and a handful of independent var-annotated/type issues. Removes all 16 gently.app.tools.* modules from the mypy override list (95 -> 79), cutting the underlying error count from 610 to 369. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 tasks
…ent crash and remaining type gaps - volume_tools.view_image: guard against a disconnected microscope client via require_microscope() instead of crashing on client.capture_bottom_image() - file_store/store register_volume: volume_data: np.ndarray = None -> np.ndarray | None = None (implicit-Optional missed in the earlier pass) - StoreProtocol: mark @runtime_checkable for consistency with gently.harness.protocols - TimelapseOrchestrator.start: embryo_ids: list[str] -> list[str] | None = None to match its actual None-handling and the docstring Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…onal CI installed mypy unpinned (`pip install mypy`) while the pre-commit hook pinned mirrors-mypy v2.1.0, so the two would diverge the moment a newer mypy released — "passes my pre-commit" would stop implying "passes CI". Pin all three sources to 2.1.0 (CI install, pyproject dev group, and the pre-commit rev) and cross-reference them so they move together. Also convert the one implicit-Optional missed in Phase 1: `view_image`'s `image: np.ndarray = None` in dispim/client.py (the other three params in that same signature were already converted). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6 tasks
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
Implements the incremental mypy-typing plan from #46: a lenient
[tool.mypy]config plus an explicit
[[tool.mypy.overrides]]ignore-list for currentlyfailing modules, wired into CI and pre-commit (#42's mypy scope), and then
progressively shrinking that list:
CONTRIBUTING.md(per Gradually introduce mypy type checking #46's task list).def f(x: str = None))across 45 modules, plus
gently/harness/bridge.py.StoreProtocolfor theContextStorememory mixins andfix the remaining errors it surfaced.
contextdict — newctx_get()helper plus retyped
require_agent/require_microscope/etc. ingently/harness/tools/helpers.py— clearing all 16gently.app.tools.*modules.
Results
mypy .passes cleanly against the remaining override list (300 source files)Test plan
.venv/bin/mypy .— success, no issues found in 300 source files.venv/bin/ruff check .— all checks passed.venv/bin/ruff format --check .— 300 files already formatted.venv/bin/pre-commit run --all-files— all hooks passProgress on #46 — 79 modules / 369 errors remain, scoped as a follow-up phase
in a separate issue.
🤖 Generated with Claude Code