diff --git a/changelog/5712.feature.rst b/changelog/5712.feature.rst new file mode 100644 index 00000000000..5b4971e4f11 --- /dev/null +++ b/changelog/5712.feature.rst @@ -0,0 +1,2 @@ +Now all arguments to ``@pytest.mark.parametrize`` need to be explicitly declared in the function signature or via ``indirect``. +Previously it was possible to omit an argument if a fixture with the same name existed, which was just an accident of implementation and was not meant to be a part of the API. diff --git a/src/_pytest/python.py b/src/_pytest/python.py index e93c5d2baa0..63db3acf121 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -928,7 +928,7 @@ def parametrize( ids=None, scope=None, *, - _param_mark: Optional[Mark] = None + _param_mark: Optional[Mark] = None, ): """ Add new invocations to the underlying test function using the list of argvalues for the given argnames. Parametrization is performed @@ -998,10 +998,11 @@ def parametrize( scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect) self._validate_if_using_arg_names(argnames, indirect) - self._validate_explicit_parameters(argnames, indirect) arg_values_types = self._resolve_arg_value_types(argnames, indirect) + self._validate_explicit_parameters(argnames, indirect) + # Use any already (possibly) generated ids with parametrize Marks. if _param_mark and _param_mark._param_ids_from: generated_ids = _param_mark._param_ids_from._param_ids_generated @@ -1155,18 +1156,18 @@ def _validate_if_using_arg_names(self, argnames, indirect): def _validate_explicit_parameters(self, argnames, indirect): """ The argnames in *parametrize* should either be declared explicitly via - indirect list or explicitly in the function + indirect list or in the function signature :param List[str] argnames: list of argument names passed to ``parametrize()``. :param indirect: same ``indirect`` parameter of ``parametrize()``. :raise ValueError: if validation fails """ func_name = self.function.__name__ - if type(indirect) is bool and indirect is True: + if isinstance(indirect, bool) and indirect is True: return parametrized_argnames = list() funcargnames = _pytest.compat.getfuncargnames(self.function) - if type(indirect) is list: + if isinstance(indirect, Sequence): for arg in argnames: if arg not in indirect: parametrized_argnames.append(arg)