-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
lru_cache annotation doesn't work as a property #5858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@probablyodd well its a bit different. If you set
Edit: Possible adhoc solution: T = TypeVar('T')
def cache(func: Callable[..., T]) -> T:
return functools.lru_cache()(func) # type: ignore
...
@property # type: ignore
@cache
def foo(self) -> dict:
return {} |
Besides @sashgorokhov awesome workaround (that adds some complexity to code) - is there any plan to support this ? |
Taking a look at the actual implementation of import functools
from typing import Any, Callable, TypeVar, Union, no_type_check, overload
RT = TypeVar("RT", bound=Callable[..., Any])
@overload
def lru_cache(
max_size: Callable[..., RT], typed: bool = False
) -> Callable[..., RT]:
...
@overload
def lru_cache(max_size: int, typed: bool = False) -> Callable[[RT], RT]:
...
@overload
def lru_cache(
max_size: Union[Callable[..., RT], int], typed: bool = False
) -> Union[Callable[..., RT], Callable[[RT], RT]]:
...
@no_type_check
def lru_cache(*args, **kwargs):
return functools.lru_cache(*args, **kwargs) This maintains the signature of whatever callable you are decorating, and you should get proper type annotation checks. Credits goes to @sashgorokhov for inspiring to get this solution with his solution above. |
Is this something that should be adjusted in Also @malthunayan I can't seem to get your workaround to work with |
Here's my modified workaround - not sure where your import functools
from typing import Any, Callable, TypeVar, Union, no_type_check, overload, Optional
RT = TypeVar("RT", bound=Callable[..., Any])
@overload
def lru_cache(
maxsize: Callable[..., RT], typed: bool = False
) -> Callable[..., RT]:
...
@overload
def lru_cache(maxsize: Optional[int], typed: bool = False) -> Callable[[RT], RT]:
...
@overload
def lru_cache(
maxsize: Union[Callable[..., RT], Optional[int]], typed: bool = False
) -> Union[Callable[..., RT], Callable[[RT], RT]]:
...
@no_type_check
def lru_cache(*args, **kwargs):
return functools.lru_cache(*args, **kwargs) |
If there is no plan to fix this soon, then can this be documented properly? This error is implicated by the recommendation in the standard library docs for # test_5858.py
import statistics
from functools import cache
class DataSet:
__slots__ = ("_data",)
def __init__(self, sequence_of_numbers):
self._data = sequence_of_numbers
@property # <- error: Decorated property not supported [misc]
@cache # <- results in downstream errors involving type "_lru_cache_wrapper[…]"
def stdev(self):
return statistics.stdev(self._data)
f: float = statistics.stdev(range(10))
f = DataSet(range(10)).stdev % python --version
Python 3.9.10
% mypy --version
mypy 0.941
% mypy --config-file=/dev/null test_5858.py
/dev/null: No [mypy] section in config file
test_5858.py:11: error: Decorated property not supported
test_5858.py:17: error: Incompatible types in assignment (expression has type "_lru_cache_wrapper[Any]", variable has type "float")
Found 2 errors in 1 file (checked 1 source file) |
So I originally reported it in typeshed/#2659 but was told this can't be fixed there and it is mypy limitation so repporting it here.
I have following code:
It works as expected:
Yet, mypy is showing errors:
The
lru_cache
works just fine when decorated as property, and the returned type should beint
and not_lru_cache_wrapper[int]
.This is on python 3.7.0 and mypy 0.641.
The text was updated successfully, but these errors were encountered: