Make mypy run again, fix what it found, and add one check script
a7fb56cpinned mypy to Python 3.11 for the Pi. In a dev venv that also has the analysis extra, numpy's stubs use 3.12 syntax, so mypy aborted on them before checking a single file - and from the next day on four real errors went in unnoticed (ebab03b,0ef5a04,9fd106b). Skip following numpy/librosa instead; only librosa_analyzer.py touches them. Fix the four errors (variables reused with a narrower type). There is no CI, so scripts/check.sh is the gate: pytest, ruff, mypy, vitest, tsc and eslint in one command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -106,6 +106,8 @@ ruff check .
|
||||
mypy # --strict, configured in pyproject.toml
|
||||
```
|
||||
|
||||
`../scripts/check.sh` runs these three plus the web front-end's checks in one go.
|
||||
|
||||
`tests/test_wire.py` parses `../esp-firmware/src/Messages.h` and fails if the Python
|
||||
message ids drift from the firmware's - the contract is hand-duplicated in two
|
||||
languages, and it had already drifted once (`BUTTON_EVENT` was missing on the Python
|
||||
|
||||
@@ -343,12 +343,12 @@ def shrink_cover(
|
||||
for a browser to decode.
|
||||
"""
|
||||
try:
|
||||
with Image.open(io.BytesIO(data)) as image:
|
||||
if max(image.size) <= max_px:
|
||||
with Image.open(io.BytesIO(data)) as source:
|
||||
if max(source.size) <= max_px:
|
||||
return data
|
||||
# JPEG can decode straight to 1/2, 1/4 or 1/8 size; a no-op for other formats.
|
||||
image.draft("RGB", (max_px, max_px))
|
||||
image = image.convert("RGB")
|
||||
source.draft("RGB", (max_px, max_px))
|
||||
image = source.convert("RGB")
|
||||
# `thumbnail` keeps the aspect ratio and never scales up.
|
||||
image.thumbnail((max_px, max_px), Image.Resampling.LANCZOS)
|
||||
buffer = io.BytesIO()
|
||||
|
||||
@@ -135,9 +135,9 @@ def _cover_for(
|
||||
return cache.store_cover(identifier, art), art
|
||||
for path in paths[:3]:
|
||||
# Podcast feeds sometimes art only some episodes; a couple of tries is enough.
|
||||
art = _embedded_art(path)
|
||||
if art is not None:
|
||||
return cache.store_cover(identifier, art), art
|
||||
embedded = _embedded_art(path)
|
||||
if embedded is not None:
|
||||
return cache.store_cover(identifier, embedded), embedded
|
||||
return None, None
|
||||
|
||||
|
||||
@@ -155,9 +155,9 @@ def _cover_for_episode(
|
||||
if candidate.is_file():
|
||||
art = candidate.read_bytes()
|
||||
return cache.store_cover(identifier, art), art
|
||||
art = _embedded_art(path)
|
||||
if art is not None:
|
||||
return cache.store_cover(identifier, art), art
|
||||
embedded = _embedded_art(path)
|
||||
if embedded is not None:
|
||||
return cache.store_cover(identifier, embedded), embedded
|
||||
for name in _COVER_NAMES:
|
||||
candidate = folder / name
|
||||
if candidate.is_file():
|
||||
|
||||
@@ -77,3 +77,12 @@ warn_unreachable = true
|
||||
# checkout must still type-check clean, so it needs the same treatment as librosa.
|
||||
module = ["vlc", "serial_asyncio", "ruamel.*", "librosa.*", "numpy", "feedparser"]
|
||||
ignore_missing_imports = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
# Recent numpy ships stubs written in 3.12+ syntax (`type X = ...`). Checking against
|
||||
# the device's 3.11 makes mypy refuse to parse them and abort before checking anything
|
||||
# at all - which is what happened in a dev venv that has the analysis extra. Treat the
|
||||
# analysis stack as untyped instead: it is only touched by librosa_analyzer.py.
|
||||
module = ["numpy", "numpy.*", "librosa", "librosa.*"]
|
||||
follow_imports = "skip"
|
||||
follow_imports_for_stubs = true
|
||||
|
||||
Reference in New Issue
Block a user