This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch script/canonical-parser-df
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/script/canonical-parser-df by
this push:
new ac5355bdcc [TVMScript] Consolidate overlapping parser regression
coverage
ac5355bdcc is described below
commit ac5355bdcc380d959d64b7b375497116c5281c35
Author: Tianqi Chen <[email protected]>
AuthorDate: Wed Sep 23 21:35:23 2026 +0000
[TVMScript] Consolidate overlapping parser regression coverage
---
.../relax/script/test_parser_captured_shapes.py | 5 ++-
.../test_relax_parser_comparison_integration.py | 13 +------
tests/python/script/test_parser.py | 40 ----------------------
tests/python/script/test_parser_call_scopes.py | 26 --------------
.../script/test_parser_comparison_semantics.py | 17 +++++++++
tests/python/script/test_parser_host_selection.py | 28 +++------------
tests/python/script/test_parser_scoped_symbols.py | 20 ++---------
.../test_tirx_parser_comparison_integration.py | 26 ++------------
8 files changed, 31 insertions(+), 144 deletions(-)
diff --git a/tests/python/relax/script/test_parser_captured_shapes.py
b/tests/python/relax/script/test_parser_captured_shapes.py
index 53a2366791..0aee00c112 100644
--- a/tests/python/relax/script/test_parser_captured_shapes.py
+++ b/tests/python/relax/script/test_parser_captured_shapes.py
@@ -31,5 +31,8 @@ def main(x: R.Tensor(shape, "float32")):
"""
result = parser.parse(source, extra_vars={"shape": (n, 16)})
assert result.params[0].ty.shape[0].same_as(n)
- with pytest.raises(Exception):
+ with pytest.raises(
+ TypeError, match="^Builder expression arguments require concrete
symbols, not strings$"
+ ) as error:
parser.parse(source, extra_vars={"shape": ("n", 16)})
+ assert type(error.value) is TypeError
diff --git
a/tests/python/relax/script/test_relax_parser_comparison_integration.py
b/tests/python/relax/script/test_relax_parser_comparison_integration.py
index de0c351a5b..e7b11bd0d2 100644
--- a/tests/python/relax/script/test_relax_parser_comparison_integration.py
+++ b/tests/python/relax/script/test_relax_parser_comparison_integration.py
@@ -35,18 +35,7 @@ def
test_unmarked_host_comparison_never_calls_python_overload(operator, kind):
calls.append(other)
return True
- setattr(
- Host,
- {
- "LT": "__lt__",
- "LE": "__le__",
- "GT": "__gt__",
- "GE": "__ge__",
- "EQ": "__eq__",
- "NE": "__ne__",
- }[kind],
- comparison,
- )
+ setattr(Host, "__" + kind.lower() + "__", comparison)
decorator = "R.function"
statement = "return left " + operator + " right"
with pytest.raises(TypeError, match="(PrimExpr|primitive|convert|type)"):
diff --git a/tests/python/script/test_parser.py
b/tests/python/script/test_parser.py
index 8954527149..40787bd135 100644
--- a/tests/python/script/test_parser.py
+++ b/tests/python/script/test_parser.py
@@ -224,33 +224,6 @@ def main():
assert all(value.args[0] is condition for _, value in result.body)
-def
test_comparison_chain_evaluates_middle_once_and_preserves_written_order(language):
- # Before: operand(0) < operand(1) <= operand(2)
- # Expected builder program:
- # a, b, c = operand(0), operand(1), operand(2)
- # X.and_(X.lt(a, b), X.le(b, c))
- seen = []
- values = [Value("operand", (index,)) for index in range(3)]
-
- def operand(index):
- seen.append(index)
- return values[index]
-
- result = language.parse(
- """
[email protected]
-def main():
- operand(0) < operand(1) <= operand(2)
-""",
- operand=operand,
- )
- assert seen == [0, 1, 2]
- comparison = result.body[0][1]
- assert comparison.op == "and"
- first, second = comparison.args
- assert first.args == tuple(values[:2]) and second.args == tuple(values[1:])
-
-
def
test_callee_arguments_and_keywords_evaluate_once_with_caller_context(language):
# Before: callee()(operand(1), b=operand(2))
# Expected builder program:
@@ -450,19 +423,6 @@ def main(x: X.tensor(("n", "n"))):
assert isinstance(error.value, NameError)
-def test_explicit_symbol_declaration_reuses_annotation_identity(language):
- # Before: def main(x: X.tensor(("n",))): n = X.symbol(); X.record(n)
- # Expected builder program: n = X.resolve_type_var_("n", "int64");
X.emit_(X.record(n))
- result = language.parse("""
[email protected]
-def main(x: X.tensor(("n",))):
- n = X.symbol()
- X.record(n)
-""")
- symbol = result.params[0].args[0].args[0][0]
- assert result.body[0][1] is symbol
-
-
@pytest.mark.parametrize(
"binding", ["X = 1", "for X in range(2):\n pass", "with context()
as X:\n pass"]
)
diff --git a/tests/python/script/test_parser_call_scopes.py
b/tests/python/script/test_parser_call_scopes.py
index b4ada811ee..6c1f5cc2ab 100644
--- a/tests/python/script/test_parser_call_scopes.py
+++ b/tests/python/script/test_parser_call_scopes.py
@@ -72,32 +72,6 @@ def
test_scoped_helper_multiple_emissions_and_normal_return(spanned):
assert span_lines(statements[1]) == [4, 9]
-def
test_source_call_callee_arguments_and_keywords_evaluate_once_in_order(language):
- seen = []
-
- def callee():
- seen.append("callee")
-
- def function(a, *, b):
- seen.append((a, b))
- return a + b
-
- return function
-
- def operand(value):
- seen.append(value)
- return value
-
- source = """
[email protected]
-def main():
- X.record(callee()(operand(1), b=operand(2)))
-"""
- result = language.parse(source, callee=callee, operand=operand)
- assert seen == ["callee", 1, 2, (1, 2)]
- assert result.body == [("emit", 3)]
-
-
def test_module_source_calls_have_context_before_annotations(spanned):
seen = []
diff --git a/tests/python/script/test_parser_comparison_semantics.py
b/tests/python/script/test_parser_comparison_semantics.py
index bffd71b264..3b56909d77 100644
--- a/tests/python/script/test_parser_comparison_semantics.py
+++ b/tests/python/script/test_parser_comparison_semantics.py
@@ -59,6 +59,8 @@ def parse(language, source, *, track_span=True, **captures):
@pytest.mark.parametrize("literal_left", [True, False])
@pytest.mark.parametrize("track_span", [True, False])
def test_written_comparison_order(language, operator, kind, literal_left,
track_span):
+ # Before: 0 < x (and each written operator/operand order).
+ # Expected builder program: X.emit_(I.at_(location, X.lt(0, x))).
x = ir.Var("x", "int32")
expression = f"0 {operator} x" if literal_left else f"x {operator} 0"
actual = parse(
@@ -77,6 +79,8 @@ def test_written_comparison_order(language, operator, kind,
literal_left, track_
@pytest.mark.parametrize("dtype", ["int64", "uint32", "float32", "int32x4",
"float32x4"])
def test_literal_uses_ir_operand_type_and_lanes(language, dtype):
+ # Before: 0 < x, where x carries the scalar or vector dtype.
+ # Expected builder program: X.lt(0, x); native IR performs literal
promotion/broadcast.
x = ir.Var("x", dtype)
value = parse(language, "@X.script\ndef main():\n 0 < x\n",
x=x).body[0][1]
assert isinstance(value, prim.LT)
@@ -87,6 +91,8 @@ def test_literal_uses_ir_operand_type_and_lanes(language,
dtype):
@pytest.mark.parametrize("operator,kind", OPERATORS)
@pytest.mark.parametrize("other_kind", ["host", "primitive"])
def test_custom_host_comparison_result_is_preserved(language, operator, kind,
other_kind):
+ # Before: consume(X.constexpr(left < right)).
+ # Expected builder program: consume(left < right), preserving the Python
overload result.
class Result:
def __bool__(self):
raise AssertionError("custom comparison result must not be
truth-tested")
@@ -169,6 +175,9 @@ def
test_host_ordering_does_not_materialize_an_equality_result(language):
def test_chain_evaluates_source_operands_once_in_order(language):
+ # Before: a() < b() <= c() != d().
+ # Expected builder program: evaluate a/b/c/d once, then X.and_(X.lt(a, b),
+ # X.le(b, c), X.ne(c, d), chain=(a, b, c, d)).
seen = []
def operand(index, value):
@@ -197,6 +206,8 @@ def main():
def test_constexpr_keeps_python_comparison_and_chain_short_circuit(language):
+ # Before: if X.constexpr(a() < b() < invalid()): ...
+ # Expected builder program: ordinary Python if/chain; the last operand
stays lazy.
seen = []
def operand(index, value):
@@ -227,6 +238,8 @@ def main():
@pytest.mark.parametrize("operator,kind", OPERATORS)
@pytest.mark.parametrize("dtype", ["int64", "float32", "int64x4"])
def test_comparisons_use_native_promotion_and_broadcast(language, operator,
kind, dtype):
+ # Before: x < y (and each comparison), with distinct primitive types.
+ # Expected builder program: X.lt(x, y); native IR owns the cast and
broadcast.
x, y = ir.Var("x", "int32"), ir.Var("y", dtype)
actual = parse(
language,
@@ -241,6 +254,8 @@ def
test_comparisons_use_native_promotion_and_broadcast(language, operator, kind
@pytest.mark.parametrize("operator,kind", [("==", prim.EQ), ("!=", prim.NE)])
@pytest.mark.parametrize("track_span", [True, False])
def test_symbolic_equality_reaches_typed_consumer(language, operator, kind,
track_span):
+ # Before: consume(x == 0), with source tracking enabled or disabled.
+ # Expected builder program: consume(X.eq(x, 0)), with the original
comparison location.
seen = []
def consume(value):
@@ -323,6 +338,8 @@ def
test_host_equality_result_is_not_arbitrarily_converted(language):
"expression", ["operand(0) == operand(1)", "operand(0) == operand(1) !=
operand(2)"]
)
def test_comparison_operands_evaluate_once_in_order(language, expression):
+ # Before: consume(a() == b()) or consume(a() == b() != c()).
+ # Expected builder program: evaluate operands once, then pass concrete
EQ/And IR to consume.
seen = []
def operand(index, value):
diff --git a/tests/python/script/test_parser_host_selection.py
b/tests/python/script/test_parser_host_selection.py
index d133f7888e..21d467f945 100644
--- a/tests/python/script/test_parser_host_selection.py
+++ b/tests/python/script/test_parser_host_selection.py
@@ -26,6 +26,8 @@ def parse(language, source, *, extra_vars=None, **options):
def test_marked_expressions_are_lazy_operand_valued_and_ordered(language):
+ # Before: value if I.constexpr(condition) else other; I.constexpr(a) and b.
+ # Expected builder program: Python conditional/and/or expressions retain
lazy operands.
seen = []
def operand(value):
@@ -49,30 +51,6 @@ def main():
assert [value for _, value in result.body] == [1, 0, 4, 7, 8]
-def test_unmarked_expression_eagerly_constructs_both_ir_arms(language):
- seen = []
-
- def operand(value):
- seen.append(value)
- return value
-
- result = parse(
- language,
- """
[email protected]
-def main(condition: X.value):
- X.record(operand(1) if condition else operand(2))
- X.record(condition and operand(True))
- X.record(condition or operand(False))
-""",
- extra_vars={"operand": operand},
- )
- assert seen == [1, 2, True, False]
- assert result.body[0][1].op == "select"
- assert result.body[1][1].op == "and"
- assert result.body[2][1].op == "or"
-
-
def test_nested_unmarked_statement_retains_ir_frame(language):
result = parse(
language,
@@ -229,6 +207,8 @@ def main():
@pytest.mark.parametrize("operator", ["and", "or"])
def test_unmarked_logical_chain_preserves_left_association(language, operator):
+ # Before: a and b and c (also or).
+ # Expected builder program: X.and_(X.and_(a, b), c).
result = language.parse(f"""
@X.script
def main(a: X.value(), b: X.value(), c: X.value()):
diff --git a/tests/python/script/test_parser_scoped_symbols.py
b/tests/python/script/test_parser_scoped_symbols.py
index dfa219e889..41cb70761e 100644
--- a/tests/python/script/test_parser_scoped_symbols.py
+++ b/tests/python/script/test_parser_scoped_symbols.py
@@ -28,6 +28,9 @@ def parse(language, source, *, extra_vars=None, **options):
@pytest.mark.parametrize("track_span", [True, False])
def
test_signature_symbols_cross_nested_calls_parameters_return_and_body(language,
track_span):
+ # Before: quoted "n" in nested annotations, then n = X.symbol() in the
body.
+ # Expected builder program: annotations use X.resolve_type_var_("n");
+ # n = X.resolve_type_var_("n", "int64") introduces the same object in the
body.
function = parse(
language,
"""
@@ -49,23 +52,6 @@ def main(
assert function.body[0][1] is n
-def
test_signature_strings_reuse_symbol_before_explicit_body_declaration(language):
- function = parse(
- language,
- """
[email protected]
-def main(x: X.tensor(("n + 1", "n"), "float32")):
- n = X.symbol()
- X.record(n)
- return x
-""",
- )
- first, n = function.params[0].args[0].args[0]
- assert first.args[0] is n
- assert first.args[1] == 1
- assert function.body[0][1] is n
-
-
@pytest.mark.parametrize(
"annotation",
[
diff --git
a/tests/python/tirx/script/test_tirx_parser_comparison_integration.py
b/tests/python/tirx/script/test_tirx_parser_comparison_integration.py
index ae5918bfaf..b2f3bbba9d 100644
--- a/tests/python/tirx/script/test_tirx_parser_comparison_integration.py
+++ b/tests/python/tirx/script/test_tirx_parser_comparison_integration.py
@@ -46,18 +46,7 @@ def
test_constexpr_preserves_host_comparison_with_iterator(operator, kind):
calls.append(other)
return result
- setattr(
- Host,
- {
- "LT": "__lt__",
- "LE": "__le__",
- "GT": "__gt__",
- "GE": "__ge__",
- "EQ": "__eq__",
- "NE": "__ne__",
- }[kind],
- compare,
- )
+ setattr(Host, "__" + kind.lower() + "__", compare)
def consume(value):
assert value is result
@@ -114,18 +103,7 @@ def
test_unmarked_host_comparison_never_calls_python_overload(operator, kind):
calls.append(other)
return True
- setattr(
- Host,
- {
- "LT": "__lt__",
- "LE": "__le__",
- "GT": "__gt__",
- "GE": "__ge__",
- "EQ": "__eq__",
- "NE": "__ne__",
- }[kind],
- comparison,
- )
+ setattr(Host, "__" + kind.lower() + "__", comparison)
decorator = "T.prim_func"
statement = "T.evaluate(left " + operator + " right)"
with pytest.raises(TypeError, match="(PrimExpr|primitive|convert|type)"):