This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch tvm-further-cleanup-python-tests-followup
in repository https://gitbox.apache.org/repos/asf/tvm.git

commit e85f528ca6093b426d183dbce2c9b2cbe13255e5
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Jul 5 19:03:04 2026 +0000

    [TEST] Remove phased-out testing modules
---
 tests/python/testing/test_testing.py               | 116 -----------
 .../testing/test_tvm_testing_before_after.py       | 147 -------------
 tests/python/testing/test_tvm_testing_features.py  | 179 ----------------
 .../python/testing/test_type_annotation_checker.py | 227 ---------------------
 4 files changed, 669 deletions(-)

diff --git a/tests/python/testing/test_testing.py 
b/tests/python/testing/test_testing.py
deleted file mode 100644
index 373e78845b..0000000000
--- a/tests/python/testing/test_testing.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E731, F821, F841
-import numpy as np
-
-import tvm
-import tvm.testing
-
-
-def test_check_numerical_grads():
-    # Functions and their derivatives
-    functions = [
-        lambda x: (x * x * x, 3 * x * x),
-        lambda x: (x * x, 2 * x),
-        lambda x: (np.abs(x), np.sign(x)),
-        lambda x: (np.log(np.abs(x)), 1 / x),
-        lambda x: (np.sqrt(np.abs(x)), np.sign(x) / (2 * np.sqrt(np.abs(x)))),
-        lambda x: (1 / x, -1 / (x * x)),
-        lambda x: (np.sign(np.sin(1 / x)), np.zeros_like(x)),
-        lambda x: (x * np.sin(1 / x), np.sin(1 / x) - np.cos(1 / x) / x),
-        lambda x: (np.sin(1 / x), -np.cos(1 / x) / (x * x)),
-        lambda x: (np.tan(x), 1.0 / (np.cos(x) * np.cos(x))),
-    ]
-
-    np.random.seed(0)
-
-    # Avoid values too close to 0 since singularities of our functions are 
there
-    min_x = 0.5
-
-    for func in functions:
-        x_input = np.random.uniform(min_x, 10, size=(3, 4))
-
-        # We need a function returning a scalar, so sum the results
-        func_forw = lambda x: np.sum(func(x)[0])
-        grads = [func(x_input)[1]]
-
-        tvm.testing.check_numerical_grads(func_forw, [x_input], grads)
-
-    # Check functions with multiple arguments
-    for f1 in functions:
-        for f2 in functions:
-            x_input = np.random.uniform(min_x, 10, size=(3, 4))
-            y_input = np.random.uniform(min_x, 10, size=(3, 4))
-
-            func_forw = lambda x, y: np.sum(f1(x)[0] + f2(y)[0])
-            grads = [f1(x_input)[1], f2(y_input)[1]]
-
-            tvm.testing.check_numerical_grads(func_forw, [x_input, y_input], 
grads)
-
-            # Same thing but with keyword arguments
-            func_forw = lambda x, y: np.sum(f1(x)[0] + f2(y)[0])
-            grads = {"x": f1(x_input)[1], "y": f2(y_input)[1]}
-
-            tvm.testing.check_numerical_grads(func_forw, {"x": x_input, "y": 
y_input}, grads)
-
-    def _noise1(x, atol=1e-2, rtol=0.1):
-        # We go in random direction using twice the original tolerance to be 
sure this
-        # results in an error
-        sqrt_n = np.sqrt(float(np.prod(x.shape)))
-        tol = 2 * (np.linalg.norm(x) * rtol + atol * sqrt_n)
-        noise = np.random.normal(size=x.shape)
-        noise = tol * noise / np.linalg.norm(noise)
-        return x + noise
-
-    def _noise2(x, atol=1e-2, rtol=0.1):
-        # This noise affects just a single component
-        sqrt_n = np.sqrt(float(np.prod(x.shape)))
-        tol = 2 * (np.linalg.norm(x) * rtol + atol * sqrt_n)
-        n = np.random.randint(np.prod(x.shape))
-        noise = np.zeros_like(x)
-        noise.reshape(-1)[n] = tol
-        return x + noise
-
-    # Add noise to gradients and check that the function throws
-    for f1 in functions:
-        for f2 in functions:
-            x_input = np.random.uniform(min_x, 10, size=(3, 4))
-            y_input = np.random.uniform(min_x, 10, size=(3, 4))
-
-            func_forw = lambda x, y: np.sum(f1(x)[0] + f2(y)[0])
-            grads = [_noise1(f1(x_input)[1]), _noise1(f2(y_input)[1])]
-
-            try:
-                tvm.testing.check_numerical_grads(func_forw, [x_input, 
y_input], grads)
-            except AssertionError as e:
-                pass
-            else:
-                raise AssertionError("tvm.testing.check_numerical_grads didn't 
raise an exception")
-
-            func_forw = lambda x, y: np.sum(f1(x)[0] + f2(y)[0])
-            grads = {"x": _noise2(f1(x_input)[1]), "y": 
_noise2(f2(y_input)[1])}
-
-            try:
-                tvm.testing.check_numerical_grads(func_forw, {"x": x_input, 
"y": y_input}, grads)
-            except AssertionError as e:
-                pass
-            else:
-                raise AssertionError("tvm.testing.check_numerical_grads didn't 
raise an exception")
-
-
-if __name__ == "__main__":
-    test_tvm.testing.check_numerical_grads()
diff --git a/tests/python/testing/test_tvm_testing_before_after.py 
b/tests/python/testing/test_tvm_testing_before_after.py
deleted file mode 100644
index 7fb7cbbff0..0000000000
--- a/tests/python/testing/test_tvm_testing_before_after.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-import tvm
-import tvm.testing
-from tvm.script import ir_module
-from tvm.script import tirx as T
-
-
-def test_before_after_prim_func():
-    @T.prim_func(private=True, s_tir=True)
-    def before():
-        T.evaluate(0)
-
-    expected = before
-
-    mod = tvm.IRModule.from_expr(before)
-    # Identity transform (no-op)
-    mod = (lambda x: x)(mod)
-    tvm.ir.assert_structural_equal(mod["main"], expected)
-
-
-def test_before_after_method():
-    @T.prim_func(private=True, s_tir=True)
-    def before():
-        T.evaluate(0)
-
-    expected = before
-
-    mod = tvm.IRModule.from_expr(before)
-    # Identity transform (no-op)
-    mod = (lambda x: x)(mod)
-    tvm.ir.assert_structural_equal(mod["main"], expected)
-
-
-def test_before_after_fixture():
-    @T.prim_func(private=True, s_tir=True)
-    def before():
-        T.evaluate(0)
-
-    expected = before
-
-    mod = tvm.IRModule.from_expr(before)
-    # Identity transform (no-op)
-    mod = (lambda x: x)(mod)
-    tvm.ir.assert_structural_equal(mod["main"], expected)
-
-
-def test_before_after_delayed_prim_func():
-    @T.prim_func(private=True, s_tir=True)
-    def before():
-        T.evaluate(0)
-
-    expected = before
-
-    mod = tvm.IRModule.from_expr(before)
-    # Identity transform (no-op)
-    mod = (lambda x: x)(mod)
-    tvm.ir.assert_structural_equal(mod["main"], expected)
-
-
-def test_before_after_parametrized_fixture():
-    """Test with different buffer sizes"""
-    for n in [1, 8, 16]:
-
-        @T.prim_func(private=True, s_tir=True)
-        def before(A: T.Buffer(n, "float32")):
-            for i in T.serial(n):
-                A[i] = 0.0
-
-        expected = before
-
-        mod = tvm.IRModule.from_expr(before)
-        # Identity transform (no-op)
-        mod = (lambda x: x)(mod)
-        tvm.ir.assert_structural_equal(mod["main"], expected)
-
-
-def test_before_after_ir_module():
-    """The preferred form for writing TIR unit tests
-
-    All evaluation is done at test-time, with the minimal amount of
-    additional lines.
-    """
-
-    @ir_module
-    class before:
-        @T.prim_func(private=True, s_tir=True)
-        def func_A(A: T.Buffer(16, "float32")):
-            for i in T.serial(16):
-                A[i] = 0.0
-
-        @T.prim_func(private=True, s_tir=True)
-        def func_B(A: T.Buffer(16, "int32")):
-            for i in T.serial(16):
-                A[i] = 42
-
-    expected = before
-
-    # Identity transform (no-op)
-    mod = (lambda x: x)(before)
-    tvm.ir.assert_structural_equal(mod, expected)
-
-
-def test_before_after_ir_module_explicit_fixture():
-    """Like test_before_after_ir_module, but with an explicit fixture
-
-    If the IRModule depends on additional fixtures, this form can be
-    used.
-    """
-
-    @ir_module
-    class before:
-        @T.prim_func(private=True, s_tir=True)
-        def func_A(A: T.Buffer(16, "float32")):
-            for i in T.serial(16):
-                A[i] = 0.0
-
-        @T.prim_func(private=True, s_tir=True)
-        def func_B(A: T.Buffer(16, "int32")):
-            for i in T.serial(16):
-                A[i] = 42
-
-    expected = before
-
-    # Identity transform (no-op)
-    mod = (lambda x: x)(before)
-    tvm.ir.assert_structural_equal(mod, expected)
-
-
-if __name__ == "__main__":
-    tvm.testing.main()
diff --git a/tests/python/testing/test_tvm_testing_features.py 
b/tests/python/testing/test_tvm_testing_features.py
deleted file mode 100644
index d66fd2841b..0000000000
--- a/tests/python/testing/test_tvm_testing_features.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: RUF012
-
-import os
-
-import pytest
-
-import tvm.testing
-
-
-class TestParameter:
-    param1_vals = [1, 2, 3]
-    param2_vals = ["a", "b", "c"]
-
-    param1 = tvm.testing.parameter(*param1_vals)
-    param2 = tvm.testing.parameter(*param2_vals)
-
-    def test_using_independent(self, param1, param2):
-        assert param1 in self.param1_vals
-        assert param2 in self.param2_vals
-
-
-class TestFixtureCaching:
-    param1_vals = [1, 2, 3]
-    param2_vals = ["a", "b", "c"]
-
-    param1 = tvm.testing.parameter(*param1_vals)
-    param2 = tvm.testing.parameter(*param2_vals)
-
-    @tvm.testing.fixture
-    def uncached_fixture(self, param1):
-        return 2 * param1
-
-    def test_use_uncached(self, param1, param2, uncached_fixture):
-        assert 2 * param1 == uncached_fixture
-
-    @tvm.testing.fixture(cache_return_value=True)
-    def cached_fixture(self, param1):
-        return 3 * param1
-
-    def test_use_cached(self, param1, param2, cached_fixture):
-        assert 3 * param1 == cached_fixture
-
-
-def test_fixture_cache_reuses_setup_and_returns_copies():
-    setup_calls = []
-
-    def setup(value):
-        setup_calls.append(value)
-        return {"value": value}
-
-    cached_setup = tvm.testing.utils._fixture_cache(setup)
-    first = cached_setup(1)
-    first["value"] = 0
-
-    assert cached_setup(1) == {"value": 1}
-    assert cached_setup(2) == {"value": 2}
-    assert setup_calls == [1, 2]
-
-
-def test_request_hook_uses_explicit_path(monkeypatch, tmp_path):
-    hook_script = tmp_path / "request_hook.py"
-    hook_script.touch()
-    hook_script = hook_script.resolve()
-    loads = []
-    initializations = []
-
-    def load_hook(path):
-        loads.append(path)
-        return {"init": lambda: initializations.append(path)}
-
-    monkeypatch.setattr(tvm.testing.utils, "IS_IN_CI", True)
-    monkeypatch.setattr(
-        tvm.testing.utils,
-        "__file__",
-        "/installed/site-packages/tvm/testing/utils.py",
-    )
-    monkeypatch.setattr(tvm.testing.utils.runpy, "run_path", load_hook)
-
-    try:
-        tvm.testing.utils.install_request_hook(hook_script)
-        tvm.testing.utils.install_request_hook(hook_script)
-    finally:
-        tvm.testing.utils._REQUEST_HOOK_INITIALIZERS.pop(hook_script, None)
-
-    assert loads == [str(hook_script)]
-    assert initializations == [str(hook_script), str(hook_script)]
-
-
-class TestBrokenFixture:
-    # Tests that use a fixture that throws an exception fail, and are
-    # marked as setup failures.  The tests themselves are never run.
-    # This behavior should be the same whether or not the fixture
-    # results are cached.
-
-    @tvm.testing.fixture
-    def broken_uncached_fixture(self):
-        raise RuntimeError("Intentionally broken fixture")
-
-    @pytest.mark.xfail(True, reason="Broken fixtures should result in a 
failing setup", strict=True)
-    def test_uses_broken_uncached_fixture(self, broken_uncached_fixture):
-        pass
-
-    @tvm.testing.fixture(cache_return_value=True)
-    def broken_cached_fixture(self):
-        raise RuntimeError("Intentionally broken fixture")
-
-    @pytest.mark.xfail(True, reason="Broken fixtures should result in a 
failing setup", strict=True)
-    def test_uses_broken_cached_fixture(self, broken_cached_fixture):
-        pass
-
-
[email protected](
-    bool(int(os.environ.get("TVM_TEST_DISABLE_CACHE", "0"))),
-    reason="Cannot test cache behavior while caching is disabled",
-)
-class TestCacheableTypes:
-    class EmptyClass:
-        pass
-
-    @tvm.testing.fixture(cache_return_value=True)
-    def uncacheable_fixture(self):
-        return self.EmptyClass()
-
-    def test_uses_uncacheable(self, request):
-        with pytest.raises(TypeError):
-            request.getfixturevalue("uncacheable_fixture")
-
-    class ImplementsReduce:
-        def __reduce__(self):
-            return super().__reduce__()
-
-    @tvm.testing.fixture(cache_return_value=True)
-    def fixture_with_reduce(self):
-        return self.ImplementsReduce()
-
-    def test_uses_reduce(self, fixture_with_reduce):
-        pass
-
-    class ImplementsDeepcopy:
-        def __deepcopy__(self, memo):
-            return type(self)()
-
-    @tvm.testing.fixture(cache_return_value=True)
-    def fixture_with_deepcopy(self):
-        return self.ImplementsDeepcopy()
-
-    def test_uses_deepcopy(self, fixture_with_deepcopy):
-        pass
-
-
-class TestPytestCache:
-    param = tvm.testing.parameter(1, 2, 3)
-
-    @pytest.fixture(scope="class")
-    def cached_fixture(self, param):
-        return param * param
-
-    def test_uses_cached_fixture(self, param, cached_fixture):
-        assert cached_fixture == param * param
-
-
-if __name__ == "__main__":
-    tvm.testing.main()
diff --git a/tests/python/testing/test_type_annotation_checker.py 
b/tests/python/testing/test_type_annotation_checker.py
deleted file mode 100644
index b5d2afcb92..0000000000
--- a/tests/python/testing/test_type_annotation_checker.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: F401
-"""Test type checker based on python's type annotations"""
-
-import sys
-from collections.abc import Callable
-from typing import Union
-
-import _pytest
-import pytest
-
-import tvm
-from tvm.s_tir.schedule._type_checker import type_checked
-
-
-def int_func(x: int) -> int:
-    return 2 * x
-
-
-def str_func(x: str) -> str:
-    return 2 * x
-
-
-test_cases = [
-    {
-        "type_annotation": int,
-        "positive_cases": [5],
-        "negative_cases": ["5"],
-    },
-    {
-        "type_annotation": list[int],
-        "positive_cases": [
-            [5],
-            [],
-            # Tuples are allowed to be used as lists, because both are
-            # represented in FFI as tvm::Array.
-            (1, 2, 3),
-        ],
-        "negative_cases": [
-            None,
-            5,
-            ["5"],
-        ],
-    },
-    {
-        "type_annotation": dict[str, int],
-        "positive_cases": [
-            {"key1": 0, "key2": 1, "key3": -1},
-        ],
-        "negative_cases": [None, [1], {1: "1"}],
-    },
-    {
-        "type_annotation": tuple[int],
-        "positive_cases": [
-            (5,),
-        ],
-        "negative_cases": [
-            None,
-            (1, 2, 3),
-            [1],
-            5,
-            ["5"],
-        ],
-    },
-    {
-        "type_annotation": tuple[str, int],
-        "positive_cases": [
-            ("x", 5),
-        ],
-        "negative_cases": [
-            42,
-            ("x", 5, 6),
-            ("x", 5, "y"),
-            ("x", 5.0),
-            (None, 5),
-        ],
-    },
-    {
-        "type_annotation": str | int,
-        "positive_cases": [
-            "x",
-            5,
-        ],
-        "negative_cases": [
-            5.0,
-            ("x", 5, 6),
-            None,
-        ],
-    },
-    {
-        "type_annotation": Callable,
-        "positive_cases": [str_func, int_func],
-        "negative_cases": [
-            None,
-            "x",
-            42,
-        ],
-    },
-    {
-        "type_annotation": Callable[[int], int],
-        "positive_cases": [int_func],
-        "negative_cases": [
-            None,
-            "x",
-            42,
-            pytest.param(
-                str_func,
-                marks=pytest.mark.xfail(
-                    reason="Signature of Callable arguments not currently 
checked"
-                ),
-            ),
-        ],
-    },
-]
-
-
-def make_parametrization(type_annotation, case):
-    if isinstance(case, _pytest.mark.structures.ParameterSet):
-        marks = case.marks
-        (case,) = case.values
-    else:
-        marks = []
-
-    try:
-        annotation_name = type_annotation.__name__
-    except AttributeError:
-        annotation_name = str(type_annotation).replace("typing.", "")
-
-    if hasattr(case, "__name__"):
-        case_name = case.__name__
-    else:
-        case_name = str(case)
-
-    name = f"{annotation_name}, {case_name}"
-
-    return pytest.param(type_annotation, case, marks=marks, id=name)
-
-
-positive_cases = [
-    make_parametrization(config["type_annotation"], case)
-    for config in test_cases
-    for case in config["positive_cases"]
-]
-
-negative_cases = [
-    make_parametrization(config["type_annotation"], case)
-    for config in test_cases
-    for case in config["negative_cases"]
-]
-
-
[email protected](
-    ["type_annotation", "case"],
-    positive_cases,
-)
-def test_matches_type(type_annotation, case):
-    @type_checked
-    def func(_: type_annotation):
-        pass
-
-    func(case)
-
-
[email protected](
-    ["type_annotation", "case"],
-    negative_cases,
-)
-def test_not_matches(type_annotation, case):
-    @type_checked
-    def func(_: type_annotation):
-        pass
-
-    with pytest.raises(TypeError):
-        func(case)
-
-
[email protected](
-    ["type_annotation", "expected_key", "expected_subtypes"],
-    [
-        pytest.param(str | int, "union", [str, int], id="str | int"),
-        pytest.param(list[str], "list", [str], id="List[str]"),
-        pytest.param(dict[str, int], "dict", [str, int], id="Dict[str, int]"),
-        pytest.param(tuple[str, int], "tuple", (str, int), id="Tuple[str, 
int]"),
-        pytest.param(
-            list[str] | dict[str, int],
-            "union",
-            [list[str], dict[str, int]],
-            id="Union[List[str], Dict[str, int]]",
-        ),
-    ],
-)
-def test_subscripted_generics(type_annotation, expected_key, 
expected_subtypes):
-    """Test that _dispatcher correctly handles subscripted generics in Python 
3.14+.
-
-    In Python 3.14, Union and other generic types have a different internal 
representation.
-    This test ensures that the dispatcher correctly identifies these types.
-    """
-    from tvm.s_tir.schedule._type_checker import _dispatcher
-
-    key, subtypes = _dispatcher(type_annotation)
-    assert key == expected_key, f"Expected '{expected_key}' but got '{key}'"
-
-    if isinstance(expected_subtypes, tuple):
-        assert tuple(subtypes) == expected_subtypes, (
-            f"Expected {expected_subtypes} but got {subtypes}"
-        )
-    else:
-        assert subtypes == expected_subtypes, f"Expected {expected_subtypes} 
but got {subtypes}"
-
-
-if __name__ == "__main__":
-    tvm.testing.main()

Reply via email to