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']
This is a regression in pytest 9.1.
output:
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:
output:
suggested output: