Skip to content

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

Description

@bzoracler

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions