Skip to content

Commit 9a4e610

Browse files
blueyednicoddemus
andauthored
Revert "[parametrize] enforce explicit argnames declaration (pytest-dev#6330)" (#403)
(cherry picked from commit 010e711) Conflicts: testing/python/metafunc.py Co-authored-by: Bruno Oliveira <[email protected]>
1 parent b3085e1 commit 9a4e610

File tree

6 files changed

+9
-98
lines changed

6 files changed

+9
-98
lines changed

changelog/6909.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Revert the change introduced by `#6330 <https://github.com/pytest-dev/pytest/pull/6330>`_, which required all arguments to ``@pytest.mark.parametrize`` to be explicitly defined in the function signature.
2+
3+
The intention of the original change was to remove what was expected to be an unintended/surprising behavior, but it turns out many people relied on it, so the restriction has been reverted.

doc/en/example/parametrize.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,6 @@ The result of this test will be successful:
398398
399399
.. regendoc:wipe
400400
401-
Note, that each argument in `parametrize` list should be explicitly declared in corresponding
402-
python test function or via `indirect`.
403-
404401
Parametrizing test methods through per-class configuration
405402
--------------------------------------------------------------
406403

src/_pytest/fixtures.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import functools
22
import inspect
3+
import itertools
34
import sys
45
import warnings
56
from collections import defaultdict
@@ -1305,8 +1306,10 @@ def getfixtureinfo(self, node, func, cls, funcargs=True):
13051306
else:
13061307
argnames = ()
13071308

1308-
usefixtures = get_use_fixtures_for_node(node)
1309-
initialnames = usefixtures + argnames
1309+
usefixtures = itertools.chain.from_iterable(
1310+
mark.args for mark in node.iter_markers(name="usefixtures")
1311+
)
1312+
initialnames = tuple(usefixtures) + argnames
13101313
fm = node.session._fixturemanager
13111314
initialnames, names_closure, arg2fixturedefs = fm.getfixtureclosure(
13121315
initialnames, node, ignore_args=self._get_direct_parametrize_args(node)
@@ -1503,12 +1506,3 @@ def _matchfactories(self, fixturedefs, nodeid):
15031506
for fixturedef in fixturedefs:
15041507
if nodes.ischildnode(fixturedef.baseid, nodeid):
15051508
yield fixturedef
1506-
1507-
1508-
def get_use_fixtures_for_node(node) -> Tuple[str, ...]:
1509-
"""Returns the names of all the usefixtures() marks on the given node"""
1510-
return tuple(
1511-
str(name)
1512-
for mark in node.iter_markers(name="usefixtures")
1513-
for name in mark.args
1514-
)

src/_pytest/python.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -947,8 +947,6 @@ def parametrize(
947947

948948
arg_values_types = self._resolve_arg_value_types(argnames, indirect)
949949

950-
self._validate_explicit_parameters(argnames, indirect)
951-
952950
# Use any already (possibly) generated ids with parametrize Marks.
953951
if _param_mark and _param_mark._param_ids_from:
954952
generated_ids = _param_mark._param_ids_from._param_ids_generated
@@ -1121,39 +1119,6 @@ def _validate_if_using_arg_names(
11211119
pytrace=False,
11221120
)
11231121

1124-
def _validate_explicit_parameters(
1125-
self,
1126-
argnames: typing.Sequence[str],
1127-
indirect: Union[bool, typing.Sequence[str]],
1128-
) -> None:
1129-
"""
1130-
The argnames in *parametrize* should either be declared explicitly via
1131-
indirect list or in the function signature
1132-
1133-
:param List[str] argnames: list of argument names passed to ``parametrize()``.
1134-
:param indirect: same ``indirect`` parameter of ``parametrize()``.
1135-
:raise ValueError: if validation fails
1136-
"""
1137-
if isinstance(indirect, bool):
1138-
parametrized_argnames = [] if indirect else argnames
1139-
else:
1140-
parametrized_argnames = [arg for arg in argnames if arg not in indirect]
1141-
1142-
if not parametrized_argnames:
1143-
return
1144-
1145-
funcargnames = _pytest.compat.getfuncargnames(self.function)
1146-
usefixtures = fixtures.get_use_fixtures_for_node(self.definition)
1147-
1148-
for arg in parametrized_argnames:
1149-
if arg not in funcargnames and arg not in usefixtures:
1150-
func_name = self.function.__name__
1151-
msg = (
1152-
'In function "{func_name}":\n'
1153-
'Parameter "{arg}" should be declared explicitly via indirect or in function itself'
1154-
).format(func_name=func_name, arg=arg)
1155-
fail(msg, pytrace=False)
1156-
11571122

11581123
def _find_parametrized_scope(argnames, arg2fixturedefs, indirect):
11591124
"""Find the most appropriate scope for a parametrized call based on its arguments.

testing/python/collect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ def fix3():
495495
return '3'
496496
497497
@pytest.mark.parametrize('fix2', ['2'])
498-
def test_it(fix1, fix2):
498+
def test_it(fix1):
499499
assert fix1 == '21'
500500
assert not fix3_instantiated
501501
"""

testing/python/metafunc.py

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,51 +1925,3 @@ def test_converted_to_str(a, b):
19251925
"*= 6 passed in *",
19261926
]
19271927
)
1928-
1929-
def test_parametrize_explicit_parameters_func(self, testdir: Testdir) -> None:
1930-
testdir.makepyfile(
1931-
"""
1932-
import pytest
1933-
1934-
1935-
@pytest.fixture
1936-
def fixture(arg):
1937-
return arg
1938-
1939-
@pytest.mark.parametrize("arg", ["baz"])
1940-
def test_without_arg(fixture):
1941-
assert "baz" == fixture
1942-
"""
1943-
)
1944-
result = testdir.runpytest()
1945-
result.assert_outcomes(error=1)
1946-
result.stdout.fnmatch_lines(
1947-
[
1948-
'*In function "test_without_arg"*',
1949-
'*Parameter "arg" should be declared explicitly via indirect or in function itself*',
1950-
]
1951-
)
1952-
1953-
def test_parametrize_explicit_parameters_method(self, testdir: Testdir) -> None:
1954-
testdir.makepyfile(
1955-
"""
1956-
import pytest
1957-
1958-
class Test:
1959-
@pytest.fixture
1960-
def test_fixture(self, argument):
1961-
return argument
1962-
1963-
@pytest.mark.parametrize("argument", ["foobar"])
1964-
def test_without_argument(self, test_fixture):
1965-
assert "foobar" == test_fixture
1966-
"""
1967-
)
1968-
result = testdir.runpytest()
1969-
result.assert_outcomes(error=1)
1970-
result.stdout.fnmatch_lines(
1971-
[
1972-
'*In function "test_without_argument"*',
1973-
'*Parameter "argument" should be declared explicitly via indirect or in function itself*',
1974-
]
1975-
)

0 commit comments

Comments
 (0)