Repository navigation
[Tests] Skip test modules cleanly when optional deps are missing - #19704
Conversation
Validating the apache-tvm wheel in a minimal environment (no torch, scipy, cloudpickle, or tornado installed) produced 33 pytest collection errors from module-level imports of optional packages. Add pytest.importorskip guards so these modules are reported as skipped instead of erroring during collection. Indirect import chains guarded: - tvm.topi.testing imports scipy - tvm.s_tir.meta_schedule.testing.local_rpc (tvm.rpc.tracker) requires tornado - tvm.s_tir.dlight.benchmark imports cloudpickle Also remove a stray pre-license-header `import pytest` in test_runtime_builtin_paged_attention_kv_cache_flashinfer.py.
There was a problem hiding this comment.
Code Review
This pull request adds pytest.importorskip checks to various test files to gracefully skip tests when optional dependencies like scipy, torch, torchvision, cloudpickle, or tornado are not installed. However, in several files, pytest.importorskip is called without importing pytest first, which will cause a NameError during test execution. The feedback points out these missing imports and provides suggestions to fix them.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Three follow-up fixes on top of the optional-dependency guards:
- Guard module-level onnx/onnxruntime imports with pytest.importorskip
in test_frontend_onnx.py, test_frontend_onnx_backend.py, and
adreno/test_texture_network.py.
- Rename tests/python/tirx/transform/test_expr_functor.py to
test_tirx_expr_functor.py: it shares a basename with
tests/python/relax/test_expr_functor.py, and pytest's default import
mode cannot import two test modules with the same basename in one run.
- Update three leftover T.block/T.block_attr calls to
T.sblock/T.sblock_attr in
test_meta_schedule_postproc_rewrite_parallel_vectorize_unroll.py;
the rest of the file was already migrated and tvm.tirx.script no
longer has `block`, so the module failed at collection time.
Collection over tests/python/{tirx,tirx-base,s_tir,relax} with
-m "cuda or gpu" now reports zero errors.
…ction A full pytest collection sweep over tests/python in a minimal wheel environment surfaced five more modules that error on missing optional packages: - contrib/test_android/test_meta_schedule.py, contrib/test_cblas.py: scipy via tvm.topi.testing - runtime/test_runtime_rpc.py: tornado via tvm.rpc.proxy / tvm.rpc.tracker - nightly/test_nnapi/test_from_exported_to_cuda.py: torch - nightly/test_nnapi/test_network.py: onnx All five now skip cleanly via pytest.importorskip.
The leftover T.block -> T.sblock migration in test_meta_schedule_postproc_rewrite_parallel_vectorize_unroll.py will be handled by a separate PR; restore the file to its original state.
tvm.support.popen_pool imports cloudpickle lazily inside PopenWorker.send, so tests that spawn popen workers or local RPC servers fail at runtime (not collection) in environments without cloudpickle. Gate the affected tests with a function-level pytest.importorskip so the rest of each file still runs: - runtime/test_runtime_module_load.py: test_device_module_dump, test_combine_module_llvm (PopenWorker) - relax/test_vm_build.py: test_multi_systemlib (PopenWorker) and the five *_rpc tests (popen-based local RPC server) - relax/test_meta_schedule_relax_integration.py: test_compile_relax_with_database (meta_schedule popen workers) In the minimal wheel env these go from 15 failed to 15 skipped; the remaining tests in the same files still run (verified on test_runtime_module_load.py: 2 passed, 2 skipped).
tests/python/contrib/test_hexagon/conftest.py loads
tvm.contrib.hexagon.pytest_plugin, which imported tvm.rpc.tracker at
module level. tvm.rpc.tracker raises ImportError without the optional
tornado package, so pytest collection broke in minimal environments
even when no Hexagon test was actually run.
Import tvm.rpc.tracker lazily inside the _tracker_info fixture branch
that starts a local tracker, gated by pytest.importorskip("tornado"),
so tracker-dependent tests skip cleanly instead of crashing. Behavior
with tornado installed is unchanged (verified: the fixture still starts
a local tracker and tests pass).
Also fix two latent bugs exposed by importing the plugin outside a
repo-conftest pytest session: session.py annotated a parameter with the
runtime.executable module instead of the runtime.Executable class
(TypeError at class creation), and the plugin used tvm.testing.fixture
without importing tvm.testing.
Per review feedback: treat torch as a supported install option rather
than sprinkling pytest.importorskip("torch") guards across test files.
- Add a `torch` extra so `pip install apache-tvm[torch]` pulls it in.
- Add torch to [dependency-groups].test so standard test environments
always have it.
- Drop the importorskip("torch") guards this PR previously introduced
(20 files). The torchvision and scipy guards in the same files are
kept: neither package is in the test dependency group.
torchvision is only used by three tests (StochasticDepth in test_frontend_from_fx.py, roi_align in test_frontend_from_exported_program.py), but the module-level import made the whole files require it. Import it via a function-level pytest.importorskip in those three tests instead, so environments with torch but without torchvision run the rest of the files normally.
Per review feedback: define a dedicated `torch` dependency group and have the `test` group pull it in via include-group, mirroring how the `dev` group composes `test` and `lint`. This keeps torch defined in one place and lets users install just the torch group when needed.
pytest 9 removed support for declaring pytest_plugins in a non-rootdir conftest, which made collection of tests/python/contrib/test_hexagon fail outright. Re-export the hexagon plugin's hooks and fixtures from the conftest via direct imports instead (the explicit import covers the underscore-prefixed _tracker_info fixture that the wildcard skips). With the directory collectable again, guard the optional-dependency imports that previously hid behind the conftest failure: - test_benchmark_maxpool2d.py, test_meta_schedule.py, test_take.py: scipy (direct or via tvm.topi.testing) - test_relax_integration.py: onnx via tvm.relax.frontend.onnx The directory now collects 571 tests with one remaining error: test_fixed_point_conversion.py imports tvm.topi.hexagon, a module that no longer exists in the source tree - a stale test, out of scope here.
tvm.tirx.bench imports triton.profiler at module level. The file's previous torch guard masked this: CPU-only torch builds do not bundle triton, so collection failed once torch became a standard test dependency. Skip the module when triton is unavailable.
PR apache#19699 (draft, being split by topic) carried a few optional dependency guards alongside its CUDA compute-capability work. Move them here where the optional-dependency gating lives: - support/test_popen_pool.py: skip the module without cloudpickle (converted from a pytestmark skipif to the module-level pytest.importorskip used throughout this PR; ruff's E402 exemption covers importorskip but not pytestmark assignments) - s_tir/meta_schedule/test_meta_schedule_builder.py: skip test_meta_schedule_missing_build_func without cloudpickle - s_tir/meta_schedule/test_meta_schedule_cost_model.py: requires_xgboost marker on the five XGBModel tests - codegen/test_target_codegen_blob.py: skip test_cuda_multi_lib without cloudpickle
…che#19704) Validating the apache-tvm wheel in a minimal environment (no torch, scipy, cloudpickle, or tornado installed) produced 33 pytest collection errors from module-level imports of optional packages. Add pytest.importorskip guards so these modules are reported as skipped instead of erroring during collection. Indirect import chains guarded: - tvm.topi.testing imports scipy - tvm.s_tir.meta_schedule.testing.local_rpc (tvm.rpc.tracker) requires tornado - tvm.s_tir.dlight.benchmark imports cloudpickle Also remove a stray pre-license-header `import pytest` in test_runtime_builtin_paged_attention_kv_cache_flashinfer.py. (cherry picked from commit def37e3)
…che#19704) Validating the apache-tvm wheel in a minimal environment (no torch, scipy, cloudpickle, or tornado installed) produced 33 pytest collection errors from module-level imports of optional packages. Add pytest.importorskip guards so these modules are reported as skipped instead of erroring during collection. Indirect import chains guarded: - tvm.topi.testing imports scipy - tvm.s_tir.meta_schedule.testing.local_rpc (tvm.rpc.tracker) requires tornado - tvm.s_tir.dlight.benchmark imports cloudpickle Also remove a stray pre-license-header `import pytest` in test_runtime_builtin_paged_attention_kv_cache_flashinfer.py. (cherry picked from commit def37e3)
) Validating the apache-tvm wheel in a minimal environment (no torch, scipy, cloudpickle, or tornado installed) produced 33 pytest collection errors from module-level imports of optional packages. Add pytest.importorskip guards so these modules are reported as skipped instead of erroring during collection. Indirect import chains guarded: - tvm.topi.testing imports scipy - tvm.s_tir.meta_schedule.testing.local_rpc (tvm.rpc.tracker) requires tornado - tvm.s_tir.dlight.benchmark imports cloudpickle Also remove a stray pre-license-header `import pytest` in test_runtime_builtin_paged_attention_kv_cache_flashinfer.py.
) Validating the apache-tvm wheel in a minimal environment (no torch, scipy, cloudpickle, or tornado installed) produced 33 pytest collection errors from module-level imports of optional packages. Add pytest.importorskip guards so these modules are reported as skipped instead of erroring during collection. Indirect import chains guarded: - tvm.topi.testing imports scipy - tvm.s_tir.meta_schedule.testing.local_rpc (tvm.rpc.tracker) requires tornado - tvm.s_tir.dlight.benchmark imports cloudpickle Also remove a stray pre-license-header `import pytest` in test_runtime_builtin_paged_attention_kv_cache_flashinfer.py.
Validating the apache-tvm wheel in a minimal environment (no torch, scipy, cloudpickle, or tornado installed) produced 33 pytest collection errors from module-level imports of optional packages. Add pytest.importorskip guards so these modules are reported as skipped instead of erroring during collection.
Indirect import chains guarded:
Also remove a stray pre-license-header
import pytestin test_runtime_builtin_paged_attention_kv_cache_flashinfer.py.