From 0297c2e7ed11f79f8c7dded0d29a7a9e2be5f81b Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Thu, 8 Jan 2026 23:25:12 +0200 Subject: [PATCH] [functools] Allow method override with `@cache` decorator Signed-off-by: Emmanuel Ferdman --- stdlib/@tests/test_cases/check_functools.py | 14 +++++++++++++- stdlib/functools.pyi | 10 +++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/stdlib/@tests/test_cases/check_functools.py b/stdlib/@tests/test_cases/check_functools.py index 47b6bb77c25d..a25c0111adf9 100644 --- a/stdlib/@tests/test_cases/check_functools.py +++ b/stdlib/@tests/test_cases/check_functools.py @@ -1,6 +1,6 @@ from __future__ import annotations -from functools import cached_property, wraps +from functools import cache, cached_property, wraps from typing import Callable, TypeVar from typing_extensions import ParamSpec, assert_type @@ -96,3 +96,15 @@ class Y(X): @cached_property def some(self) -> Child: # safe override return Child() + + +class CachedParent: + @cache + def method(self) -> Parent: + return Parent() + + +class CachedChild(CachedParent): + @cache + def method(self) -> Child: + return Child() diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 47baf917294d..52d0d0958134 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -54,14 +54,14 @@ class _CacheParameters(TypedDict): typed: bool @final -class _lru_cache_wrapper(Generic[_T]): - __wrapped__: Callable[..., _T] - def __call__(self, *args: Hashable, **kwargs: Hashable) -> _T: ... +class _lru_cache_wrapper(Generic[_T_co]): + __wrapped__: Callable[..., _T_co] + def __call__(self, *args: Hashable, **kwargs: Hashable) -> _T_co: ... def cache_info(self) -> _CacheInfo: ... def cache_clear(self) -> None: ... 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[_T_co]: ... + def __deepcopy__(self, memo: Any, /) -> _lru_cache_wrapper[_T_co]: ... @overload def lru_cache(maxsize: int | None = 128, typed: bool = False) -> Callable[[Callable[..., _T]], _lru_cache_wrapper[_T]]: ...