chore(mypy): make the type check clean and a hard gate#28
Merged
Conversation
chore(mypy): make the type check clean and a hard gate Fixed all 43 pre-existing mypy errors and promoted mypy to a required status check (added to the Code Quality Checks job; removed the advisory copy from the test job). src/ now type-checks clean against py3.10. Highlights (no runtime behaviour change): - models.py: type ScoringContext.audio_data/cache via TYPE_CHECKING forward refs (np.ndarray / AudioCache) instead of `object`, keeping numpy out of the runtime import graph. - implicit Optional fixes: spectrum/calculator/silence params, console globals in main.py & logging_config.py. - annotate accumulator lists (`reasons: list[str]`) and dicts (`details`/`stats: Dict[str, Any]`). - cast Any-returning soundfile/scipy calls (file_cache, silence_utils, cassette) to their declared types. - audio_cache: correct _spectrum/_segments element types (sample rate is int, not ndarray), guard sr-None, assert non-None after the double-checked-lock build. - audio_loader: load_audio_with_retry returns np.ndarray (not NDArray[float64]) so the float32 partial-load path type-checks. - quality.py: `# type: ignore[override]` on the detector registry's intentionally-specialised detect() signatures. - delete src/flac_detective/reporter.py: dead compat shim importing a removed symbol (ExcelReporter no longer exists); referenced nowhere. flake8 = 0, black & isort clean, mypy clean, pytest 139 passed / 8 skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
refactor(quality): uniform detect(**kwargs) signature (Liskov-clean) The QualityDetector subclasses overrode detect() with extra required positional params (filepath / reported_depth / cutoff_freq+samplerate), which both mypy AND CodeQL flagged as a signature-mismatch / Liskov violation. The previous commit silenced mypy with `# type: ignore[override]`, but that was a suppression — CodeQL still (correctly) reported it. Real fix: every detector now matches the base `detect(self, **kwargs)` exactly and pulls its inputs from kwargs at the top of the method. All call sites already pass these by keyword (registry dispatch), so behaviour is unchanged. Removed all 6 `# type: ignore[override]`. mypy clean, flake8 = 0, black & isort clean, pytest 139 passed / 8 skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
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.
@
What & why
Follows up the flake8 gate (#27): mypy was running but advisory because
src/carried 43 pre-existing type errors. This PR fixes all of them andpromotes mypy to a required check (added to
Code Quality Checks, thegating job; removed the advisory copy from
test).No runtime behaviour changes — these are annotations, Optional fixes, casts,
and narrowing asserts.
Key changes
ScoringContext.audio_data/cachetyped viaTYPE_CHECKINGforward refs (np.ndarray/AudioCache) instead ofobject, so the real types flow without importing numpy at runtime.spectrum/calculator/silenceparams and theconsoleglobals inmain.py&logging_config.py.reasons: list[str],details/stats: Dict[str, Any].file_cache,silence_utils,cassetteto their declared return types._spectrum/_segmentselement types (thethird tuple element is the sample-rate
int, not an ndarray),sr-Noneguards, and
assert ... is not Noneafter the double-checked-lock build.load_audio_with_retryreturnsnp.ndarray(notNDArray[float64]) so the float32 partial-load path type-checks.# type: ignore[override]on the detector registry'sintentionally-specialised
detect()signatures.src/flac_detective/reporter.py— dead compatibility shim thatimported a removed symbol (
ExcelReporter); referenced nowhere, would haveraised
ImportErrorif anyone tried to use it.Verification (local)
mypy src→ Success: no issues found in 49 source filesflake8 src tests→ 0 ·black --check✅ ·isort --check-only✅pytest(CI selection) → 139 passed, 8 skipped🤖 Generated with Claude Code
@