Skip to content

Improved lru_cache which keeps argument types - #3880

Closed
asottile wants to merge 1 commit into
python:masterfrom
asottile:improved_lru_cache
Closed

asottile wants to merge 1 commit into
python:masterfrom
asottile:improved_lru_cache

Conversation

@asottile

Copy link
Copy Markdown
Contributor

see also python/mypy#5107

demo file

from functools import lru_cache

@lru_cache(maxsize=5)
def f(x: int) -> int:
    return 6 * x

reveal_type(f)
reveal_type(f.__wrapped__)
reveal_type(f(1))
f('wat')  # should be an error

before

$ mypy t.py
t.py:7: note: Revealed type is 'functools._lru_cache_wrapper[builtins.int*]'
t.py:8: note: Revealed type is 'def (*Any, **Any) -> builtins.int*'
t.py:9: note: Revealed type is 'builtins.int*'

after

$ mypy --custom-typeshed-dir typeshed t.py
t.py:7: note: Revealed type is 'functools._lru_cache_wrapper[def (x: builtins.int) -> builtins.int]'
t.py:8: note: Revealed type is 'def (x: builtins.int) -> builtins.int'
t.py:9: note: Revealed type is 'builtins.int'
t.py:10: error: Argument 1 to "f" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)

@asottile

Copy link
Copy Markdown
Contributor Author

this also (?) appears to fix generics and lru_cache:

demo

from typing import TypeVar
from functools import lru_cache

T = TypeVar('T')

@lru_cache(maxsize=5)
def f(x: T) -> T: ...

reveal_type(f)
reveal_type(f.__wrapped__)
reveal_type(f(1))
reveal_type(f('wat'))

before

$ mypy t.py
t.py:9: note: Revealed type is 'functools._lru_cache_wrapper[T`-1]'
t.py:10: note: Revealed type is 'def (*Any, **Any) -> T`-1'
t.py:11: note: Revealed type is 'T`-1'
t.py:12: note: Revealed type is 'T`-1'

after

$ mypy t.py --custom-typeshed-dir typeshed
t.py:9: note: Revealed type is 'functools._lru_cache_wrapper[def [T] (x: T`-1) -> T`-1]'
t.py:10: note: Revealed type is 'def [T] (x: T`-1) -> T`-1'
t.py:11: note: Revealed type is 'builtins.int*'
t.py:12: note: Revealed type is 'builtins.str*'

@asottile

Copy link
Copy Markdown
Contributor Author

ah dang, doesn't work for classes:

from functools import lru_cache

class C:
    @lru_cache(maxsize=5)
    def f(self, x: int) -> int: ...

reveal_type(C().f)
reveal_type(C().f(1))
C().f('wat')
$ mypy t.py --custom-typeshed-dir typeshed
t.py:7: note: Revealed type is 'functools._lru_cache_wrapper[def (self: t.C, x: builtins.int) -> builtins.int]'
t.py:8: error: Too few arguments for "f" of "C"
t.py:8: note: Revealed type is 'builtins.int'
t.py:8: error: Argument 1 to "f" of "C" has incompatible type "int"; expected "C"
t.py:9: error: Too few arguments for "f" of "C"
t.py:9: error: Argument 1 to "f" of "C" has incompatible type "str"; expected "C"
Found 4 errors in 1 file (checked 1 source file)

@asottile asottile closed this Mar 23, 2020
@asottile
asottile deleted the improved_lru_cache branch March 23, 2020 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant