@@ -3617,8 +3617,9 @@ def dangerous_comparison(
36173617 self ,
36183618 left : Type ,
36193619 right : Type ,
3620- original_container : Type | None = None ,
36213620 * ,
3621+ original_container : Type | None = None ,
3622+ seen_types : set [tuple [Type , Type ]] | None = None ,
36223623 prefer_literal : bool = True ,
36233624 ) -> bool :
36243625 """Check for dangerous non-overlapping comparisons like 42 == 'no'.
@@ -3639,6 +3640,12 @@ def dangerous_comparison(
36393640 if not self .chk .options .strict_equality :
36403641 return False
36413642
3643+ if seen_types is None :
3644+ seen_types = set ()
3645+ if (left , right ) in seen_types :
3646+ return False
3647+ seen_types .add ((left , right ))
3648+
36423649 left , right = get_proper_types ((left , right ))
36433650
36443651 # We suppress the error if there is a custom __eq__() method on either
@@ -3694,17 +3701,21 @@ def dangerous_comparison(
36943701 abstract_set = self .chk .lookup_typeinfo ("typing.AbstractSet" )
36953702 left = map_instance_to_supertype (left , abstract_set )
36963703 right = map_instance_to_supertype (right , abstract_set )
3697- return self .dangerous_comparison (left .args [0 ], right .args [0 ])
3704+ return self .dangerous_comparison (
3705+ left .args [0 ], right .args [0 ], seen_types = seen_types
3706+ )
36983707 elif left .type .has_base ("typing.Mapping" ) and right .type .has_base ("typing.Mapping" ):
36993708 # Similar to above: Mapping ignores the classes, it just compares items.
37003709 abstract_map = self .chk .lookup_typeinfo ("typing.Mapping" )
37013710 left = map_instance_to_supertype (left , abstract_map )
37023711 right = map_instance_to_supertype (right , abstract_map )
37033712 return self .dangerous_comparison (
3704- left .args [0 ], right .args [0 ]
3705- ) or self .dangerous_comparison (left .args [1 ], right .args [1 ])
3713+ left .args [0 ], right .args [0 ], seen_types = seen_types
3714+ ) or self .dangerous_comparison (left .args [1 ], right .args [1 ], seen_types = seen_types )
37063715 elif left_name in ("builtins.list" , "builtins.tuple" ) and right_name == left_name :
3707- return self .dangerous_comparison (left .args [0 ], right .args [0 ])
3716+ return self .dangerous_comparison (
3717+ left .args [0 ], right .args [0 ], seen_types = seen_types
3718+ )
37083719 elif left_name in OVERLAPPING_BYTES_ALLOWLIST and right_name in (
37093720 OVERLAPPING_BYTES_ALLOWLIST
37103721 ):
0 commit comments