chore(QUAL-007): check the whole test tree with mypy [stacked on #105]#106
Conversation
Flips tests/ typing from an opt-in whitelist (QUAL-004: conftest + two policy tests) to checked-by-default: pyproject mypy `files` now lists "tests", so every NEW test file is type-checked automatically and the ~60 already-clean modules are locked. Full adoption surfaced 409 mechanical errors in 45 modules (fake clients passed where the real client class is annotated, records-dict rows, unannotated accumulators). Per the planned fallback, this PR: - fixes the 16 low-count modules (~24 errors): typed audit-recorder fakes replacing `append(...) or True` lambdas, Optional narrowing on ORM metadata/scalar reads, isinstance-first AST walk in the IPO boundary guard, deliberate-invalid enum/string inputs marked with cast (the validators they exercise are unchanged), DataFrame-typed capture slots in UI fakes, and the same np.log/Series narrowing the production component uses; - enumerates the remaining 29 dirty modules in a shrink-only ignore_errors override (~385 errors of typed-API debt, documented for incremental cleanup) - the comment forbids ever ADDING to the list. The tests/ entries are top-level module names (tests/ has no __init__.py). CI's mypy command is unchanged (config-driven). All 240 tests in the 16 touched modules pass; full suite at baseline. Stacked on QUAL-006 (needs pandas-stubs and edits the same pyproject section). Merge #105 first; GitHub retargets this PR to main when the base branch is deleted. Gates: 1,386 passed, coverage 88.13% (floor 87); mypy clean at 209 files (up from 122); pre-commit validate, compileall, ruff, bandit, pip-audit all clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DoRmAmMu1997
left a comment
There was a problem hiding this comment.
Self-review (posted as COMMENT — the bot runs as the PR author and cannot APPROVE). Verdict: Approve.
- The flip is the point — before: 3 test modules whitelisted, new test files unchecked forever unless someone remembered to add them. After: checked-by-default (209 files), with the remaining debt enumerated in a shrink-only list. The override comment explicitly forbids additions, making "new untyped test module" a reviewable config change instead of silent drift.
- Module-name gotcha caught in-flight — the first draft used
tests.test_*names, which silently matched nothing becausetests/has no__init__.py; mypy names those files as top-level modules. The committed version uses the correct bare names and the full run proves the override actually bites (409 errors → 0 reported). - Behavior-preservation of the 16 fixes — all 240 tests in the touched modules pass. The two riskiest edits were checked closely: the IPO boundary guard's isinstance-first walk visits the same Import/ImportFrom nodes (non-import nodes previously produced an empty
moduleslist, i.e. a no-op inner loop); and therole_changedmetadata None-filter removes nothing at runtime because that event always writes metadata (asserted by the same suite). - Deliberate-invalid inputs stay deliberate —
cast(IpoIssueType, "UNKNOWN")andcast(Any, "bullish")exist precisely so the coercion/rejection tests keep sending the raw values their validators must handle; comments at both sites say so. - No dependency motion — the pyproject diff is mypy config only; constraints/requirements untouched on this branch (the pins live in the #105 base).
- Stacking discipline — base is
chore/qual-006-pandas-stubs; the body's top banner spells out the merge order and GitHub's auto-retarget. This PR should merge last of the wave so test files from #98–#103 get checked on main under the new default (any stragglers are fix-forward).
Gates: mypy clean at 209 files; 1,386 passed + 1 skipped, coverage 88.13% (floor 87); ruff/bandit/pip-audit/pre-commit/compileall clean. Security review: no findings (test/config-only).
Appends the "July 2026" section to docs/architecture/audit-2026-06.md so future audits read one durable history instead of re-deriving it: - both waves indexed: #88-#97 (other session) and #98-#107 (this wave, one ticket per PR); - findings verified FALSE this round (cpr_yearly float convention, cpr_yearly test coverage, technical-agent injection posture = locked TEST-003 decision); - wave 1's considered-and-REJECTED list recorded so those ideas are not re-proposed (session-state registry, indicators decorator, sectors iterrows, DNS-rebinding on the fixed listing URLs, run_scan split); - the June deferral table updated item by item: Agent SDK dedup landed in two steps with the per-agent remainder locked by ADR; pandas-stubs estimate corrected (June "hundreds" -> actual 22); the parquet sidecar idea superseded by footer statistics with the June measure-first objection honored and the advisory-index review hardening noted. Stacked on QUAL-007 (#106) -> QUAL-006 (#105); merge those first. Gates: 1,386 passed, coverage 88.13%; ruff clean; mypy clean (209 files). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Codex review plan before fixes:
No new typing strictness or product behavior is being added. |
DoRmAmMu1997
left a comment
There was a problem hiding this comment.
Codex found two actionable QUAL-007 integration/policy issues before updating the branch.
Reconcile the whole-test-tree mypy gate with the newly merged PRs, type the affected fixtures and values without changing runtime behavior, and enforce that QUAL-007's temporary ignore-errors baseline can only shrink. Co-authored-by: Hemant <hemantdhamija@gmail.com> Co-authored-by: Codex <codex@openai.com>
|
Codex review follow-up complete for QUAL-007. What I fixed:
Verification on the final local tree:
The formal diff-scoped security review found no reportable issues. The change is limited to typing/test-policy code and introduces no runtime behavior. |
Reconcile the July audit register with the reviewed final PR heads, record the enforced QUAL-007 debt policy, and update the architecture index to describe the durable June-July register through PR #107. Co-authored-by: Hemant <hemantdhamija@gmail.com> Co-authored-by: Codex <codex@openai.com>
…-july docs(DOC-003): record the July 2026 review waves in the audit register [stacked on #106]
Ticket scope (QUAL-007 — mypy over tests/, phase 2)
Goal: finish what QUAL-004 started. The mypy
fileswhitelist covered exactly three test modules; every other test file — including any new one — was invisible to the type checker. This PR flips the default:filesnow says"tests", so the whole tree is checked and new test files are typed from day one.What full adoption surfaced: 409 mechanical errors in 45 of ~90 test modules — fake clients passed where the real client class is annotated,
to_dict("records")rows, unannotated accumulators,append(...) or Truerecorder lambdas. Per the plan's pre-agreed fallback ("if the count balloons, keep the largest-coverage whitelist and document the remainder"):In scope
pyproject.toml:filesextended to"tests"; a new shrink-onlyignore_errorsoverride enumerates the 29 modules still carrying debt (~385 errors), with a comment forbidding additions — the module names are top-level (notests.prefix) becausetests/is not a package.append(...) or True/append(...) or valuelambdas → small named fakes with real return statements (4 sites);metadata_json,scalar()) via explicitassert/str()/comprehension filters;isinstance-filters AST nodes up front (same runtime walk, typedlineno);"UNKNOWN"coercion test,"bullish"rejection test) marked withcast+ comments — the validators they exercise are untouched;pd.DataFrameso assertions may use frame methods;np.log(Series)narrowing the production scoring component uses.Out of scope (deliberate)
disallow_untyped_defsetc.).This is ticket 9 of the 10-ticket second improvement wave (TEST-007 #98, REF-003 #99, AI-006 #100, IPO-006 #101, TEST-006 #102, PERF-002 #103, DEPLOY-004 #104, QUAL-006 #105, QUAL-007, DOC-003).
Gates (all green, local, Python 3.13)
mypypyteston the 16 touched modules--cov-fail-under=87pre_commit validate-config/compileall/ruff/bandit/pip_auditDiff vs the #105 base: 17 files, +125/−29 —
pyproject.toml(mypy config only; no dependency motion) and 16 test modules.Review
/code-review: Approve — every fix re-ran its module's tests (240 passed); the two deliberate-invalid-input casts keep the validators' rejection paths exercised; the exclusion list was cross-checked against the actual mypy output so no clean module is accidentally ignored./security-review: no findings (test/config-only diff; the strengthened IPO boundary-guard typing keeps that policy test enforcing the same rules).🤖 Generated with Claude Code