Skip to content

type: clean mypy errors in inspect, loader, onnx, optim and enforce in CI#896

Merged
xieofxie merged 10 commits into
mainfrom
hualxie/type_4
Jun 17, 2026
Merged

type: clean mypy errors in inspect, loader, onnx, optim and enforce in CI#896
xieofxie merged 10 commits into
mainfrom
hualxie/type_4

Conversation

@xieofxie

@xieofxie xieofxie commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Brings four winml.modelkit packages to zero mypy errors under the strict [tool.mypy] config, and wires them into the required CI type-check gate so they cannot regress.

  • inspect, loader, onnx, optim — now 0 errors under strict = true.
  • .github/workflows/lint.yml — adds the four packages to the Type check (required) step (12 → 16 packages). New errors in them now block the PR.

Fixes follow the repos typing playbook: narrow/fix at the source first; cast() only at genuine untyped third-party boundaries; Any only for true dynamic pass-throughs.

Notable fixes

  • optimBasePipe is now generic over its config (BasePipe[ConfigT], ConfigT bound to PipeConfig). This resolves all 6 Liskov [override] errors structurally and lets the pre-existing # type: ignore[override] in rewrite.py be removed. Test-driven __post_init__ type validators in registry.py kept behind a file-level # mypy: disable-error-code="unreachable" pragma.
  • inspect — corrected a stale process_module return annotation (cleared 3 [unreachable] + a [return-value] together); assert export is not None matching the existing codebase convention; hf-hub exceptions imported from their defining module huggingface_hub.errors.
  • onnx — declared SupportedONNXTypes dynamically-built lookup maps as typed ClassVars (fixes the attr-defined + no-any-return cluster); list[int | None] for dynamic tensor dims; targeted [call-arg] ignores for onnxs pybind11-enum stubs.
  • loader — boundary cast()s at untyped optimum/transformers returns; a typed local for the Case-2 model-class resolution instead of reusing a type-typed name.

Housekeeping

  • Normalized line endings back to LF on a handful of files that had been flipped to CRLF on Windows (pure line-ending change, no content difference).

Out of scope

  • models is left untouched (still has pre-existing errors) for a follow-up pass; it is intentionally not added to the required gate.

@xieofxie xieofxie changed the title type checking: add .. type: clean mypy errors in inspect, loader, onnx, optim and enforce in CI Jun 16, 2026
@xieofxie xieofxie marked this pull request as ready for review June 16, 2026 06:17
@xieofxie xieofxie requested a review from a team as a code owner June 16, 2026 06:17
Comment thread src/winml/modelkit/loader/hf.py Fixed
Comment thread src/winml/modelkit/loader/task.py Fixed
Comment thread src/winml/modelkit/loader/task.py Fixed

@DingmaomaoBJTU DingmaomaoBJTU left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 24 changed files. Type annotations are generally correct and well-motivated. Found one consistency gap (SurgeryPipe missing new type parameter), one redundant reset, one fragile assert-for-narrowing, and one overly-broad module-level mypy suppressor.

Comment thread src/winml/modelkit/optim/pipes/surgery.py
Comment thread src/winml/modelkit/loader/resolution.py Outdated
Comment thread src/winml/modelkit/inspect/resolver.py Outdated
Comment thread src/winml/modelkit/optim/registry.py Outdated
- surgery.py: SurgeryPipe -> BasePipe[SurgeryPipeConfig] (consistency; main merge had reverted it)
- resolution.py: drop redundant Stage-1 opt_task reset (already hoisted to None)
- resolver.py: replace assert with explicit ValueError guard (survives python -O)
- registry.py: replace file-level unreachable pragma with per-line ignores on the 3 validators

@DingmaomaoBJTU DingmaomaoBJTU left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up review: all four findings from the previous pass are fully addressed in commit c2feb8a. No new issues found.

Comment thread src/winml/modelkit/optim/pipes/surgery.py
Comment thread src/winml/modelkit/loader/resolution.py
Comment thread src/winml/modelkit/inspect/resolver.py
Comment thread src/winml/modelkit/optim/registry.py

@DingmaomaoBJTU DingmaomaoBJTU left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! All 4 findings resolved in c2feb8a: SurgeryPipe correctly parameterized, redundant Stage-1 reset replaced with comment, assert-for-narrowing replaced with explicit if/raise ValueError, and module-level mypy pragma replaced with three narrowly-scoped per-line ignores.

@xieofxie xieofxie merged commit c156654 into main Jun 17, 2026
9 checks passed
@xieofxie xieofxie deleted the hualxie/type_4 branch June 17, 2026 07:48
timenick added a commit that referenced this pull request Jun 18, 2026
…accessor

- Add _composite_registry(): the single registry-load trigger the three readers
  (resolve_composite / composite_pipeline_tasks / _composite_components_for_task)
  now share. It raises RuntimeError when COMPOSITE_MODEL_REGISTRY is empty, so a
  moved/renamed registration fails loudly instead of silently returning []/None
  and disabling the composite feature unnoticed.
- Fix a mypy break the main merge surfaced: #896 re-tightened the
  _composite_components_for_task annotation to type[WinMLCompositeModel] while the
  prior commit had removed that import; re-add it under TYPE_CHECKING.
- Test: the accessor raises loudly when the registry is empty.
xieofxie added a commit that referenced this pull request Jun 22, 2026
…try, utils and enforce in CI (#916)

@
## Summary

Brings seven more `winml.modelkit` packages to **zero mypy errors**
under the strict `[tool.mypy]` config and wires them into the required
CI type-check gate (16 → 23 packages). Continues the incremental cleanup
from #896.

Cleaned: **optracing, quant, serve, session, sysinfo, telemetry, utils**
(sysinfo was already clean). Fixes follow the repos typing playbook —
fix at the source first; `cast()` only at genuine untyped third-party
boundaries; `Any` only for true dynamic pass-throughs.

## Real bugs surfaced (not just typing)

- **`utils/hub_utils.py` version import** — `from ..version import
__version__` referenced a non-existent module; guarded by `try/except`,
so the export version was silently always `"unknown"`. Fixed to `from ..
import __version__`. (The containing helper `inject_hub_metadata` is
dead code — tracked in #913.)
- **`utils/hub_utils.py`** — `model_info.modelId` → `model_info.id`
(huggingface_hub renamed the attribute).

## Notable fixes

- **session** — bound a non-None local after auto-compile so narrowing
survives into the lambda/comprehension; explicit guards for `resolved_ep
is None` and single-mode `model_path`; widened PDH counter containers to
`float`; class-level `_initialized` annotation; distinct ctypes struct
locals.
- **telemetry** — annotated the `LoggerProvider`/`Logger` instance
attributes (were inferred as `None`, cascading into
unreachable/attr-defined); OTel/JSON boundary casts; typed the
`@contextmanager`/`@asynccontextmanager` generators.
- **serve** — `cast()` at `json.loads`/`app.state` boundaries; `import
binascii` to use `binascii.Error` (typeshed doesnt expose
`base64.binascii`); explicit single-mode `model_path` guard.
- **utils** — removed stale `# type: ignore`s; `DataclassInstance` cast
for generic-`TypeVar` dataclass reflection; `EPAlias` key cast for the
alias lookup; loop-variable rename to fix
`InputTensorSpec`/`OutputTensorSpec` shadowing.

## Config changes (`pyproject.toml`)

- **`qairt.*`** → `ignore_missing_imports` (external Qualcomm AI Runtime
SDK; imported only inside `compile_qairt_bin.py`, which runs in a
separate `venv-winml` subprocess — absent from the CI env).
- **`windowsml`** → `follow_untyped_imports = true` (installed but ships
no `py.typed`; analyzing its source is clean and keeps its inline
annotations instead of collapsing to `Any`).

## Verification

- Combined required-gate invocation (all 23 packages): `Success: no
issues found in 300 source files`.
- ruff clean; unit tests green for the touched packages (2 pre-existing
OpenVINO-EP-unavailable failures in this env, confirmed unrelated).
- Branch-vs-main diff is content-only (line endings normalized to LF to
match main).
@

---------

Co-authored-by: Hualiang Xie <hualxie@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants