Skip to content
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

Non-Enum base class variables are interpreted as Enum instances #14600

Open
bzoracler opened this issue Feb 3, 2023 · 0 comments
Open

Non-Enum base class variables are interpreted as Enum instances #14600

bzoracler opened this issue Feb 3, 2023 · 0 comments
Labels
bug mypy got something wrong

Comments

@bzoracler
Copy link
Contributor

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
@bzoracler bzoracler added the bug mypy got something wrong label Feb 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

1 participant