Skip to content

Commit 7d585ac

Browse files
fix #13031: use the concrete id NOTSET for the empty parameter list (#13073)
* fix #13031: use the concrete id NOTSET for the empty parameter list stand-in this ensures we dont invoke idfunc with the internal NOTSET enum token * Apply suggestions from code review Co-authored-by: Bruno Oliveira <[email protected]> --------- Co-authored-by: Bruno Oliveira <[email protected]>
1 parent 868e1d2 commit 7d585ac

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

changelog/13031.improvement.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
An empty parameter set as in ``pytest.mark.parametrize([], ids=idfunc)`` will no longer trigger a call to ``idfunc`` with internal objects.

src/_pytest/mark/structures.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,18 @@ def get_empty_parameterset_mark(
4747
) -> MarkDecorator:
4848
from ..nodes import Collector
4949

50+
argslisting = ", ".join(argnames)
51+
5052
fs, lineno = getfslineno(func)
51-
reason = f"got empty parameter set {argnames!r}, function {func.__name__} at {fs}:{lineno}"
53+
reason = f"got empty parameter set for ({argslisting})"
5254
requested_mark = config.getini(EMPTY_PARAMETERSET_OPTION)
5355
if requested_mark in ("", None, "skip"):
5456
mark = MARK_GEN.skip(reason=reason)
5557
elif requested_mark == "xfail":
5658
mark = MARK_GEN.xfail(reason=reason, run=False)
5759
elif requested_mark == "fail_at_collect":
58-
f_name = func.__name__
59-
_, lineno = getfslineno(func)
6060
raise Collector.CollectError(
61-
f"Empty parameter set in '{f_name}' at line {lineno + 1}"
61+
f"Empty parameter set in '{func.__name__}' at line {lineno + 1}"
6262
)
6363
else:
6464
raise LookupError(requested_mark)
@@ -181,7 +181,9 @@ def _for_parametrize(
181181
# parameter set with NOTSET values, with the "empty parameter set" mark applied to it.
182182
mark = get_empty_parameterset_mark(config, argnames, func)
183183
parameters.append(
184-
ParameterSet(values=(NOTSET,) * len(argnames), marks=[mark], id=None)
184+
ParameterSet(
185+
values=(NOTSET,) * len(argnames), marks=[mark], id="NOTSET"
186+
)
185187
)
186188
return argnames, parameters
187189

testing/test_mark.py

+26
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,32 @@ def test():
10481048
assert result.ret == ExitCode.INTERRUPTED
10491049

10501050

1051+
def test_paramset_empty_no_idfunc(
1052+
pytester: Pytester, monkeypatch: pytest.MonkeyPatch
1053+
) -> None:
1054+
"""An empty parameter set should not call the user provided id function (#13031)."""
1055+
p1 = pytester.makepyfile(
1056+
"""
1057+
import pytest
1058+
1059+
def idfunc(value):
1060+
raise ValueError()
1061+
@pytest.mark.parametrize("param", [], ids=idfunc)
1062+
def test(param):
1063+
pass
1064+
"""
1065+
)
1066+
result = pytester.runpytest(p1, "-v", "-rs")
1067+
result.stdout.fnmatch_lines(
1068+
[
1069+
"* collected 1 item",
1070+
"test_paramset_empty_no_idfunc* SKIPPED *",
1071+
"SKIPPED [1] test_paramset_empty_no_idfunc.py:5: got empty parameter set for (param)",
1072+
"*= 1 skipped in *",
1073+
]
1074+
)
1075+
1076+
10511077
def test_parameterset_for_parametrize_bad_markname(pytester: Pytester) -> None:
10521078
with pytest.raises(pytest.UsageError):
10531079
test_parameterset_for_parametrize_marks(pytester, "bad")

0 commit comments

Comments
 (0)