You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reported by Codex on #19. The mypy job added with the typed coordinator
passed on its first run, which should have been the tell: Home Assistant
was not installed for it and ignore_missing_imports was on, so every
homeassistant.* import resolved to Any. WineCellarData derives from
DataUpdateCoordinator, a class deriving from Any inherits Any for every
member it does not declare, and coordinator.data was therefore Any at all
five sensors, both views and the diagnostics - the exact call sites
DataUpdateCoordinator[CellarData] was introduced to type.
Confirmed before fixing: reveal_type(coordinator.data) reported Any, and
coordinator.data["definitely_not_a_key"] was accepted in silence. The job
reported success over code it had never checked, which is worse than no job
at all, because the PR claimed those errors were now impossible.
Resolving Home Assistant's real types found four genuine bugs the Any gate
had accepted: the four entity classes derived from a bare CoordinatorEntity,
so their coordinator was DataUpdateCoordinator[dict[str, Any]] and
CellarLastSyncSensor read a last_success that type does not have.
* requirements_mypy.txt installs a pinned Home Assistant for the job;
the test matrix keeps its light stub harness and its seconds-long run.
* No ignore_missing_imports. disallow_any_unimported and warn_return_any
make an unresolved import fail rather than degrade - without Home
Assistant the job now reports 84 errors instead of success.
* stubs/cellartracker for the one dependency that ships no py.typed:
RateLimited derives from its CannotConnect, so an Any base there is the
same hole one dependency further down.
* tests/typing_gate.py asserts what the gate is supposed to guarantee in
the checker's own terms - assert_type fails on Any, and the
misspelled-key checks are type: ignore comments that warn_unused_ignores
turns into errors if they ever stop being necessary.
* tests/test_mypy_gate.py pins the wiring from pytest's side.
Every reader of the payload is now typed rather than Any, which cost the
four CoordinatorEntity[WineCellarData] parameterisations, a Literal key on
the drink-window counters, and one honest redeclaration: Home Assistant
types data as the payload and then assigns None to it before the first
refresh, so the F-15 guards read as dead code until the coordinator says so.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LLPEGFSy3fLEuXNUPAPWR4
0 commit comments