Skip to content

Commit 43e7401

Browse files
committed
Produce a warning when unknown arguments are passed to pytest.param()
1 parent a9e850f commit 43e7401

File tree

6 files changed

+31
-6
lines changed

6 files changed

+31
-6
lines changed

changelog/5092.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Produce a warning when unknown keywords are passed to ``pytest.param(...)``.

src/_pytest/deprecated.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,9 @@
9393
"pytest.warns() got unexpected keyword arguments: {args!r}.\n"
9494
"This will be an error in future versions.",
9595
)
96+
97+
PYTEST_PARAM_UNKNOWN_KWARGS = UnformattedWarning(
98+
PytestDeprecationWarning,
99+
"pytest.param() got unexpected keyword arguments: {args!r}.\n"
100+
"This will be an error in future versions.",
101+
)

src/_pytest/mark/structures.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ..compat import getfslineno
1111
from ..compat import MappingMixin
1212
from ..compat import NOTSET
13+
from _pytest.deprecated import PYTEST_PARAM_UNKNOWN_KWARGS
1314
from _pytest.outcomes import fail
1415

1516
EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark"
@@ -60,20 +61,25 @@ def get_empty_parameterset_mark(config, argnames, func):
6061

6162
class ParameterSet(namedtuple("ParameterSet", "values, marks, id")):
6263
@classmethod
63-
def param(cls, *values, **kw):
64-
marks = kw.pop("marks", ())
64+
def param(cls, *values, **kwargs):
65+
marks = kwargs.pop("marks", ())
6566
if isinstance(marks, MarkDecorator):
6667
marks = (marks,)
6768
else:
6869
assert isinstance(marks, (tuple, list, set))
6970

70-
id_ = kw.pop("id", None)
71+
id_ = kwargs.pop("id", None)
7172
if id_ is not None:
7273
if not isinstance(id_, six.string_types):
7374
raise TypeError(
7475
"Expected id to be a string, got {}: {!r}".format(type(id_), id_)
7576
)
7677
id_ = ascii_escaped(id_)
78+
79+
if kwargs:
80+
warnings.warn(
81+
PYTEST_PARAM_UNKNOWN_KWARGS.format(args=sorted(kwargs)), stacklevel=3
82+
)
7783
return cls(values, marks, id_)
7884

7985
@classmethod

src/_pytest/outcomes.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ def skip(msg="", **kwargs):
9797
__tracebackhide__ = True
9898
allow_module_level = kwargs.pop("allow_module_level", False)
9999
if kwargs:
100-
keys = [k for k in kwargs.keys()]
101-
raise TypeError("unexpected keyword arguments: {}".format(keys))
100+
raise TypeError("unexpected keyword arguments: {}".format(sorted(kwargs)))
102101
raise Skipped(msg=msg, allow_module_level=allow_module_level)
103102

104103

src/_pytest/python_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ def raises(expected_exception, *args, **kwargs):
682682
match_expr = kwargs.pop("match")
683683
if kwargs:
684684
msg = "Unexpected keyword arguments passed to pytest.raises: "
685-
msg += ", ".join(kwargs.keys())
685+
msg += ", ".join(sorted(kwargs))
686686
raise TypeError(msg)
687687
return RaisesContext(expected_exception, message, match_expr)
688688
elif isinstance(args[0], str):

testing/test_mark.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from _pytest.mark import MarkGenerator as Mark
1414
from _pytest.nodes import Collector
1515
from _pytest.nodes import Node
16+
from _pytest.warning_types import PytestDeprecationWarning
1617
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
1718

1819
try:
@@ -991,3 +992,15 @@ def test_pytest_param_id_requires_string():
991992
@pytest.mark.parametrize("s", (None, "hello world"))
992993
def test_pytest_param_id_allows_none_or_string(s):
993994
assert pytest.param(id=s)
995+
996+
997+
def test_pytest_param_warning_on_unknown_kwargs():
998+
with pytest.warns(PytestDeprecationWarning) as warninfo:
999+
# typo, should be marks=
1000+
pytest.param(1, 2, mark=pytest.mark.xfail())
1001+
assert warninfo[0].filename == __file__
1002+
msg, = warninfo[0].message.args
1003+
assert msg == (
1004+
"pytest.param() got unexpected keyword arguments: ['mark'].\n"
1005+
"This will be an error in future versions."
1006+
)

0 commit comments

Comments
 (0)