From fff10587278fef318b44871174c5a9da56eaf684 Mon Sep 17 00:00:00 2001 From: Marc Edwards Date: Sun, 17 Nov 2024 23:23:28 +0000 Subject: [PATCH 1/2] Add type signatures to lru_cache --- stdlib/functools.pyi | 67 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 9957fa8f1634..abd1081aea69 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -2,7 +2,7 @@ import sys import types from _typeshed import SupportsAllComparisons, SupportsItems from collections.abc import Callable, Hashable, Iterable, Sequence, Sized -from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload +from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload, Protocol from typing_extensions import ParamSpec, Self, TypeAlias if sys.version_info >= (3, 9): @@ -30,6 +30,8 @@ if sys.version_info >= (3, 9): _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) _S = TypeVar("_S") +_R = TypeVar("_R") +_P = ParamSpec("_P") _PWrapped = ParamSpec("_PWrapped") _RWrapped = TypeVar("_RWrapped") _PWrapper = ParamSpec("_PWrapper") @@ -51,22 +53,69 @@ if sys.version_info >= (3, 9): maxsize: int typed: bool +class _Function(Protocol[_P, _R]): # type: ignore[misc] # pyright: ignore reportInvalidTypeVarUse + def __call__(self, *args: _P.args, **kwds: _P.kwargs) -> _R: ... + +class _Method(Protocol[_T, _P, _R]): # type: ignore[misc] # pyright: ignore reportInvalidTypeVarUse + def __call__(_self, self: _T, *args: _P.args, **kwds: _P.kwargs) -> _R: ... + +class _Classmethod(Protocol[_T, _P, _R]): # type: ignore[misc] # pyright: ignore reportInvalidTypeVarUse + def __call__(_self, cls: type[_T], *args: _P.args, **kwds: _P.kwargs) -> _R: ... + +_CacheFn: TypeAlias = _lru_cache_wrapper[_Function[_P, _R]] +_CacheMethod: TypeAlias = _lru_cache_wrapper[_Method[_T, _P, _R]] +_CacheClassmethod: TypeAlias = _lru_cache_wrapper[_Classmethod[_T, _P, _R]] +_C = TypeVar("_C", bound=Callable[..., Any]) + @final -class _lru_cache_wrapper(Generic[_T]): - __wrapped__: Callable[..., _T] - def __call__(self, *args: Hashable, **kwargs: Hashable) -> _T: ... +class _lru_cache_wrapper(Generic[_C]): + __wrapped__: _C + + @overload + def __call__( + _self: _CacheMethod[_T, _P, _R], + *args: _P.args, + **kwargs: _P.kwargs + ) -> _R: ... + @overload + def __call__( + _self: _CacheMethod[_T, _P, _R], + self: _T, + *args: _P.args, + **kwargs: _P.kwargs + ) -> _R: ... + @overload + def __call__( + _self: _CacheClassmethod[_T, _P, _R], + *args: _P.args, + **kwargs: _P.kwargs + ) -> _R: ... + @overload + def __call__( + _self: _CacheClassmethod[_T, _P, _R], + cls: type[_T], + *args: _P.args, + **kwargs: _P.kwargs + ) -> _R: ... + @overload + def __call__( + _self: _CacheFn[_P, _R], + *args: _P.args, + **kwargs: _P.kwargs + ) -> _R: ... + def cache_info(self) -> _CacheInfo: ... def cache_clear(self) -> None: ... if sys.version_info >= (3, 9): def cache_parameters(self) -> _CacheParameters: ... - def __copy__(self) -> _lru_cache_wrapper[_T]: ... - def __deepcopy__(self, memo: Any, /) -> _lru_cache_wrapper[_T]: ... + def __copy__(self) -> Self: ... + def __deepcopy__(self, memo: Any, /) -> Self: ... @overload -def lru_cache(maxsize: int | None = 128, typed: bool = False) -> Callable[[Callable[..., _T]], _lru_cache_wrapper[_T]]: ... +def lru_cache(maxsize: int | None = 128, typed: bool = False) -> Callable[[_C], _lru_cache_wrapper[_C]]: ... @overload -def lru_cache(maxsize: Callable[..., _T], typed: bool = False) -> _lru_cache_wrapper[_T]: ... +def lru_cache(maxsize: _C, typed: bool = False) -> _lru_cache_wrapper[_C]: ... if sys.version_info >= (3, 12): WRAPPER_ASSIGNMENTS: tuple[ @@ -199,7 +248,7 @@ class cached_property(Generic[_T_co]): def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... if sys.version_info >= (3, 9): - def cache(user_function: Callable[..., _T], /) -> _lru_cache_wrapper[_T]: ... + def cache(user_function: _C, /) -> _lru_cache_wrapper[_C]: ... def _make_key( args: tuple[Hashable, ...], From 03e550f3ec81544519730fb9804bc58b0535c270 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 00:48:44 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/functools.pyi | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index abd1081aea69..f79d3f44356b 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -2,7 +2,7 @@ import sys import types from _typeshed import SupportsAllComparisons, SupportsItems from collections.abc import Callable, Hashable, Iterable, Sequence, Sized -from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload, Protocol +from typing import Any, Generic, Literal, NamedTuple, Protocol, TypedDict, TypeVar, final, overload from typing_extensions import ParamSpec, Self, TypeAlias if sys.version_info >= (3, 9): @@ -72,38 +72,15 @@ class _lru_cache_wrapper(Generic[_C]): __wrapped__: _C @overload - def __call__( - _self: _CacheMethod[_T, _P, _R], - *args: _P.args, - **kwargs: _P.kwargs - ) -> _R: ... + def __call__(_self: _CacheMethod[_T, _P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... @overload - def __call__( - _self: _CacheMethod[_T, _P, _R], - self: _T, - *args: _P.args, - **kwargs: _P.kwargs - ) -> _R: ... + def __call__(_self: _CacheMethod[_T, _P, _R], self: _T, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... @overload - def __call__( - _self: _CacheClassmethod[_T, _P, _R], - *args: _P.args, - **kwargs: _P.kwargs - ) -> _R: ... + def __call__(_self: _CacheClassmethod[_T, _P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... @overload - def __call__( - _self: _CacheClassmethod[_T, _P, _R], - cls: type[_T], - *args: _P.args, - **kwargs: _P.kwargs - ) -> _R: ... + def __call__(_self: _CacheClassmethod[_T, _P, _R], cls: type[_T], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... @overload - def __call__( - _self: _CacheFn[_P, _R], - *args: _P.args, - **kwargs: _P.kwargs - ) -> _R: ... - + def __call__(_self: _CacheFn[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... def cache_info(self) -> _CacheInfo: ... def cache_clear(self) -> None: ... if sys.version_info >= (3, 9):