mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 22:35:08 +00:00
ci: mypy ratchet -- keep type-clean modules clean (71 modules, 536 -> 442 errors) (#661)
* ci: mypy ratchet -- keep type-clean modules clean mypy-clean.txt lists the 71 modules under src/ that type-check clean; scripts/check_types.py runs mypy (--follow-imports=silent) on exactly those files and fails on any error or a missing/unsorted/duplicate entry. A new "Type check (mypy ratchet)" CI job runs it with mypy 1.20.2 and pinned stubs; the manual pre-commit mypy hook now runs the same script (a local hook, so mypy sees the installed requirements like CI does). 35 modules were made clean with annotation-only fixes: hints, typing.cast, TYPE_CHECKING imports, implicit-Optional defaults made explicit, and annotations widened (never guards removed) where mypy called a defensive isinstance check unreachable. No runtime behaviour change. mypy.ini: numpy and orjson are treated as Any (follow_imports=skip, also for stubs). numpy 2.3+ stubs use 3.12 `type` statements that mypy won't parse at python_version 3.10, and orjson is optional, so seeing its stubs made the result depend on whether it was installed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: annotate check_types.py's list-form mypy subprocess Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -49,7 +49,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass, replace
|
||||
from typing import Any, Dict, Optional
|
||||
from typing import Any, Dict, List, Optional, cast
|
||||
|
||||
from src.matrix_support import DEFAULT_REFRESH_LIMIT_HZ
|
||||
|
||||
@@ -132,14 +132,14 @@ def crisp_ladder(
|
||||
refresh_hz: float = DEFAULT_REFRESH_HZ,
|
||||
max_frame_hold: int = MAX_FRAME_HOLD,
|
||||
max_pixels_per_frame: int = MAX_PIXELS_PER_FRAME,
|
||||
):
|
||||
) -> List[CrispSpeed]:
|
||||
"""Every whole-pixel speed this panel can show, slowest first.
|
||||
|
||||
Duplicates are collapsed keeping the gentlest option: 100 px/s is reachable
|
||||
as 1px every refresh or 2px every 2nd refresh, and the former moves in
|
||||
smaller increments, so that is the one worth offering.
|
||||
"""
|
||||
best = {}
|
||||
best: Dict[float, CrispSpeed] = {}
|
||||
for hold in range(1, max_frame_hold + 1):
|
||||
for ppf in range(1, max_pixels_per_frame + 1):
|
||||
pps = refresh_hz / hold * ppf
|
||||
@@ -434,7 +434,8 @@ def configure(
|
||||
# they start scrolling. configure() only reports what is needed.
|
||||
|
||||
if choice:
|
||||
requested = settings.requested_pixels_per_second
|
||||
# Set whenever there is a crisp choice (see the replace() above).
|
||||
requested = cast(float, settings.requested_pixels_per_second)
|
||||
if abs(requested - applied) > 0.05:
|
||||
log.info(
|
||||
"Scroll configured: %s (asked for %.1f px/s from %s; "
|
||||
|
||||
Reference in New Issue
Block a user