Skip to content

mypy treats enum fields as enum members #16730

@rlazarus

Description

@rlazarus

Bug Report

When Enum members have a field set in the Enum's __init__ method, mypy exhaustiveness checking incorrectly considers that field to be a member of the Enum, and therefore a possible value.

To Reproduce

Using the Planet example from the enum documentation:

https://mypy-play.net/?mypy=1.8.0&python=3.12&gist=8efc534dda9e5cb62e4ff9f7aff7f5e6

from enum import Enum
from typing import assert_never

class Planet(Enum):
    MERCURY = (3.303e+23, 2.4397e6)
    VENUS   = (4.869e+24, 6.0518e6)
    EARTH   = (5.976e+24, 6.37814e6)
    MARS    = (6.421e+23, 3.3972e6)
    JUPITER = (1.9e+27,   7.1492e7)
    SATURN  = (5.688e+26, 6.0268e7)
    URANUS  = (8.686e+25, 2.5559e7)
    NEPTUNE = (1.024e+26, 2.4746e7)
    def __init__(self, mass, radius):
        self.mass = mass       # in kilograms
        self.radius = radius   # in meters

def foo(p: Planet) -> None:
    match p:
        case Planet.MERCURY|Planet.VENUS|Planet.EARTH|Planet.MARS|Planet.JUPITER|Planet.SATURN|Planet.URANUS|Planet.NEPTUNE:
            pass
        case _:
            assert_never(p)  # mypy error here

Expected Behavior

All members of the enum are represented in match cases, so the exhaustiveness check should pass. I expect no mypy errors.

Actual Behavior

main.py:22: error: Argument 1 to "assert_never" has incompatible type "Literal[Planet.mass, Planet.radius]"; expected "NoReturn"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

Planet.mass is not an enum member, so Literal[Planet.mass] is not a possible type for p. In fact, evaluating Planet.mass raises AttributeError. Only an expression like Planet.EARTH.mass is allowed. Same for radius.

Your Environment

  • Mypy version used: 1.8.0
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 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