You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
functools.lru_cache doesn't work with generic functions #1515
fromtypingimportTypeVarimportfunctoolsT=TypeVar('T')
@functools.lru_cache()deff(x: T) ->T: passreveal_type(f) # E: Revealed type is 'functools._lru_cache_wrapper[T`-1]'reveal_type(f(1)) # E: Revealed type is 'T`-1'
These types are wrong: types are not allowed to contain unbound type variables.
There isn't really a clearly correct thing to do here though. The stubs for lru_cache are defined in a way that does not retain the relationship between the input and output types of the function being decorated. Options here include
Find a way to retain the entire Callable type of the decorated function while having the result of lru_cache's __call__ simultaneously be an instance of _lru_cache_wrapper. As far as I can tell, this is currently impossible, but would be the ideal long-term outcome.
Give up on _lru_cache_wrapper and CacheInfo (for now?) and just give lru_cache the type
Have mypy infer the type _lru_cache_wrapper[Any] for this f on the grounds that the type variable _T is undetermined. But normally in this situation (where an undetermined type variable appears in an inferred type) mypy either uses 'None' or complains about being unable to infer a type. What makes this case special?
This kind of situation occurs in stdlib-samples/3.2/fnmatch.py:
Activity
JukkaL commentedon May 10, 2016
Interestingly, this is an example where intersection types would be useful. We could annotate
lru_cachelike this:ilevkivskyi commentedon May 18, 2018
I think this is a duplicate of #1317