Skip to content

Commit ab3ed33

Browse files
committed
Fix enum comparison with literal values
1 parent 64dff42 commit ab3ed33

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

mypy/meet.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,12 @@ def _type_object_overlap(left: Type, right: Type) -> bool:
547547
right = right.fallback
548548

549549
if isinstance(left, LiteralType) and isinstance(right, LiteralType):
550-
if left.value == right.value:
550+
if left.value == right.value or (left.fallback.type.is_enum ^ right.fallback.type.is_enum):
551551
# If values are the same, we still need to check if fallbacks are overlapping,
552552
# this is done below.
553+
# Enums are more interesting:
554+
# * if both sides are enums, they should have same values
555+
# * if exactly one of them is a enum, fallback compatibibility is enough
553556
left = left.fallback
554557
right = right.fallback
555558
else:

test-data/unit/check-enum.test

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,3 +2681,50 @@ reveal_type(Wrapper.Nested.FOO) # N: Revealed type is "Literal[__main__.Wrapper
26812681
reveal_type(Wrapper.Nested.FOO.value) # N: Revealed type is "builtins.ellipsis"
26822682
reveal_type(Wrapper.Nested.FOO._value_) # N: Revealed type is "builtins.ellipsis"
26832683
[builtins fixtures/enum.pyi]
2684+
2685+
[case testEnumItemsEqualityToLiterals]
2686+
# flags: --python-version=3.11 --strict-equality
2687+
from enum import Enum, StrEnum, IntEnum
2688+
2689+
class A(str, Enum):
2690+
a = "b"
2691+
b = "a"
2692+
2693+
A.a == "a"
2694+
A.a == "b"
2695+
2696+
A.a == A.a
2697+
A.a == A.b # E: Non-overlapping equality check (left operand type: "Literal[A.a]", right operand type: "Literal[A.b]")
2698+
2699+
class B(StrEnum):
2700+
a = "b"
2701+
b = "a"
2702+
2703+
B.a == "a"
2704+
B.a == "b"
2705+
2706+
B.a == B.a
2707+
B.a == B.b # E: Non-overlapping equality check (left operand type: "Literal[B.a]", right operand type: "Literal[B.b]")
2708+
2709+
B.a == A.a # E: Non-overlapping equality check (left operand type: "Literal[B.a]", right operand type: "Literal[A.a]")
2710+
2711+
class C(IntEnum):
2712+
a = 0
2713+
2714+
C.a == "a" # E: Non-overlapping equality check (left operand type: "Literal[C.a]", right operand type: "Literal['a']")
2715+
C.a == "b" # E: Non-overlapping equality check (left operand type: "Literal[C.a]", right operand type: "Literal['b']")
2716+
2717+
C.a == C.a
2718+
C.a == C.b
2719+
2720+
class D(int, Enum):
2721+
a = 0
2722+
2723+
D.a == "a" # E: Non-overlapping equality check (left operand type: "Literal[D.a]", right operand type: "Literal['a']")
2724+
D.a == "b" # E: Non-overlapping equality check (left operand type: "Literal[D.a]", right operand type: "Literal['b']")
2725+
2726+
D.a == D.a
2727+
D.a == D.b
2728+
2729+
D.a == C.a # E: Non-overlapping equality check (left operand type: "Literal[D.a]", right operand type: "Literal[C.a]")
2730+
[builtins fixtures/dict.pyi]

0 commit comments

Comments
 (0)