Skip to content

Commit 3dd1e5e

Browse files
itscloud0codex
andcommitted
Improve parametrize error for invalid tuple-style values
Closes #14619 Co-authored-by: OpenAI Codex <codex@openai.com>
1 parent 4904d2b commit 3dd1e5e

4 files changed

Lines changed: 56 additions & 4 deletions

File tree

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ Hugo van Kemenade
207207
Hui Wang (coldnight)
208208
Ian Bicking
209209
Ian Lesperance
210+
Ilia Sorokin
210211
Ilya Abdolmanafi
211212
Ilya Konstantinov
212213
Ionuț Turturică

changelog/14619.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved ``parametrize`` collection errors for tuple-style parameter names with invalid scalar values.

src/_pytest/mark/structures.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,28 @@ def _for_parametrize(
213213

214214
if parameters:
215215
# Check all parameter sets have the correct number of values.
216-
for param in parameters:
217-
if len(param.values) != len(argnames):
216+
for i, param in enumerate(parameters):
217+
try:
218+
values_len = len(param.values)
219+
except TypeError:
220+
values_len = None
221+
222+
if values_len is None:
223+
msg = (
224+
'{nodeid}: in "parametrize" the parameter set at index {index} '
225+
"needs to be a sequence, but got {values!r}"
226+
)
227+
fail(
228+
msg.format(nodeid=nodeid, index=i, values=param.values),
229+
pytrace=False,
230+
)
231+
232+
if values_len != len(argnames):
233+
values = (
234+
list(param.values)
235+
if isinstance(param.values, str)
236+
else param.values
237+
)
218238
msg = (
219239
'{nodeid}: in "parametrize" the number of names ({names_len}):\n'
220240
" {names}\n"
@@ -224,10 +244,10 @@ def _for_parametrize(
224244
fail(
225245
msg.format(
226246
nodeid=nodeid,
227-
values=param.values,
247+
values=values,
228248
names=argnames,
229249
names_len=len(argnames),
230-
values_len=len(param.values),
250+
values_len=values_len,
231251
),
232252
pytrace=False,
233253
)

testing/python/metafunc.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,36 @@ def func(arg):
119119
assert metafunc._calls[0].params == {"arg": "a"}
120120
assert metafunc._calls[1].params == {"arg": "b"}
121121

122+
def test_parametrize_trailing_comma_scalar_parameter_set(self) -> None:
123+
def func(arg):
124+
pass # pragma: no cover
125+
126+
metafunc = self.Metafunc(func)
127+
128+
with pytest.raises(fail.Exception) as excinfo:
129+
metafunc.parametrize("arg,", [None])
130+
131+
assert str(excinfo.value) == (
132+
'mock::nodeid: in "parametrize" the parameter set at index 0 '
133+
"needs to be a sequence, but got None"
134+
)
135+
136+
def test_parametrize_string_parameter_set_error_shows_sequence(self) -> None:
137+
def func(arg):
138+
pass # pragma: no cover
139+
140+
metafunc = self.Metafunc(func)
141+
142+
with pytest.raises(fail.Exception) as excinfo:
143+
metafunc.parametrize("arg,", ["foo"])
144+
145+
assert str(excinfo.value) == (
146+
'mock::nodeid: in "parametrize" the number of names (1):\n'
147+
" ['arg']\n"
148+
"must be equal to the number of values (3):\n"
149+
" ['f', 'o', 'o']"
150+
)
151+
122152
def test_parametrize_error(self) -> None:
123153
def func(x, y):
124154
pass

0 commit comments

Comments
 (0)