Skip to content

Commit ba435ac

Browse files
committed
Fix enum attributes are not members
This adds on to the change in #17182 and fixes enum attributes being used as members.
1 parent fb31409 commit ba435ac

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

mypy/typeops.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
)
3131
from mypy.state import state
3232
from mypy.types import (
33-
ENUM_REMOVED_PROPS,
3433
AnyType,
3534
CallableType,
3635
ExtraAttrs,
@@ -878,18 +877,9 @@ class Status(Enum):
878877
return make_simplified_union(items, contract_literals=False)
879878
elif isinstance(typ, Instance) and typ.type.fullname == target_fullname:
880879
if typ.type.is_enum:
881-
new_items = []
882-
for name, symbol in typ.type.names.items():
883-
if not isinstance(symbol.node, Var):
884-
continue
885-
# Skip these since Enum will remove it
886-
if name in ENUM_REMOVED_PROPS:
887-
continue
888-
# Skip private attributes
889-
if name.startswith("__"):
890-
continue
891-
new_items.append(LiteralType(name, typ))
892-
return make_simplified_union(new_items, contract_literals=False)
880+
return make_simplified_union(
881+
[LiteralType(name, typ) for name in typ.get_enum_values()], contract_literals=False
882+
)
893883
elif typ.type.fullname == "builtins.bool":
894884
return make_simplified_union(
895885
[LiteralType(True, typ), LiteralType(False, typ)], contract_literals=False

mypy/types.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,14 @@ def is_singleton_type(self) -> bool:
14961496
def get_enum_values(self) -> list[str]:
14971497
"""Return the list of values for an Enum."""
14981498
return [
1499-
name for name, sym in self.type.names.items() if isinstance(sym.node, mypy.nodes.Var)
1499+
name
1500+
for name, sym in self.type.names.items()
1501+
if (
1502+
isinstance(sym.node, mypy.nodes.Var)
1503+
and name not in ENUM_REMOVED_PROPS
1504+
and not name.startswith("__")
1505+
and sym.node.has_explicit_value
1506+
)
15001507
]
15011508

15021509

test-data/unit/check-python310.test

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,42 @@ def g(m: Medal) -> int:
14841484
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.bronze]"
14851485
return 2
14861486

1487+
1488+
[case testMatchLiteralPatternEnumWithProperty]
1489+
from enum import Enum
1490+
from typing import NoReturn
1491+
def assert_never(x: NoReturn) -> None: ...
1492+
1493+
class int:
1494+
def __new__(cls, value: int): pass
1495+
1496+
class Medal(int, Enum):
1497+
prize: str
1498+
1499+
def __new__(cls, value: int, prize: str) -> Medal:
1500+
enum = int.__new__(cls, value)
1501+
enum._value_ = value
1502+
enum.prize = prize
1503+
return enum
1504+
1505+
gold = (1, 'cash prize')
1506+
silver = (2, 'sponsorship')
1507+
bronze = (3, 'nothing')
1508+
1509+
m: Medal
1510+
1511+
match m:
1512+
case Medal.gold:
1513+
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]"
1514+
case Medal.silver:
1515+
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.silver]"
1516+
case Medal.bronze:
1517+
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.bronze]"
1518+
case _ as unreachable:
1519+
assert_never(unreachable)
1520+
1521+
[builtins fixtures/tuple.pyi]
1522+
14871523
[case testMatchLiteralPatternEnumCustomEquals-skip]
14881524
from enum import Enum
14891525
class Medal(Enum):

0 commit comments

Comments
 (0)