Skip to content

refactor(test): auto-stub missing modules via meta-path finder#9250

Draft
furionw wants to merge 1 commit into
mainfrom
qiwa/auto-stub-finder
Draft

refactor(test): auto-stub missing modules via meta-path finder#9250
furionw wants to merge 1 commit into
mainfrom
qiwa/auto-stub-finder

Conversation

@furionw
Copy link
Copy Markdown
Contributor

@furionw furionw commented May 7, 2026

Why

tests/report_pytest_markers.py's hand-maintained STUB_MODULES list (~190 entries) drifts: stale entries clutter, missed entries surface only as failed CI runs hours later. Reviewer feedback (Keiven) on PR #7796 asked for an import hook that auto-stubs anything that fails to resolve, eliminating the list entirely. A prior attempt at this used the deprecated find_module/load_module API that Python 3.12 ignores (52bec7279d removed it as dead code) — the right fix is the modern find_spec + Loader pair, with guards against the failure modes auto-stubbing introduces (stdlib platform-specific imports wrapped in try/except, find_spec() presence checks).

What Change

  • _AutoStubFinder appended to end of sys.meta_path; cascades submodules via is_package=True.
  • Three skip rules: first-party namespaces, sys.stdlib_module_names, and importlib.util.find_spec presence checks.
  • _LOADER_SPECIALS dict replaces inline patches for vllm.__version__ and pytest_benchmark.logger.PytestBenchmarkWarning.
  • Adds missing pytest.mark.unit to test_trtllm_request_handler_factory.py (newly surfaced by the validator).

Test Plan

  • pre-commit run pytest-marker-report --all-files — passes; [auto-stub] N modules across M packages log shows ~200 modules cascade-stubbed.
  • Verified guards in container env: winreg/_winapi skipped, dash/dash.py find_spec("dash_design_kit") returns None, dynamo.runtime.foo raises ModuleNotFoundError.

Replace the hand-maintained STUB_MODULES list (~190 entries) with a
sys.meta_path import hook that auto-stubs any third-party module the
real loaders can't resolve. The list was drift-prone — stale entries
clutter and missed entries surface only as red CI runs.

Mechanism (Python 3.12 modern API): _AutoStubFinder.find_spec returns
a stub ModuleSpec backed by _StubLoader, which instantiates the
existing _StubModule. Appended to the END of sys.meta_path so real
finders win first; auto-stubbing only fires on ModuleNotFoundError.
is_package=True + empty __path__ makes the cascade automatic — no
need to enumerate vllm.* / sglang.* / kubernetes.* upfront.

Three guard rails address the worry that auto-stub silently masks
real bugs:

  - First-party namespaces (dynamo.*, dynamo_run.*, tests.*,
    components.*, _pytest.*) are excluded — a typo or real bug in our
    own code surfaces as ImportError. ALWAYS_STUB_EXACT lets
    dynamo._core / nixl._api fall through (native bindings, .so not
    built in pre-commit env).

  - sys.stdlib_module_names skips the entire stdlib namespace at the
    top level. Catches platform-specific imports (winreg, _winapi,
    msilib, _posixsubprocess) that stdlib code wraps in try/except —
    auto-stubbing those makes blocks take the wrong branch (Windows
    code path on Linux, mimetypes registry read against a stub).

  - importlib.util.find_spec presence-checks are detected by stack
    walk and return None. Otherwise patterns like dash/dash.py's
    `if find_spec("dash_design_kit"): metadata.version(...)` would
    false-positive and fail at the metadata lookup.

The two specials previously inlined (vllm.__version__,
pytest_benchmark.logger.PytestBenchmarkWarning) move into a
_LOADER_SPECIALS dict keyed by module name; loader applies them in
exec_module after the bare stub is created.

Visibility: stderr summary line `[auto-stub] N modules across M
packages: ...` printed after collection so reviewers can spot-check
what got stubbed (surprising names like "pandas" surface immediately).

Net diff: tests/report_pytest_markers.py shrinks from 711 to ~605
lines (-103). pre-commit hook still passes; auto-stub catches ~200
modules across ~60 packages on a clean tree (cascade discovers the
actual transitive set, vs the manual list's 190 hand-picked entries).

Also adds pytest.mark.unit to test_trtllm_request_handler_factory.py
— the validator now collects this file (which previously failed
under STUB_MODULES due to tensorrt_llm import errors) and correctly
flags the missing Test Type marker. Sibling tests in the same dir
already had it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added refactor backend::trtllm Relates to the trtllm backend labels May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend::trtllm Relates to the trtllm backend refactor size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant