From bc17034a67c2ce9cc9169fd85b65bdd2a92db772 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Tue, 14 Jul 2020 13:05:38 +0300 Subject: [PATCH] Fix typing of params ids callable form The previous typing had an object passed to the user, which they can't do anything with without asserting, which is inconvenient. Change it to Any instead. Note that what comes *back* to pytest (the return value) should be an `object`, because we want to handle arbitrary objects without assuming anything about them. --- src/_pytest/fixtures.py | 14 +++++++------- src/_pytest/mark/structures.py | 2 +- src/_pytest/python.py | 11 ++++++----- testing/typing_checks.py | 12 ++++++++++++ 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 8fd56f8ac..b24fc5fd3 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -976,7 +976,7 @@ class FixtureDef(Generic[_FixtureValue]): ids: Optional[ Union[ Tuple[Union[None, str, float, int, bool], ...], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ] = None, ) -> None: @@ -1128,13 +1128,13 @@ def _ensure_immutable_ids( ids: Optional[ Union[ Iterable[Union[None, str, float, int, bool]], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ], ) -> Optional[ Union[ Tuple[Union[None, str, float, int, bool], ...], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ]: if ids is None: @@ -1180,7 +1180,7 @@ class FixtureFunctionMarker: ids = attr.ib( type=Union[ Tuple[Union[None, str, float, int, bool], ...], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ], default=None, converter=_ensure_immutable_ids, @@ -1223,7 +1223,7 @@ def fixture( ids: Optional[ Union[ Iterable[Union[None, str, float, int, bool]], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ] = ..., name: Optional[str] = ... @@ -1241,7 +1241,7 @@ def fixture( # noqa: F811 ids: Optional[ Union[ Iterable[Union[None, str, float, int, bool]], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ] = ..., name: Optional[str] = None @@ -1258,7 +1258,7 @@ def fixture( # noqa: F811 ids: Optional[ Union[ Iterable[Union[None, str, float, int, bool]], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ] = None, name: Optional[str] = None diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index c55e04755..5edeecdd5 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -433,7 +433,7 @@ if TYPE_CHECKING: ids: Optional[ Union[ Iterable[Union[None, str, float, int, bool]], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ] = ..., scope: Optional[_Scope] = ... diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 7209bf1ed..aa8171486 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -11,6 +11,7 @@ from collections import Counter from collections import defaultdict from collections.abc import Sequence from functools import partial +from typing import Any from typing import Callable from typing import Dict from typing import Generator @@ -920,7 +921,7 @@ class Metafunc: ids: Optional[ Union[ Iterable[Union[None, str, float, int, bool]], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ] = None, scope: "Optional[_Scope]" = None, @@ -1040,7 +1041,7 @@ class Metafunc: ids: Optional[ Union[ Iterable[Union[None, str, float, int, bool]], - Callable[[object], Optional[object]], + Callable[[Any], Optional[object]], ] ], parameters: typing.Sequence[ParameterSet], @@ -1226,7 +1227,7 @@ def _idval( val: object, argname: str, idx: int, - idfn: Optional[Callable[[object], Optional[object]]], + idfn: Optional[Callable[[Any], Optional[object]]], nodeid: Optional[str], config: Optional[Config], ) -> str: @@ -1266,7 +1267,7 @@ def _idvalset( idx: int, parameterset: ParameterSet, argnames: Iterable[str], - idfn: Optional[Callable[[object], Optional[object]]], + idfn: Optional[Callable[[Any], Optional[object]]], ids: Optional[List[Union[None, str]]], nodeid: Optional[str], config: Optional[Config], @@ -1287,7 +1288,7 @@ def _idvalset( def idmaker( argnames: Iterable[str], parametersets: Iterable[ParameterSet], - idfn: Optional[Callable[[object], Optional[object]]] = None, + idfn: Optional[Callable[[Any], Optional[object]]] = None, ids: Optional[List[Union[None, str]]] = None, config: Optional[Config] = None, nodeid: Optional[str] = None, diff --git a/testing/typing_checks.py b/testing/typing_checks.py index 94c66ef51..0a6b5ad28 100644 --- a/testing/typing_checks.py +++ b/testing/typing_checks.py @@ -10,3 +10,15 @@ import pytest @pytest.mark.xfail(raises=RuntimeError) def check_mark_xfail_raises() -> None: pass + + +# Issue #7494. +@pytest.fixture(params=[(0, 0), (1, 1)], ids=lambda x: str(x[0])) +def check_fixture_ids_callable() -> None: + pass + + +# Issue #7494. +@pytest.mark.parametrize("func", [str, int], ids=lambda x: str(x.__name__)) +def check_parametrize_ids_callable(func) -> None: + pass