From 89b145a6c6c5e8c9e3dda50501edc4640fdeaaa3 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 20 Feb 2023 14:31:45 +0100 Subject: [PATCH 1/8] Add typing for decorated function arguments in functools.cache() any functools.lru_cache() --- stdlib/functools.pyi | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 8adc3d82292e..02ca5fc67fdc 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -30,6 +30,8 @@ if sys.version_info >= (3, 9): _T = TypeVar("_T") _S = TypeVar("_S") +_P = ParamSpec("_P") + _PWrapped = ParamSpec("_PWrapped") _RWrapped = TypeVar("_RWrapped") _PWrapper = ParamSpec("_PWrapper") @@ -52,25 +54,25 @@ if sys.version_info >= (3, 9): typed: bool @final -class _lru_cache_wrapper(Generic[_T]): - __wrapped__: Callable[..., _T] +class _lru_cache_wrapper(Generic[_P, _T]): + __wrapped__: Callable[_P, _T] def __call__(self, *args: Hashable, **kwargs: Hashable) -> _T: ... 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) -> _lru_cache_wrapper[_P, _T]: ... + def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_P, _T]: ... if sys.version_info >= (3, 8): @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[[Callable[_P, _T]], _lru_cache_wrapper[_P, _T]]: ... @overload - def lru_cache(maxsize: Callable[..., _T], typed: bool = False) -> _lru_cache_wrapper[_T]: ... + def lru_cache(maxsize: Callable[_P, _T], typed: bool = False) -> _lru_cache_wrapper[_P, _T]: ... else: - 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[[Callable[_P, _T]], _lru_cache_wrapper[_P, _T]]: ... if sys.version_info >= (3, 12): WRAPPER_ASSIGNMENTS: tuple[ @@ -208,7 +210,7 @@ if sys.version_info >= (3, 8): 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: Callable[_P, _T]) -> _lru_cache_wrapper[_P, _T]: ... def _make_key( args: tuple[Hashable, ...], From 0a965e2326501cef708f30958c7f8404d59a1f9a Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 20 Feb 2023 14:35:32 +0100 Subject: [PATCH 2/8] Add missing types --- stdlib/functools.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 02ca5fc67fdc..6fbf51eb0ce5 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -56,7 +56,7 @@ if sys.version_info >= (3, 9): @final class _lru_cache_wrapper(Generic[_P, _T]): __wrapped__: Callable[_P, _T] - def __call__(self, *args: Hashable, **kwargs: Hashable) -> _T: ... + def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _T: ... def cache_info(self) -> _CacheInfo: ... def cache_clear(self) -> None: ... if sys.version_info >= (3, 9): From f612ee8dcb8b50775dd67c00e722165c6310ae74 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 20 Feb 2023 15:14:25 +0100 Subject: [PATCH 3/8] Fix instancemethods --- stdlib/functools.pyi | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 6fbf51eb0ce5..d4eb838303f4 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -3,7 +3,7 @@ import types from _typeshed import SupportsAllComparisons, SupportsItems from collections.abc import Callable, Hashable, Iterable, Sequence, Sized from typing import Any, Generic, NamedTuple, TypeVar, overload -from typing_extensions import Literal, ParamSpec, Self, TypeAlias, TypedDict, final +from typing_extensions import Concatenate, Literal, ParamSpec, Self, TypeAlias, TypedDict, final if sys.version_info >= (3, 9): from types import GenericAlias @@ -64,6 +64,19 @@ class _lru_cache_wrapper(Generic[_P, _T]): def __copy__(self) -> _lru_cache_wrapper[_P, _T]: ... def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_P, _T]: ... + @overload + def __get__(self, instance: _S, owner: type[_S]) -> _lru_cache_wrapper_instance[_S, _P, _T]: ... + @overload + def __get__(self, instance: _S, owner: None) -> _lru_cache_wrapper[_P, _T]: ... + +@final +class _lru_cache_wrapper_instance(Generic[_S, _P, _T]): + __wrapped__: Callable[Concatenate[_S, _P], _T] + def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _T: ... + def cache_info(self) -> _CacheInfo: ... + def cache_clear(self) -> None: ... + def __copy__(self) -> _lru_cache_wrapper[Concatenate[_S, _P], _T]: ... + def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[Concatenate[_S, _P], _T]: ... if sys.version_info >= (3, 8): @overload From a942bea3f363abd207921ea1d33c8a161aca20bc Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 20 Feb 2023 15:25:24 +0100 Subject: [PATCH 4/8] fix checher --- stdlib/functools.pyi | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index d4eb838303f4..fdf6ee1b90ad 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -64,19 +64,16 @@ class _lru_cache_wrapper(Generic[_P, _T]): def __copy__(self) -> _lru_cache_wrapper[_P, _T]: ... def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_P, _T]: ... - @overload - def __get__(self, instance: _S, owner: type[_S]) -> _lru_cache_wrapper_instance[_S, _P, _T]: ... - @overload - def __get__(self, instance: _S, owner: None) -> _lru_cache_wrapper[_P, _T]: ... - -@final -class _lru_cache_wrapper_instance(Generic[_S, _P, _T]): - __wrapped__: Callable[Concatenate[_S, _P], _T] - def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _T: ... - def cache_info(self) -> _CacheInfo: ... - def cache_clear(self) -> None: ... - def __copy__(self) -> _lru_cache_wrapper[Concatenate[_S, _P], _T]: ... - def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[Concatenate[_S, _P], _T]: ... + if sys.version_info >= (3, 8): + @overload + def __get__(self, instance: _S, owner: type[_S] = ...) -> Callable[Concatenate[_S, _P], _T]: ... + @overload + def __get__(self, instance: _S, owner: None = ...) -> _lru_cache_wrapper[_P, _T]: ... + else: + @overload + def __get__(self, instance: _S, owner: type[_S]) -> Callable[Concatenate[_S, _P], _T]: ... + @overload + def __get__(self, instance: _S, owner: None) -> _lru_cache_wrapper[_P, _T]: ... if sys.version_info >= (3, 8): @overload From cc45bd5afafe4101ac14550a9e084577c7cb1273 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 20 Feb 2023 15:36:26 +0100 Subject: [PATCH 5/8] fix --- stdlib/functools.pyi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index fdf6ee1b90ad..b205bd506c85 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -66,14 +66,14 @@ class _lru_cache_wrapper(Generic[_P, _T]): def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_P, _T]: ... if sys.version_info >= (3, 8): @overload - def __get__(self, instance: _S, owner: type[_S] = ...) -> Callable[Concatenate[_S, _P], _T]: ... + def __get__(self, __instance: None, __owner: type[_S]|None = ...) -> _lru_cache_wrapper[_P, _T]: ... @overload - def __get__(self, instance: _S, owner: None = ...) -> _lru_cache_wrapper[_P, _T]: ... + def __get__(self, __instance: _S, __owner: type[_S]|None = ...) -> Callable[Concatenate[_S, _P], _T]: ... else: @overload - def __get__(self, instance: _S, owner: type[_S]) -> Callable[Concatenate[_S, _P], _T]: ... + def __get__(self, __instance: None, __owner: type[_S]|None) -> _lru_cache_wrapper[_P, _T]: ... @overload - def __get__(self, instance: _S, owner: None) -> _lru_cache_wrapper[_P, _T]: ... + def __get__(self, __instance: _S, __owner: type[_S]|None) -> Callable[Concatenate[_S, _P], _T]: ... if sys.version_info >= (3, 8): @overload From e591a5b59087d044d5d7da6c6127613a1a810441 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:38:24 +0000 Subject: [PATCH 6/8] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/functools.pyi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index b205bd506c85..828a9d241ab0 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -66,14 +66,14 @@ class _lru_cache_wrapper(Generic[_P, _T]): def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_P, _T]: ... if sys.version_info >= (3, 8): @overload - def __get__(self, __instance: None, __owner: type[_S]|None = ...) -> _lru_cache_wrapper[_P, _T]: ... + def __get__(self, __instance: None, __owner: type[_S] | None = ...) -> _lru_cache_wrapper[_P, _T]: ... @overload - def __get__(self, __instance: _S, __owner: type[_S]|None = ...) -> Callable[Concatenate[_S, _P], _T]: ... + def __get__(self, __instance: _S, __owner: type[_S] | None = ...) -> Callable[Concatenate[_S, _P], _T]: ... else: @overload - def __get__(self, __instance: None, __owner: type[_S]|None) -> _lru_cache_wrapper[_P, _T]: ... + def __get__(self, __instance: None, __owner: type[_S] | None) -> _lru_cache_wrapper[_P, _T]: ... @overload - def __get__(self, __instance: _S, __owner: type[_S]|None) -> Callable[Concatenate[_S, _P], _T]: ... + def __get__(self, __instance: _S, __owner: type[_S] | None) -> Callable[Concatenate[_S, _P], _T]: ... if sys.version_info >= (3, 8): @overload From 89e9326d440b36fd2328533981cd4fa93c12f730 Mon Sep 17 00:00:00 2001 From: jakkdl Date: Mon, 31 Jul 2023 17:47:26 +0200 Subject: [PATCH 7/8] implement suggested change from WMOkiishi --- stdlib/functools.pyi | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 828a9d241ab0..58e01d04c05e 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -31,6 +31,7 @@ if sys.version_info >= (3, 9): _T = TypeVar("_T") _S = TypeVar("_S") _P = ParamSpec("_P") +_Q = ParamSpec("_Q") _PWrapped = ParamSpec("_PWrapped") _RWrapped = TypeVar("_RWrapped") @@ -66,14 +67,22 @@ class _lru_cache_wrapper(Generic[_P, _T]): def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_P, _T]: ... if sys.version_info >= (3, 8): @overload - def __get__(self, __instance: None, __owner: type[_S] | None = ...) -> _lru_cache_wrapper[_P, _T]: ... + def __get__( + self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: None, __owner: type[_S] | None = ... + ) -> Callable[_Q, _T]: ... @overload - def __get__(self, __instance: _S, __owner: type[_S] | None = ...) -> Callable[Concatenate[_S, _P], _T]: ... + def __get__( + self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: _S, __owner: type[_S] | None = ... + ) -> Callable[_Q, _T]: ... else: @overload - def __get__(self, __instance: None, __owner: type[_S] | None) -> _lru_cache_wrapper[_P, _T]: ... + def __get__( + self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: None, __owner: type[_S] | None + ) -> Callable[_Q, _T]: ... @overload - def __get__(self, __instance: _S, __owner: type[_S] | None) -> Callable[Concatenate[_S, _P], _T]: ... + def __get__( + self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: _S, __owner: type[_S] | None + ) -> Callable[_Q, _T]: ... if sys.version_info >= (3, 8): @overload From c179308d4c5d64e8e06425bb79afda0c0e1f3b14 Mon Sep 17 00:00:00 2001 From: jakkdl Date: Mon, 31 Jul 2023 18:15:30 +0200 Subject: [PATCH 8/8] Reverting "implement suggested change from WMOkiishi" to see changes in primer. This reverts commit 89e9326d440b36fd2328533981cd4fa93c12f730. --- stdlib/functools.pyi | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 58e01d04c05e..828a9d241ab0 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -31,7 +31,6 @@ if sys.version_info >= (3, 9): _T = TypeVar("_T") _S = TypeVar("_S") _P = ParamSpec("_P") -_Q = ParamSpec("_Q") _PWrapped = ParamSpec("_PWrapped") _RWrapped = TypeVar("_RWrapped") @@ -67,22 +66,14 @@ class _lru_cache_wrapper(Generic[_P, _T]): def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_P, _T]: ... if sys.version_info >= (3, 8): @overload - def __get__( - self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: None, __owner: type[_S] | None = ... - ) -> Callable[_Q, _T]: ... + def __get__(self, __instance: None, __owner: type[_S] | None = ...) -> _lru_cache_wrapper[_P, _T]: ... @overload - def __get__( - self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: _S, __owner: type[_S] | None = ... - ) -> Callable[_Q, _T]: ... + def __get__(self, __instance: _S, __owner: type[_S] | None = ...) -> Callable[Concatenate[_S, _P], _T]: ... else: @overload - def __get__( - self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: None, __owner: type[_S] | None - ) -> Callable[_Q, _T]: ... + def __get__(self, __instance: None, __owner: type[_S] | None) -> _lru_cache_wrapper[_P, _T]: ... @overload - def __get__( - self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: _S, __owner: type[_S] | None - ) -> Callable[_Q, _T]: ... + def __get__(self, __instance: _S, __owner: type[_S] | None) -> Callable[Concatenate[_S, _P], _T]: ... if sys.version_info >= (3, 8): @overload