python's TypeVar inference broken when using lru_cache decorator. For example, after applying mypy the following example, only function with lru_cache causes error like:
main.py:14: error: Incompatible types in assignment (expression has type "T", variable has type "int")
Found 1 error in 1 file (checked 1 source file)
and pyright's editor support also warn the same thing. Is this lru_cache's own limitation or is there some good workaround?
from functools import lru_cache
from typing import TypeVar
T = TypeVar("T")
def working(foo: T) -> T:
return foo
@lru_cache(maxsize=None)
def not_working(foo: T) -> T:
return foo
a: int = working(1)
b: int = not_working(1)
Here's the relevant parts of the
lru_cachetype hintsso it appears that, in its attempts to allow for any argument set, it loses any connection between the input and output types and so is unable to refine
Ttoint. You may have to wraplru_cachelocally to fix this. You may be able to useParamSpec, but you might find difficulties with that, see the note below. If you only need it for a small set of function types (unary, binary, ternary), you could wrap it for those.Apparently they did actually fix this with
ParamSpecbut from a cursory reading it appears to break other things so they reverted it. This issue also discusses it.