diff --git a/changelog/14619.bugfix.rst b/changelog/14619.bugfix.rst new file mode 100644 index 00000000000..e50fc05dd5f --- /dev/null +++ b/changelog/14619.bugfix.rst @@ -0,0 +1 @@ +Parametrization now reports a clear collection error when a trailing-comma argument receives a non-sequence value, instead of raising an internal ``TypeError``. diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 5449b17a1c6..07c202fb952 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -214,7 +214,16 @@ def _for_parametrize( if parameters: # Check all parameter sets have the correct number of values. for param in parameters: - if len(param.values) != len(argnames): + try: + values_len = len(param.values) + except TypeError: + fail( + f'{nodeid}: in "parametrize" expected a sequence of values, ' + f"got {param.values!r}", + pytrace=False, + ) + + if values_len != len(argnames): msg = ( '{nodeid}: in "parametrize" the number of names ({names_len}):\n' " {names}\n" @@ -227,7 +236,7 @@ def _for_parametrize( values=param.values, names=argnames, names_len=len(argnames), - values_len=len(param.values), + values_len=values_len, ), pytrace=False, ) diff --git a/testing/test_mark.py b/testing/test_mark.py index 253cda94503..78a8c88e7e4 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -495,6 +495,26 @@ def test_func(foo, bar): ) +def test_parametrized_collect_with_non_sequence_value(pytester: Pytester) -> None: + """Test parametrization reports non-sequence values without crashing.""" + py_file = pytester.makepyfile( + """ + import pytest + + @pytest.mark.parametrize("value,", [None]) + def test_func(value): + pass + """ + ) + + result = pytester.runpytest(py_file) + result.stdout.fnmatch_lines( + [ + '*in "parametrize" expected a sequence of values, got None', + ] + ) + + def test_parametrized_with_kwargs(pytester: Pytester) -> None: """Test collect parametrized func with wrong number of args.""" py_file = pytester.makepyfile(