diff --git a/mypy/checker.py b/mypy/checker.py index 212ddd65d912..e3cd08cdee94 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -6858,9 +6858,13 @@ def comparison_type_narrowing_helper(self, node: ComparisonExpr) -> tuple[TypeMa for known_item in container_item_types: # Match the should_coerce_literals logic from narrow_type_by_identity_equality p_known_item = get_proper_type(known_item) - if is_literal_type_like(p_known_item) or ( - isinstance(p_known_item, Instance) and p_known_item.type.is_enum - ): + if ( + is_literal_type_like(p_known_item) + or ( + isinstance(p_known_item, Instance) + and p_known_item.type.is_enum + ) + ) and not has_custom_eq_checks(p_known_item): known_item = coerce_to_literal(known_item) if_map, else_map = self.narrow_type_by_identity_equality( "==", diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 7bab7baa6ceb..29f4cd47929d 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -3335,6 +3335,24 @@ def narrow_dict(x: Literal['a', 'b', 'c'], t: dict[Literal['a', 'b'], int]): [builtins fixtures/primitives.pyi] +[case testNarrowCustomEqEnumInLiteralContainer] +# flags: --strict-equality --warn-unreachable +# https://github.com/python/mypy/issues/21703 +from enum import Enum + +class E(Enum): + foo = 1 + bar = 2 + + def __eq__(self, other: object) -> bool: + return True + +def f(x: int) -> None: + if x in [E.foo, E.bar]: + reveal_type(x) # N: Revealed type is "builtins.int" +[builtins fixtures/list.pyi] + + [case testNarrowingLiteralInLiteralContainer] # flags: --strict-equality --warn-unreachable from typing import Literal