From 67e29d2548839ecc6ab91802f746c5fba704ffc2 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Mon, 15 Aug 2022 19:12:12 +0300 Subject: [PATCH] mark: allow any Sequence[str] for parametrize(argnames), not just list/tuple The main motivation for this change is to simplify the type shown in code editors -- `Sequence[str]` is easier to follow than `Union[list[str], tuple[str, ...]]`. It also permits using other types if desired. It might lead to problems if someone uses some oddball sequence type, but hopefully they won't do that. --- changelog/10218.improvement.rst | 5 +++++ src/_pytest/mark/structures.py | 12 ++++++------ src/_pytest/python.py | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 changelog/10218.improvement.rst diff --git a/changelog/10218.improvement.rst b/changelog/10218.improvement.rst new file mode 100644 index 000000000..e00325e25 --- /dev/null +++ b/changelog/10218.improvement.rst @@ -0,0 +1,5 @@ +``@pytest.mark.parametrize()`` (and similar functions) now accepts any ``Sequence[str]`` for the argument names, +instead of just ``list[str]`` and ``tuple[str, ...]``. + +(Note that ``str``, which is itself a ``Sequence[str]``, is still treated as a +comma-delimited name list, as before). diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index b8cbf0d18..800a25c92 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -126,12 +126,12 @@ class ParameterSet(NamedTuple): @staticmethod def _parse_parametrize_args( - argnames: Union[str, List[str], Tuple[str, ...]], + argnames: Union[str, Sequence[str]], argvalues: Iterable[Union["ParameterSet", Sequence[object], object]], *args, **kwargs, - ) -> Tuple[Union[List[str], Tuple[str, ...]], bool]: - if not isinstance(argnames, (tuple, list)): + ) -> Tuple[Sequence[str], bool]: + if isinstance(argnames, str): argnames = [x.strip() for x in argnames.split(",") if x.strip()] force_tuple = len(argnames) == 1 else: @@ -150,12 +150,12 @@ class ParameterSet(NamedTuple): @classmethod def _for_parametrize( cls, - argnames: Union[str, List[str], Tuple[str, ...]], + argnames: Union[str, Sequence[str]], argvalues: Iterable[Union["ParameterSet", Sequence[object], object]], func, config: Config, nodeid: str, - ) -> Tuple[Union[List[str], Tuple[str, ...]], List["ParameterSet"]]: + ) -> Tuple[Sequence[str], List["ParameterSet"]]: argnames, force_tuple = cls._parse_parametrize_args(argnames, argvalues) parameters = cls._parse_parametrize_parameters(argvalues, force_tuple) del argvalues @@ -434,7 +434,7 @@ if TYPE_CHECKING: class _ParametrizeMarkDecorator(MarkDecorator): def __call__( # type: ignore[override] self, - argnames: Union[str, List[str], Tuple[str, ...]], + argnames: Union[str, Sequence[str]], argvalues: Iterable[Union[ParameterSet, Sequence[object], object]], *, indirect: Union[bool, Sequence[str]] = ..., diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 91054f370..3db877506 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1207,7 +1207,7 @@ class Metafunc: def parametrize( self, - argnames: Union[str, List[str], Tuple[str, ...]], + argnames: Union[str, Sequence[str]], argvalues: Iterable[Union[ParameterSet, Sequence[object], object]], indirect: Union[bool, Sequence[str]] = False, ids: Optional[