Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/13031.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
An empty parameter set as in ``pytest.mark.parametrize([], ids=idfunc)`` will no longer trigger a call to ``idfunc`` with internal objects.
12 changes: 7 additions & 5 deletions src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ def get_empty_parameterset_mark(
) -> MarkDecorator:
from ..nodes import Collector

argslisting = ", ".join(argnames)

fs, lineno = getfslineno(func)
reason = f"got empty parameter set {argnames!r}, function {func.__name__} at {fs}:{lineno}"
reason = f"got empty parameter set for ({argslisting})"
requested_mark = config.getini(EMPTY_PARAMETERSET_OPTION)
if requested_mark in ("", None, "skip"):
mark = MARK_GEN.skip(reason=reason)
elif requested_mark == "xfail":
mark = MARK_GEN.xfail(reason=reason, run=False)
elif requested_mark == "fail_at_collect":
f_name = func.__name__
_, lineno = getfslineno(func)
raise Collector.CollectError(
f"Empty parameter set in '{f_name}' at line {lineno + 1}"
f"Empty parameter set in '{func.__name__}' at line {lineno + 1}"
)
else:
raise LookupError(requested_mark)
Expand Down Expand Up @@ -181,7 +181,9 @@ def _for_parametrize(
# parameter set with NOTSET values, with the "empty parameter set" mark applied to it.
mark = get_empty_parameterset_mark(config, argnames, func)
parameters.append(
ParameterSet(values=(NOTSET,) * len(argnames), marks=[mark], id=None)
ParameterSet(
values=(NOTSET,) * len(argnames), marks=[mark], id="NOTSET"
)
)
return argnames, parameters

Expand Down
26 changes: 26 additions & 0 deletions testing/test_mark.py
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,32 @@ def test():
assert result.ret == ExitCode.INTERRUPTED


def test_paramset_empty_no_idfunc(
pytester: Pytester, monkeypatch: pytest.MonkeyPatch
) -> None:
"""An empty parameter set should not call the user provided id function (#13031)."""
p1 = pytester.makepyfile(
"""
import pytest

def idfunc(value):
raise ValueError()
@pytest.mark.parametrize("param", [], ids=idfunc)
def test(param):
pass
"""
)
result = pytester.runpytest(p1, "-v", "-rs")
result.stdout.fnmatch_lines(
[
"* collected 1 item",
"test_paramset_empty_no_idfunc* SKIPPED *",
"SKIPPED [1] test_paramset_empty_no_idfunc.py:5: got empty parameter set for (param)",
"*= 1 skipped in *",
]
)


def test_parameterset_for_parametrize_bad_markname(pytester: Pytester) -> None:
with pytest.raises(pytest.UsageError):
test_parameterset_for_parametrize_marks(pytester, "bad")
Expand Down