Skip to content

Spurious comma in parametrize causes obfuscated crash #14619

@crusaderky

Description

@crusaderky

This is a regression in pytest 9.1.

@pytest.mark.parametrize("x,", [None, "foo", "bar"])  # Spurious comma after parameter name
def test1(x):
    pass

output:

________________________________________________________________ ERROR collecting test.py ________________________________________________________________
.pixi/envs/py314/lib/python3.14/site-packages/pluggy/_hooks.py:512: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.pixi/envs/py314/lib/python3.14/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.pixi/envs/py314/lib/python3.14/site-packages/_pytest/python.py:250: in pytest_pycollect_makeitem
    return list(collector._genfunctions(name, obj))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.pixi/envs/py314/lib/python3.14/site-packages/_pytest/python.py:476: in _genfunctions
    self.ihook.pytest_generate_tests.call_extra(methods, dict(metafunc=metafunc))
.pixi/envs/py314/lib/python3.14/site-packages/pluggy/_hooks.py:573: in call_extra
    return self._hookexec(self.name, hookimpls, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.pixi/envs/py314/lib/python3.14/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.pixi/envs/py314/lib/python3.14/site-packages/_pytest/python.py:124: in pytest_generate_tests
    metafunc.parametrize(*marker.args, **marker.kwargs, _param_mark=marker)
.pixi/envs/py314/lib/python3.14/site-packages/_pytest/python.py:1316: in parametrize
    argnames, parametersets = ParameterSet._for_parametrize(
.pixi/envs/py314/lib/python3.14/site-packages/_pytest/mark/structures.py:218: in _for_parametrize
    if len(param.values) != len(argnames):
       ^^^^^^^^^^^^^^^^^
E   TypeError: object of type 'NoneType' has no len()

As there is no hint as to where the offending test is, the only way to find it is to bisect the whole module.

If the first value is a string, pytest cleanly points at the offending test, but IMHO the error message is improvable as it could better clarify that it's treating the first string as a sequence:

@pytest.mark.parametrize("x,", ["foo", "bar"])
def test1(x):
    pass

output:

test.py::test1: in "parametrize" the number of names (1):
  ['x']
must be equal to the number of values (3):
  foo

suggested output:

test.py::test1: in "parametrize" the number of names (1):
  ['x']
must be equal to the number of values (3):
  ['f', 'o', 'o']

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions