Skip to content

Enum types are incorrectly inferred #19334

Open
@ivany4

Description

@ivany4

Bug Report

mypy does not infer enum values correctly. E.g. It would be reasonable to expect that IntEnum subclasses have their raw values as ints. Instead, mypy detects it as a literal of whatever it sees. This is especially a problem for *.pyi stubs, where options are assigned ellipsis.

In addition, Python documentation allows specifying special _value_ attribute, that type-checkers should use to infer the raw value type. E.g. they even have a snippet:

class ColumnType(Enum):
    _value_: int
    DORIC = ...
    IONIC = ...
    CORINTHIAN = ...

reveal_type(ColumnType.DORIC.value)  # Revealed type is int (or object or Any)

To Reproduce

import enum
import typing

class Simple(enum.IntEnum):
    OPTION = ...

class WithValue(enum.IntEnum):
    _value_: int
    OPTION = ...

class WithDirectValue(enum.IntEnum):
    _value_: int
    OPTION = 2

class NonInt(enum.Enum):
    _value_: str
    OPTION = "str"

typing.reveal_type(Simple.OPTION)
typing.reveal_type(Simple.OPTION.value)
typing.reveal_type(WithValue.OPTION)
typing.reveal_type(WithValue.OPTION.value)
typing.reveal_type(WithDirectValue.OPTION)
typing.reveal_type(WithDirectValue.OPTION.value)
typing.reveal_type(NonInt.OPTION)
typing.reveal_type(NonInt.OPTION.value)

GIST: https://gist.github.com/mypy-play/18540009e25f31525cd1b872ca2a252c

Expected Behavior

The output is:

note: Revealed type is "Literal[Simple.OPTION]?"
note: Revealed type is "int"
note: Revealed type is "Literal[WithValue.OPTION]?"
note: Revealed type is "int"
note: Revealed type is "Literal[WithDirectValue.OPTION]?"
note: Revealed type is "int"
note: Revealed type is "Literal[NonInt.OPTION]?"
note: Revealed type is "str"

Actual Behavior

The output is:

note: Revealed type is "Literal[Simple.OPTION]?"
note: Revealed type is "types.EllipsisType"
note: Revealed type is "Literal[WithValue.OPTION]?"
note: Revealed type is "types.EllipsisType"
note: Revealed type is "Literal[WithDirectValue.OPTION]?"
note: Revealed type is "Literal[2]?"
note: Revealed type is "Literal[NonInt.OPTION]?"
note: Revealed type is "Literal['str']?"

Your Environment

  • Mypy version used: 1.16.1
  • Mypy command-line flags: mypy file.py
  • Python version used: 3.11.11 (but Gist is also at Python 3.12)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions