From 9289a336f7e292e33790520b9fe1bdf7ed266124 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Sat, 25 Nov 2023 22:32:09 +0000 Subject: [PATCH] Speed up tests by simplifying test fixtures (#16560) Move some definitions away from commonly used fixtures that are only needed in one or two test cases, as they will slow down many test cases. This speeds up `mypy/test/testcheck.py` by about 5% on my Linux desktop. --- test-data/unit/check-class-namedtuple.test | 2 +- test-data/unit/check-expressions.test | 3 +- test-data/unit/check-python310.test | 2 +- test-data/unit/check-tuples.test | 6 ++ test-data/unit/check-type-aliases.test | 2 +- test-data/unit/check-typeddict.test | 4 +- test-data/unit/fixtures/dict-full.pyi | 83 ++++++++++++++++++++++ test-data/unit/fixtures/dict.pyi | 33 ++------- test-data/unit/fixtures/tuple.pyi | 2 - 9 files changed, 102 insertions(+), 35 deletions(-) create mode 100644 test-data/unit/fixtures/dict-full.pyi diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index a095f212b900..f334b9011645 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -301,7 +301,7 @@ reveal_type(X._field_defaults) # N: Revealed type is "builtins.dict[builtins.st # but it's inferred as `Mapping[str, object]` here due to the fixture we're using reveal_type(X.__annotations__) # N: Revealed type is "typing.Mapping[builtins.str, builtins.object]" -[builtins fixtures/dict.pyi] +[builtins fixtures/dict-full.pyi] [case testNewNamedTupleUnit] from typing import NamedTuple diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index 8fe68365e5ac..04b3f7a131cc 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -1589,8 +1589,7 @@ if str(): ....a # E: "ellipsis" has no attribute "a" class A: pass -[builtins fixtures/dict.pyi] -[out] +[builtins fixtures/dict-full.pyi] -- Yield expression diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index d3cdf3af849d..cbb26a130738 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -931,7 +931,7 @@ match x: reveal_type(x) # N: Revealed type is "builtins.list[builtins.list[builtins.dict[builtins.int, builtins.int]]]" reveal_type(y) # N: Revealed type is "builtins.int" reveal_type(z) # N: Revealed type is "builtins.int" -[builtins fixtures/dict.pyi] +[builtins fixtures/dict-full.pyi] [case testMatchNonFinalMatchArgs] class A: diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 4f468b59fc3f..66115ca0c30d 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -957,6 +957,12 @@ for x in B(), A(): [builtins fixtures/for.pyi] [case testTupleIterable] +from typing import Iterable, Optional, TypeVar + +T = TypeVar("T") + +def sum(iterable: Iterable[T], start: Optional[T] = None) -> T: pass + y = 'a' x = sum((1,2)) if int(): diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 46f5ff07f1ac..4364a9bfa9dc 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1065,4 +1065,4 @@ def eval(e: Expr) -> int: return e[1] elif e[0] == 456: return -eval(e[1]) -[builtins fixtures/dict.pyi] +[builtins fixtures/dict-full.pyi] diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index dc808390021a..d8022f85574c 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -2708,7 +2708,7 @@ class TD(TypedDict): reveal_type(TD.__iter__) # N: Revealed type is "def (typing._TypedDict) -> typing.Iterator[builtins.str]" reveal_type(TD.__annotations__) # N: Revealed type is "typing.Mapping[builtins.str, builtins.object]" reveal_type(TD.values) # N: Revealed type is "def (self: typing.Mapping[T`1, T_co`2]) -> typing.Iterable[T_co`2]" -[builtins fixtures/dict.pyi] +[builtins fixtures/dict-full.pyi] [typing fixtures/typing-typeddict.pyi] [case testGenericTypedDictAlias] @@ -3299,7 +3299,7 @@ main:10: error: No overload variant of "__ror__" of "dict" matches argument type main:10: note: Possible overload variants: main:10: note: def __ror__(self, Dict[Any, Any], /) -> Dict[Any, Any] main:10: note: def [T, T2] __ror__(self, Dict[T, T2], /) -> Dict[Union[Any, T], Union[Any, T2]] -[builtins fixtures/dict.pyi] +[builtins fixtures/dict-full.pyi] [typing fixtures/typing-typeddict-iror.pyi] [case testTypedDictWith__ror__method] diff --git a/test-data/unit/fixtures/dict-full.pyi b/test-data/unit/fixtures/dict-full.pyi new file mode 100644 index 000000000000..f20369ce9332 --- /dev/null +++ b/test-data/unit/fixtures/dict-full.pyi @@ -0,0 +1,83 @@ +# Builtins stub used in dictionary-related test cases (more complete). + +from _typeshed import SupportsKeysAndGetItem +import _typeshed +from typing import ( + TypeVar, Generic, Iterable, Iterator, Mapping, Tuple, overload, Optional, Union, Sequence, + Self, +) + +T = TypeVar('T') +T2 = TypeVar('T2') +KT = TypeVar('KT') +VT = TypeVar('VT') + +class object: + def __init__(self) -> None: pass + def __init_subclass__(cls) -> None: pass + def __eq__(self, other: object) -> bool: pass + +class type: + __annotations__: Mapping[str, object] + +class dict(Mapping[KT, VT]): + @overload + def __init__(self, **kwargs: VT) -> None: pass + @overload + def __init__(self, arg: Iterable[Tuple[KT, VT]], **kwargs: VT) -> None: pass + def __getitem__(self, key: KT) -> VT: pass + def __setitem__(self, k: KT, v: VT) -> None: pass + def __iter__(self) -> Iterator[KT]: pass + def __contains__(self, item: object) -> int: pass + def update(self, a: SupportsKeysAndGetItem[KT, VT]) -> None: pass + @overload + def get(self, k: KT) -> Optional[VT]: pass + @overload + def get(self, k: KT, default: Union[VT, T]) -> Union[VT, T]: pass + def __len__(self) -> int: ... + + # This was actually added in 3.9: + @overload + def __or__(self, __value: dict[KT, VT]) -> dict[KT, VT]: ... + @overload + def __or__(self, __value: dict[T, T2]) -> dict[Union[KT, T], Union[VT, T2]]: ... + @overload + def __ror__(self, __value: dict[KT, VT]) -> dict[KT, VT]: ... + @overload + def __ror__(self, __value: dict[T, T2]) -> dict[Union[KT, T], Union[VT, T2]]: ... + # dict.__ior__ should be kept roughly in line with MutableMapping.update() + @overload # type: ignore[misc] + def __ior__(self, __value: _typeshed.SupportsKeysAndGetItem[KT, VT]) -> Self: ... + @overload + def __ior__(self, __value: Iterable[Tuple[KT, VT]]) -> Self: ... + +class int: # for convenience + def __add__(self, x: Union[int, complex]) -> int: pass + def __radd__(self, x: int) -> int: pass + def __sub__(self, x: Union[int, complex]) -> int: pass + def __neg__(self) -> int: pass + real: int + imag: int + +class str: pass # for keyword argument key type +class bytes: pass + +class list(Sequence[T]): # needed by some test cases + def __getitem__(self, x: int) -> T: pass + def __iter__(self) -> Iterator[T]: pass + def __mul__(self, x: int) -> list[T]: pass + def __contains__(self, item: object) -> bool: pass + def append(self, item: T) -> None: pass + +class tuple(Generic[T]): pass +class function: pass +class float: pass +class complex: pass +class bool(int): pass + +class ellipsis: + __class__: object +def isinstance(x: object, t: Union[type, Tuple[type, ...]]) -> bool: pass +class BaseException: pass + +def iter(__iterable: Iterable[T]) -> Iterator[T]: pass diff --git a/test-data/unit/fixtures/dict.pyi b/test-data/unit/fixtures/dict.pyi index 7c0c8767f7d7..ed2287511161 100644 --- a/test-data/unit/fixtures/dict.pyi +++ b/test-data/unit/fixtures/dict.pyi @@ -1,4 +1,7 @@ -# Builtins stub used in dictionary-related test cases. +# Builtins stub used in dictionary-related test cases (stripped down). +# +# NOTE: Use dict-full.pyi if you need more builtins instead of adding here, +# if feasible. from _typeshed import SupportsKeysAndGetItem import _typeshed @@ -14,11 +17,9 @@ VT = TypeVar('VT') class object: def __init__(self) -> None: pass - def __init_subclass__(cls) -> None: pass def __eq__(self, other: object) -> bool: pass -class type: - __annotations__: Mapping[str, object] +class type: pass class dict(Mapping[KT, VT]): @overload @@ -36,28 +37,10 @@ class dict(Mapping[KT, VT]): def get(self, k: KT, default: Union[VT, T]) -> Union[VT, T]: pass def __len__(self) -> int: ... - # This was actually added in 3.9: - @overload - def __or__(self, __value: dict[KT, VT]) -> dict[KT, VT]: ... - @overload - def __or__(self, __value: dict[T, T2]) -> dict[Union[KT, T], Union[VT, T2]]: ... - @overload - def __ror__(self, __value: dict[KT, VT]) -> dict[KT, VT]: ... - @overload - def __ror__(self, __value: dict[T, T2]) -> dict[Union[KT, T], Union[VT, T2]]: ... - # dict.__ior__ should be kept roughly in line with MutableMapping.update() - @overload # type: ignore[misc] - def __ior__(self, __value: _typeshed.SupportsKeysAndGetItem[KT, VT]) -> Self: ... - @overload - def __ior__(self, __value: Iterable[Tuple[KT, VT]]) -> Self: ... - class int: # for convenience def __add__(self, x: Union[int, complex]) -> int: pass def __radd__(self, x: int) -> int: pass def __sub__(self, x: Union[int, complex]) -> int: pass - def __neg__(self) -> int: pass - real: int - imag: int class str: pass # for keyword argument key type class bytes: pass @@ -74,10 +57,8 @@ class function: pass class float: pass class complex: pass class bool(int): pass - -class ellipsis: - __class__: object -def isinstance(x: object, t: Union[type, Tuple[type, ...]]) -> bool: pass +class ellipsis: pass class BaseException: pass +def isinstance(x: object, t: Union[type, Tuple[type, ...]]) -> bool: pass def iter(__iterable: Iterable[T]) -> Iterator[T]: pass diff --git a/test-data/unit/fixtures/tuple.pyi b/test-data/unit/fixtures/tuple.pyi index e270f3d79d3e..cb6347e9f2fd 100644 --- a/test-data/unit/fixtures/tuple.pyi +++ b/test-data/unit/fixtures/tuple.pyi @@ -49,8 +49,6 @@ class list(Sequence[T], Generic[T]): def isinstance(x: object, t: type) -> bool: pass -def sum(iterable: Iterable[T], start: Optional[T] = None) -> T: pass - class BaseException: pass class dict: pass