Skip to content

Commit 2c071a0

Browse files
refactor resolve_arg_value_types
* more explicit type checks * expand from list+tuple to sequence
1 parent 898028c commit 2c071a0

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

src/_pytest/python.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
""" Python test discovery, setup and run of test functions. """
2-
import collections
32
import enum
43
import fnmatch
54
import inspect
65
import os
76
import sys
87
import warnings
8+
from collections import Counter
9+
from collections.abc import Sequence
910
from functools import partial
1011
from textwrap import dedent
1112

@@ -1042,12 +1043,9 @@ def _resolve_arg_value_types(self, argnames, indirect):
10421043
* "params" if the argname should be the parameter of a fixture of the same name.
10431044
* "funcargs" if the argname should be a parameter to the parametrized test function.
10441045
"""
1045-
valtypes = {}
1046-
if indirect is True:
1047-
valtypes = dict.fromkeys(argnames, "params")
1048-
elif indirect is False:
1049-
valtypes = dict.fromkeys(argnames, "funcargs")
1050-
elif isinstance(indirect, (tuple, list)):
1046+
if isinstance(indirect, bool):
1047+
valtypes = dict.fromkeys(argnames, "params" if indirect else "funcargs")
1048+
elif isinstance(indirect, Sequence):
10511049
valtypes = dict.fromkeys(argnames, "funcargs")
10521050
for arg in indirect:
10531051
if arg not in argnames:
@@ -1058,6 +1056,13 @@ def _resolve_arg_value_types(self, argnames, indirect):
10581056
pytrace=False,
10591057
)
10601058
valtypes[arg] = "params"
1059+
else:
1060+
fail(
1061+
"In {func}: expected Sequence or boolean for indirect, got {type}".format(
1062+
type=type(indirect).__name__, func=self.function.__name__
1063+
),
1064+
pytrace=False,
1065+
)
10611066
return valtypes
10621067

10631068
def _validate_if_using_arg_names(self, argnames, indirect):
@@ -1185,7 +1190,7 @@ def idmaker(argnames, parametersets, idfn=None, ids=None, config=None, item=None
11851190
if len(set(ids)) != len(ids):
11861191
# The ids are not unique
11871192
duplicates = [testid for testid in ids if ids.count(testid) > 1]
1188-
counters = collections.defaultdict(lambda: 0)
1193+
counters = Counter()
11891194
for index, testid in enumerate(ids):
11901195
if testid in duplicates:
11911196
ids[index] = testid + str(counters[testid])

testing/python/metafunc.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,17 @@ def func(x, y):
599599
assert metafunc._calls[0].funcargs == dict(x="a", y="b")
600600
assert metafunc._calls[0].params == {}
601601

602+
def test_parametrize_indirect_wrong_type(self):
603+
def func(x, y):
604+
pass
605+
606+
metafunc = self.Metafunc(func)
607+
with pytest.raises(
608+
pytest.fail.Exception,
609+
match="In func: expected Sequence or boolean for indirect, got dict",
610+
):
611+
metafunc.parametrize("x, y", [("a", "b")], indirect={})
612+
602613
def test_parametrize_indirect_list_functional(self, testdir):
603614
"""
604615
#714

0 commit comments

Comments
 (0)