Skip to content

Commit

Permalink
fix #13031: use the concrete id NOTSET for the empty parameter list s…
Browse files Browse the repository at this point in the history
…tand-in

this ensures we dont invoke idfunc with the internal NOTSET enum token
  • Loading branch information
RonnyPfannschmidt committed Dec 21, 2024
1 parent 868e1d2 commit 4dcbbcb
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
2 changes: 2 additions & 0 deletions changelog/13031.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
``pytest.mark.parametrize([], idfunc=...)`` will no longer trigger a call to ``idfunc`` with internal objects.
instead the concrete id ``NOTSET`` is used.
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)

Check warning on line 50 in src/_pytest/mark/structures.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/mark/structures.py#L50

Added line #L50 was not covered by tests

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})"

Check warning on line 53 in src/_pytest/mark/structures.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/mark/structures.py#L53

Added line #L53 was not covered by tests
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
25 changes: 25 additions & 0 deletions testing/test_mark.py
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,31 @@ def test():
assert result.ret == ExitCode.INTERRUPTED


def test_paramset_empty_no_idfunc(
pytester: Pytester, monkeypatch: pytest.MonkeyPatch
) -> None:
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

0 comments on commit 4dcbbcb

Please sign in to comment.