From e2967a8beee9e079963ea91a67087ba8fded1d0b Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 27 Feb 2021 20:43:45 -0700 Subject: [PATCH] Eliminated the use of "bare" TypeVars in stdlib stubs (#5041) Eliminated the use of "bare" TypeVars (i.e. a TypeVar that appears only once) within generic methods. While not considered an error in PEP 484, these are a common source of bugs in code, and some type checkers (including pytype and pyright) flag them as errors. Co-authored-by: Eric Traut --- stdlib/_heapq.pyi | 2 +- stdlib/_weakrefset.pyi | 4 ++-- stdlib/builtins.pyi | 4 ++-- stdlib/enum.pyi | 2 +- stdlib/functools.pyi | 2 +- stdlib/gettext.pyi | 2 +- stdlib/heapq.pyi | 4 ++-- stdlib/operator.pyi | 12 ++++++------ stdlib/typing.pyi | 8 ++++---- stubs/aiofiles/aiofiles/threadpool/__init__.pyi | 4 ++-- stubs/cachetools/cachetools/decorators.pyi | 9 +++------ stubs/click/click/termui.pyi | 2 +- stubs/enum34/enum.pyi | 2 +- stubs/mypy-extensions/mypy_extensions.pyi | 4 ++-- stubs/six/six/__init__.pyi | 8 ++++---- stubs/typing-extensions/typing_extensions.pyi | 2 +- 16 files changed, 34 insertions(+), 37 deletions(-) diff --git a/stdlib/_heapq.pyi b/stdlib/_heapq.pyi index 673c03e80..5b14a9de7 100644 --- a/stdlib/_heapq.pyi +++ b/stdlib/_heapq.pyi @@ -3,7 +3,7 @@ from typing import Any, Callable, Iterable, List, Optional, TypeVar _T = TypeVar("_T") -def heapify(__heap: List[_T]) -> None: ... +def heapify(__heap: List[Any]) -> None: ... def heappop(__heap: List[_T]) -> _T: ... def heappush(__heap: List[_T], __item: _T) -> None: ... def heappushpop(__heap: List[_T], __item: _T) -> _T: ... diff --git a/stdlib/_weakrefset.pyi b/stdlib/_weakrefset.pyi index 6f8412464..c369584aa 100644 --- a/stdlib/_weakrefset.pyi +++ b/stdlib/_weakrefset.pyi @@ -23,7 +23,7 @@ class WeakSet(MutableSet[_T], Generic[_T]): def __ior__(self, other: Iterable[_S]) -> WeakSet[Union[_S, _T]]: ... def difference(self: _SelfT, other: Iterable[_T]) -> _SelfT: ... def __sub__(self: _SelfT, other: Iterable[_T]) -> _SelfT: ... - def difference_update(self: _SelfT, other: Iterable[_T]) -> None: ... + def difference_update(self, other: Iterable[_T]) -> None: ... def __isub__(self: _SelfT, other: Iterable[_T]) -> _SelfT: ... def intersection(self: _SelfT, other: Iterable[_T]) -> _SelfT: ... def __and__(self: _SelfT, other: Iterable[_T]) -> _SelfT: ... @@ -38,7 +38,7 @@ class WeakSet(MutableSet[_T], Generic[_T]): def __eq__(self, other: object) -> bool: ... def symmetric_difference(self, other: Iterable[_S]) -> WeakSet[Union[_S, _T]]: ... def __xor__(self, other: Iterable[_S]) -> WeakSet[Union[_S, _T]]: ... - def symmetric_difference_update(self, other: Iterable[_S]) -> None: ... + def symmetric_difference_update(self, other: Iterable[Any]) -> None: ... def __ixor__(self, other: Iterable[_S]) -> WeakSet[Union[_S, _T]]: ... def union(self, other: Iterable[_S]) -> WeakSet[Union[_S, _T]]: ... def __or__(self, other: Iterable[_S]) -> WeakSet[Union[_S, _T]]: ... diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 7512cb947..ca0779db7 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1200,9 +1200,9 @@ def reversed(__sequence: Sequence[_T]) -> Iterator[_T]: ... def reversed(__sequence: Reversible[_T]) -> Iterator[_T]: ... def repr(__obj: object) -> str: ... @overload -def round(number: SupportsRound[_T]) -> int: ... +def round(number: SupportsRound[Any]) -> int: ... @overload -def round(number: SupportsRound[_T], ndigits: None) -> int: ... +def round(number: SupportsRound[Any], ndigits: None) -> int: ... @overload def round(number: SupportsRound[_T], ndigits: int) -> _T: ... def setattr(__obj: Any, __name: str, __value: Any) -> None: ... diff --git a/stdlib/enum.pyi b/stdlib/enum.pyi index 1a1dcf005..6a1710faa 100644 --- a/stdlib/enum.pyi +++ b/stdlib/enum.pyi @@ -13,7 +13,7 @@ _S = TypeVar("_S", bound=Type[Enum]) class EnumMeta(ABCMeta): def __iter__(self: Type[_T]) -> Iterator[_T]: ... def __reversed__(self: Type[_T]) -> Iterator[_T]: ... - def __contains__(self: Type[_T], member: object) -> bool: ... + def __contains__(self: Type[Any], member: object) -> bool: ... def __getitem__(self: Type[_T], name: str) -> _T: ... @property def __members__(self: Type[_T]) -> Mapping[str, _T]: ... diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 0c4d1d2f3..32c65937b 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -123,7 +123,7 @@ if sys.version_info >= (3, 8): @overload def __get__(self, instance: None, owner: Optional[Type[Any]] = ...) -> cached_property[_T]: ... @overload - def __get__(self, instance: _S, owner: Optional[Type[Any]] = ...) -> _T: ... + def __get__(self, instance: object, owner: Optional[Type[Any]] = ...) -> _T: ... def __set_name__(self, owner: Type[Any], name: str) -> None: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... diff --git a/stdlib/gettext.pyi b/stdlib/gettext.pyi index 5624817b1..74a5e56a7 100644 --- a/stdlib/gettext.pyi +++ b/stdlib/gettext.pyi @@ -52,7 +52,7 @@ def translation( domain: str, localedir: Optional[StrPath] = ..., languages: Optional[Iterable[str]] = ..., - class_: Type[_T] = ..., + class_: Type[Any] = ..., fallback: Literal[True] = ..., codeset: Optional[str] = ..., ) -> Any: ... diff --git a/stdlib/heapq.pyi b/stdlib/heapq.pyi index 5592e615f..3d27a30bb 100644 --- a/stdlib/heapq.pyi +++ b/stdlib/heapq.pyi @@ -6,9 +6,9 @@ _T = TypeVar("_T") def heappush(__heap: List[_T], __item: _T) -> None: ... def heappop(__heap: List[_T]) -> _T: ... def heappushpop(__heap: List[_T], __item: _T) -> _T: ... -def heapify(__heap: List[_T]) -> None: ... +def heapify(__heap: List[Any]) -> None: ... def heapreplace(__heap: List[_T], __item: _T) -> _T: ... def merge(*iterables: Iterable[_T], key: Optional[Callable[[_T], Any]] = ..., reverse: bool = ...) -> Iterable[_T]: ... def nlargest(n: int, iterable: Iterable[_T], key: Optional[Callable[[_T], SupportsLessThan]] = ...) -> List[_T]: ... def nsmallest(n: int, iterable: Iterable[_T], key: Optional[Callable[[_T], SupportsLessThan]] = ...) -> List[_T]: ... -def _heapify_max(__x: List[_T]) -> None: ... # undocumented +def _heapify_max(__x: List[Any]) -> None: ... # undocumented diff --git a/stdlib/operator.pyi b/stdlib/operator.pyi index f82d4c667..687de813e 100644 --- a/stdlib/operator.pyi +++ b/stdlib/operator.pyi @@ -86,17 +86,17 @@ def contains(__a: Container[Any], __b: Any) -> bool: ... def __contains__(a: Container[Any], b: Any) -> bool: ... def countOf(__a: Container[Any], __b: Any) -> int: ... @overload -def delitem(__a: MutableSequence[_T], __b: int) -> None: ... +def delitem(__a: MutableSequence[Any], __b: int) -> None: ... @overload -def delitem(__a: MutableSequence[_T], __b: slice) -> None: ... +def delitem(__a: MutableSequence[Any], __b: slice) -> None: ... @overload -def delitem(__a: MutableMapping[_K, _V], __b: _K) -> None: ... +def delitem(__a: MutableMapping[_K, Any], __b: _K) -> None: ... @overload -def __delitem__(a: MutableSequence[_T], b: int) -> None: ... +def __delitem__(a: MutableSequence[Any], b: int) -> None: ... @overload -def __delitem__(a: MutableSequence[_T], b: slice) -> None: ... +def __delitem__(a: MutableSequence[Any], b: slice) -> None: ... @overload -def __delitem__(a: MutableMapping[_K, _V], b: _K) -> None: ... +def __delitem__(a: MutableMapping[_K, Any], b: _K) -> None: ... if sys.version_info < (3,): def delslice(a: MutableSequence[Any], b: int, c: int) -> None: ... diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index 6979f03eb..03aee05e3 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -362,7 +362,7 @@ class MutableSet(AbstractSet[_T], Generic[_T]): def __isub__(self, s: AbstractSet[Any]) -> MutableSet[_T]: ... class MappingView(Sized): - def __init__(self, mapping: Mapping[_KT_co, _VT_co]) -> None: ... # undocumented + def __init__(self, mapping: Mapping[Any, Any]) -> None: ... # undocumented def __len__(self) -> int: ... class ItemsView(MappingView, AbstractSet[Tuple[_KT_co, _VT_co]], Generic[_KT_co, _VT_co]): @@ -381,7 +381,7 @@ class ItemsView(MappingView, AbstractSet[Tuple[_KT_co, _VT_co]], Generic[_KT_co, def __rxor__(self, o: Iterable[_T]) -> Set[Union[Tuple[_KT_co, _VT_co], _T]]: ... class KeysView(MappingView, AbstractSet[_KT_co], Generic[_KT_co]): - def __init__(self, mapping: Mapping[_KT_co, _VT_co]) -> None: ... # undocumented + def __init__(self, mapping: Mapping[_KT_co, Any]) -> None: ... # undocumented def __and__(self, o: Iterable[Any]) -> Set[_KT_co]: ... def __rand__(self, o: Iterable[_T]) -> Set[_T]: ... def __contains__(self, o: object) -> bool: ... @@ -396,7 +396,7 @@ class KeysView(MappingView, AbstractSet[_KT_co], Generic[_KT_co]): def __rxor__(self, o: Iterable[_T]) -> Set[Union[_KT_co, _T]]: ... class ValuesView(MappingView, Iterable[_VT_co], Generic[_VT_co]): - def __init__(self, mapping: Mapping[_KT_co, _VT_co]) -> None: ... # undocumented + def __init__(self, mapping: Mapping[Any, _VT_co]) -> None: ... # undocumented def __contains__(self, o: object) -> bool: ... def __iter__(self) -> Iterator[_VT_co]: ... if sys.version_info >= (3, 8): @@ -661,7 +661,7 @@ class _TypedDict(Mapping[str, object], metaclass=ABCMeta): # can go through. def setdefault(self, k: NoReturn, default: object) -> object: ... # Mypy plugin hook for 'pop' expects that 'default' has a type variable type. - def pop(self, k: NoReturn, default: _T = ...) -> object: ... + def pop(self, k: NoReturn, default: _T = ...) -> object: ... # type: ignore def update(self: _T, __m: _T) -> None: ... def __delitem__(self, k: NoReturn) -> None: ... def items(self) -> ItemsView[str, object]: ... diff --git a/stubs/aiofiles/aiofiles/threadpool/__init__.pyi b/stubs/aiofiles/aiofiles/threadpool/__init__.pyi index bde6ad8a3..dd6480404 100644 --- a/stubs/aiofiles/aiofiles/threadpool/__init__.pyi +++ b/stubs/aiofiles/aiofiles/threadpool/__init__.pyi @@ -1,13 +1,13 @@ from _typeshed import AnyPath, OpenBinaryMode, OpenBinaryModeReading, OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenTextMode from asyncio import AbstractEventLoop -from typing import Any, Callable, Optional, TypeVar, Union, overload +from typing import Any, Callable, Optional, Union, overload from typing_extensions import Literal from ..base import AiofilesContextManager from .binary import AsyncBufferedIOBase, AsyncBufferedReader, AsyncFileIO, _UnknownAsyncBinaryIO from .text import AsyncTextIOWrapper -_OpenFile = TypeVar("_OpenFile", bound=Union[AnyPath, int]) +_OpenFile = Union[AnyPath, int] _Opener = Callable[[str, int], int] # Text mode: always returns AsyncTextIOWrapper diff --git a/stubs/cachetools/cachetools/decorators.pyi b/stubs/cachetools/cachetools/decorators.pyi index 4cd437483..2c3802647 100644 --- a/stubs/cachetools/cachetools/decorators.pyi +++ b/stubs/cachetools/cachetools/decorators.pyi @@ -1,16 +1,13 @@ from typing import Any, Callable, ContextManager, MutableMapping, Optional, TypeVar _KT = TypeVar("_KT") -_VT = TypeVar("_VT") _T = TypeVar("_T", bound=Callable[..., Any]) -_T_co = TypeVar("_T_co", covariant=True) -_T_self = TypeVar("_T_self") def cached( - cache: Optional[MutableMapping[_KT, _VT]], key: Callable[..., _KT] = ..., lock: Optional[ContextManager[_T_co]] = ... + cache: Optional[MutableMapping[_KT, Any]], key: Callable[..., _KT] = ..., lock: Optional[ContextManager[Any]] = ... ) -> Callable[[_T], _T]: ... def cachedmethod( - cache: Callable[[_T_self], Optional[MutableMapping[_KT, _VT]]], + cache: Callable[[Any], Optional[MutableMapping[_KT, Any]]], key: Callable[..., _KT] = ..., - lock: Optional[ContextManager[_T_co]] = ..., + lock: Optional[ContextManager[Any]] = ..., ) -> Callable[[_T], _T]: ... diff --git a/stubs/click/click/termui.pyi b/stubs/click/click/termui.pyi index bb584adbe..fc14a8e3c 100644 --- a/stubs/click/click/termui.pyi +++ b/stubs/click/click/termui.pyi @@ -51,7 +51,7 @@ def progressbar( show_eta: bool = ..., show_percent: Optional[bool] = ..., show_pos: bool = ..., - item_show_func: Optional[Callable[[_T], str]] = ..., + item_show_func: Optional[Callable[[Any], str]] = ..., fill_char: str = ..., empty_char: str = ..., bar_template: str = ..., diff --git a/stubs/enum34/enum.pyi b/stubs/enum34/enum.pyi index 1a1dcf005..4bc061d1c 100644 --- a/stubs/enum34/enum.pyi +++ b/stubs/enum34/enum.pyi @@ -13,7 +13,7 @@ _S = TypeVar("_S", bound=Type[Enum]) class EnumMeta(ABCMeta): def __iter__(self: Type[_T]) -> Iterator[_T]: ... def __reversed__(self: Type[_T]) -> Iterator[_T]: ... - def __contains__(self: Type[_T], member: object) -> bool: ... + def __contains__(self, member: object) -> bool: ... def __getitem__(self: Type[_T], name: str) -> _T: ... @property def __members__(self: Type[_T]) -> Mapping[str, _T]: ... diff --git a/stubs/mypy-extensions/mypy_extensions.pyi b/stubs/mypy-extensions/mypy_extensions.pyi index e5df53ff7..11a1fed9c 100644 --- a/stubs/mypy-extensions/mypy_extensions.pyi +++ b/stubs/mypy-extensions/mypy_extensions.pyi @@ -12,7 +12,7 @@ class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): # can go through. def setdefault(self, k: NoReturn, default: object) -> object: ... # Mypy plugin hook for 'pop' expects that 'default' has a type variable type. - def pop(self, k: NoReturn, default: _T = ...) -> object: ... + def pop(self, k: NoReturn, default: _T = ...) -> object: ... # type: ignore def update(self: _T, __m: _T) -> None: ... if sys.version_info < (3, 0): def has_key(self, k: str) -> bool: ... @@ -25,7 +25,7 @@ class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): def values(self) -> ValuesView[object]: ... def __delitem__(self, k: NoReturn) -> None: ... -def TypedDict(typename: str, fields: Dict[str, Type[_T]], total: bool = ...) -> Type[Dict[str, Any]]: ... +def TypedDict(typename: str, fields: Dict[str, Type[Any]], total: bool = ...) -> Type[Dict[str, Any]]: ... def Arg(type: _T = ..., name: Optional[str] = ...) -> _T: ... def DefaultArg(type: _T = ..., name: Optional[str] = ...) -> _T: ... def NamedArg(type: _T = ..., name: Optional[str] = ...) -> _T: ... diff --git a/stubs/six/six/__init__.pyi b/stubs/six/six/__init__.pyi index bd055bbca..80b21672d 100644 --- a/stubs/six/six/__init__.pyi +++ b/stubs/six/six/__init__.pyi @@ -61,14 +61,14 @@ def get_function_closure(fun: types.FunctionType) -> Optional[Tuple[types._Cell, def get_function_code(fun: types.FunctionType) -> types.CodeType: ... def get_function_defaults(fun: types.FunctionType) -> Optional[Tuple[Any, ...]]: ... def get_function_globals(fun: types.FunctionType) -> Dict[str, Any]: ... -def iterkeys(d: Mapping[_K, _V]) -> typing.Iterator[_K]: ... -def itervalues(d: Mapping[_K, _V]) -> typing.Iterator[_V]: ... +def iterkeys(d: Mapping[_K, Any]) -> typing.Iterator[_K]: ... +def itervalues(d: Mapping[Any, _V]) -> typing.Iterator[_V]: ... def iteritems(d: Mapping[_K, _V]) -> typing.Iterator[Tuple[_K, _V]]: ... # def iterlists -def viewkeys(d: Mapping[_K, _V]) -> KeysView[_K]: ... -def viewvalues(d: Mapping[_K, _V]) -> ValuesView[_V]: ... +def viewkeys(d: Mapping[_K, Any]) -> KeysView[_K]: ... +def viewvalues(d: Mapping[Any, _V]) -> ValuesView[_V]: ... def viewitems(d: Mapping[_K, _V]) -> ItemsView[_K, _V]: ... def b(s: str) -> binary_type: ... def u(s: str) -> text_type: ... diff --git a/stubs/typing-extensions/typing_extensions.pyi b/stubs/typing-extensions/typing_extensions.pyi index f103a0faf..3ca636af8 100644 --- a/stubs/typing-extensions/typing_extensions.pyi +++ b/stubs/typing-extensions/typing_extensions.pyi @@ -51,7 +51,7 @@ class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): # can go through. def setdefault(self, k: NoReturn, default: object) -> object: ... # Mypy plugin hook for 'pop' expects that 'default' has a type variable type. - def pop(self, k: NoReturn, default: _T = ...) -> object: ... + def pop(self, k: NoReturn, default: _T = ...) -> object: ... # type: ignore def update(self: _T, __m: _T) -> None: ... if sys.version_info < (3, 0): def has_key(self, k: str) -> bool: ...