-
- Notifications
You must be signed in to change notification settings - Fork 3k
Open
Labels
Description
Bug Report, Reproduction, & Actual Behaviour
An enum.Enum
subclass allows a concrete data type and/or mix-in bases. However, if one of the non-Enum
bases contains variables or variable declarations (regardless of whether it is a ClassVar
), mypy thinks that the variable is also an Enum
instance.
from enum import Enum from typing import TYPE_CHECKING, ClassVar, Final, Literal class A: var1 = 1 var2: ClassVar[str] var3: Final[Literal[3]] = 3 var4: Literal["4"] class E(A, Enum): pass if TYPE_CHECKING: reveal_type(E.var1) # mypy: Revealed type is "Literal[E.var1]?" reveal_type(E.var2) # mypy: Revealed type is "Literal[E.var2]?" reveal_type(E.var3) # mypy: Revealed type is "Literal[E.var3]?" reveal_type(E.var4) # mypy: Revealed type is "Literal[E.var4]?" reveal_type(E.var1.value) # mypy: Revealed type is "builtins.int" reveal_type(E.var2.name) # mypy: Revealed type is "Literal['var2']?"
Treating these variables as Enum
instances will fail at runtime:
>>> E.var1.value Traceback (most recent call last): ... AttributeError: 'int' object has no attribute 'value'
Expected Behavior
mypy should act as if E
did not have Enum
as one of the base classes when accessing variables which are inherited from A
:
if TYPE_CHECKING: reveal_type(E.var1) # mypy: Revealed type is "builtins.int" reveal_type(E.var2) # mypy: Revealed type is "builtins.str" reveal_type(E.var3) # mypy: Revealed type is "Literal[3]" reveal_type(E.var4) # mypy: Revealed type is "Literal['4']" reveal_type(E.var1.value) # mypy: "int" has no attribute "value" [attr-defined] \ # mypy: Revealed type is "Any" reveal_type(E.var2.name) # mypy: "str" has no attribute "name" [attr-defined] \ # mypy: Revealed type is "Any"
Your Environment
- Mypy version used: 0.991 & master (see mypy playground snippet)
- Mypy command-line flags: None
- Mypy configuration options from
mypy.ini
(and other config files): None - Python version used: 3.10 & 3.11