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
false positive: functools.lru_cache()
breaks assert_type(..., SomeEnum)
#15851
Comments
@JelleZijlstra, are you sure this one's a typeshed issue? It looks like mypy's revealing the correct type with the |
I minimized it a bit: from __future__ import annotations
import sys
from enum import auto, Enum
from typing import Callable, TypeVar, Generic
_T = TypeVar("_T")
from typing_extensions import assert_type, reveal_type
class SomeEnum(Enum):
A = auto()
B = auto()
class _lru_cache_wrapper(Generic[_T]):
def __call__(self) -> _T:
assert False
def lru_cache(f: Callable[..., _T]) -> _lru_cache_wrapper[_T]:
assert False
@lru_cache
def _inner_method1() -> SomeEnum:
return SomeEnum.A
def method1() -> None:
some_enum: SomeEnum = _inner_method1()
reveal_type(some_enum) # 'SomeEnum'
assert_type(some_enum, SomeEnum) # error
reveal_type(some_enum) # 'SomeEnum' |
(@Akuli: Thanks for this! I'll try to include a minimal reproduction case in any future issues.) |
I wasn't able to repro the issue on mypy playground with @Akuli's minimal repro, but I can with this variation on it (which is also slightly more reduced): from enum import Enum
from typing import Callable, TypeVar
from typing_extensions import assert_type
T = TypeVar("T")
def lru_cache(f: Callable[[], T]) -> Callable[[], T]:
return f
class SomeEnum(Enum):
A = object()
B = object()
def method1() -> None:
some_enum: SomeEnum = _inner_method1()
reveal_type(some_enum) # 'SomeEnum'
assert_type(some_enum, SomeEnum) # error: Expression is of type "Any", not "SomeEnum" [assert-type]
@lru_cache
def _inner_method1() -> SomeEnum:
return SomeEnum.A https://mypy-play.net/?mypy=latest&python=3.11&gist=81326668cbc8056d8f3b44d3396ea0d0 |
Now it is quite the same as `reveal_type`. Which is defined here: https://github.com/python/mypy/blob/2c1fd97986064161c542956bb3d9d5043dc0a480/mypy/checkexpr.py#L4297 Closes #15851
Thanks so much, @sobolevn, @Akuli, @AlexWaygood, @JelleZijlstra (and anyone I may have missed)! |
Bug Report
Interactions between
@functools.lru_cache
andEnum
s confuseassert_type()
, resulting in a false positives.Return values from functions which are decorated by
functools.lru_cache()
and have return typeSomeEnum
are treated asAny
byassert_type()
, while return values from undecorated functions work correctly.In all cases,
reveal_type()
reports the expected values, even asassert_type()
insists the values are of typeAny
.Steps to reproduce
In the following code,
method1()
exhibits the issue while the nearly-identicalmethod2()
does not.This code is also available on mypy-play.net.
diff
A side-by-side diff of the
method1()
andmethod2()
sections:Accessible format of diff
Expected Behavior
Aside from notes arising from use of
reveal_type()
, there should be no mypy output.Actual Behavior
Decorating
_inner_method1()
withfunctools.lru_cache()
causes this issue to manifest. Removing the decoration result in the expected behaviour.After removing notes arising from
reveal_type()
, the output is (mypy 1.4.1, Python 3.11):Your Environment
assert_type()
mypy.ini
(and other config files): (none)The text was updated successfully, but these errors were encountered: