-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed
Labels
Description
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