From e426904e089024aadf82ca9410db648351ff9dca Mon Sep 17 00:00:00 2001 From: Mike Ma Date: Wed, 17 Jun 2026 13:06:52 -0500 Subject: [PATCH 1/2] Improve parametrize error for scalar parameter sets Tuple-style parametrization expects each parameter set to be a sequence of values. When a scalar like None was passed, pytest crashed while trying to format the validation error because it called len() on the scalar. Report a normal collection error instead, pointing at the offending test. Tested: PYTHONPATH=src python3 -m pytest testing/test_mark.py::test_parametrized_collect_with_non_sequence_values testing/test_mark.py::test_parametrized_collect_with_wrong_args -q Tested: PYTHONPATH=src python3 -m pytest testing/test_mark.py -q Tested: git diff --check -- src/_pytest/mark/structures.py testing/test_mark.py changelog/14619.bugfix.rst AUTHORS Tested: python3 -m py_compile src/_pytest/mark/structures.py testing/test_mark.py Not-tested: testing/python/metafunc.py because hypothesis is not installed in this environment. Co-authored-by: OpenAI Codex --- AUTHORS | 1 + changelog/14619.bugfix.rst | 1 + src/_pytest/mark/structures.py | 18 ++++++++++++++++-- testing/test_mark.py | 22 ++++++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 changelog/14619.bugfix.rst diff --git a/AUTHORS b/AUTHORS index 972f39aa45e..94a70b16a2e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -333,6 +333,7 @@ Mihail Milushev Mike Fiedler (miketheman) Mike Hoyle (hoylemd) Mike Lundy +Mike Ma Milan Lesnek minbang930 Miro HronĨok diff --git a/changelog/14619.bugfix.rst b/changelog/14619.bugfix.rst new file mode 100644 index 00000000000..6208677f843 --- /dev/null +++ b/changelog/14619.bugfix.rst @@ -0,0 +1 @@ +Fixed a crash in :func:`pytest.mark.parametrize` when a non-sequence value is passed for a parameter set. It now provides a clear error message during collection. diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 5449b17a1c6..875d43d59cf 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -214,7 +214,21 @@ 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: + values_len = None + if values_len is None: + fail( + '{nodeid}: in "parametrize" expected a sequence of values, got {values_type}:\n' + " {values}".format( + nodeid=nodeid, + values=param.values, + values_type=type(param.values).__name__, + ), + pytrace=False, + ) + if values_len != len(argnames): msg = ( '{nodeid}: in "parametrize" the number of names ({names_len}):\n' " {names}\n" @@ -227,7 +241,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..5c8b9f9f967 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -495,6 +495,28 @@ def test_func(foo, bar): ) +def test_parametrized_collect_with_non_sequence_values(pytester: Pytester) -> None: + """Test collect parametrized func with tuple-style argnames and scalar values.""" + py_file = pytester.makepyfile( + """ + import pytest + + @pytest.mark.parametrize("x,", [None]) + def test_func(x): + pass + """ + ) + + result = pytester.runpytest(py_file) + result.stdout.fnmatch_lines( + [ + "test_parametrized_collect_with_non_sequence_values.py::test_func: " + 'in "parametrize" expected a sequence of values, got NoneType:', + " None", + ] + ) + + def test_parametrized_with_kwargs(pytester: Pytester) -> None: """Test collect parametrized func with wrong number of args.""" py_file = pytester.makepyfile( From bc13fe923e5c8fc5e85434ff2973f2c239b37def Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 18:07:59 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/_pytest/mark/structures.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 875d43d59cf..546e258139b 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -220,12 +220,8 @@ def _for_parametrize( values_len = None if values_len is None: fail( - '{nodeid}: in "parametrize" expected a sequence of values, got {values_type}:\n' - " {values}".format( - nodeid=nodeid, - values=param.values, - values_type=type(param.values).__name__, - ), + f'{nodeid}: in "parametrize" expected a sequence of values, got {type(param.values).__name__}:\n' + f" {param.values}", pytrace=False, ) if values_len != len(argnames):