ITADN

Spurious comma in `parametrize` causes obfuscated crash

#14619Opencrusaderky 创建于 2026-06-17
C
crusaderkycommented
This is a regression in pytest 9.1. ```python @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: ```python @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'] ```
1 条评论