@@ -2988,20 +2988,14 @@ def visit_comparison_expr(self, e: ComparisonExpr) -> Type:
2988
2988
# testCustomEqCheckStrictEquality for an example.
2989
2989
if not w .has_new_errors () and operator in ("==" , "!=" ):
2990
2990
right_type = self .accept (right )
2991
- # We suppress the error if there is a custom __eq__() method on either
2992
- # side. User defined (or even standard library) classes can define this
2993
- # to return True for comparisons between non-overlapping types.
2994
- if not custom_special_method (
2995
- left_type , "__eq__"
2996
- ) and not custom_special_method (right_type , "__eq__" ):
2997
- # Also flag non-overlapping literals in situations like:
2998
- # x: Literal['a', 'b']
2999
- # if x == 'c':
3000
- # ...
3001
- left_type = try_getting_literal (left_type )
3002
- right_type = try_getting_literal (right_type )
3003
- if self .dangerous_comparison (left_type , right_type ):
3004
- self .msg .dangerous_comparison (left_type , right_type , "equality" , e )
2991
+ # Also flag non-overlapping literals in situations like:
2992
+ # x: Literal['a', 'b']
2993
+ # if x == 'c':
2994
+ # ...
2995
+ left_type = try_getting_literal (left_type )
2996
+ right_type = try_getting_literal (right_type )
2997
+ if self .dangerous_comparison (left_type , right_type ):
2998
+ self .msg .dangerous_comparison (left_type , right_type , "equality" , e )
3005
2999
3006
3000
elif operator == "is" or operator == "is not" :
3007
3001
right_type = self .accept (right ) # validate the right operand
@@ -3064,6 +3058,12 @@ def dangerous_comparison(
3064
3058
3065
3059
left , right = get_proper_types ((left , right ))
3066
3060
3061
+ # We suppress the error if there is a custom __eq__() method on either
3062
+ # side. User defined (or even standard library) classes can define this
3063
+ # to return True for comparisons between non-overlapping types.
3064
+ if custom_special_method (left , "__eq__" ) or custom_special_method (right , "__eq__" ):
3065
+ return False
3066
+
3067
3067
if self .chk .binder .is_unreachable_warning_suppressed ():
3068
3068
# We are inside a function that contains type variables with value restrictions in
3069
3069
# its signature. In this case we just suppress all strict-equality checks to avoid
@@ -3094,14 +3094,18 @@ def dangerous_comparison(
3094
3094
return False
3095
3095
if isinstance (left , Instance ) and isinstance (right , Instance ):
3096
3096
# Special case some builtin implementations of AbstractSet.
3097
+ left_name = left .type .fullname
3098
+ right_name = right .type .fullname
3097
3099
if (
3098
- left . type . fullname in OVERLAPPING_TYPES_ALLOWLIST
3099
- and right . type . fullname in OVERLAPPING_TYPES_ALLOWLIST
3100
+ left_name in OVERLAPPING_TYPES_ALLOWLIST
3101
+ and right_name in OVERLAPPING_TYPES_ALLOWLIST
3100
3102
):
3101
3103
abstract_set = self .chk .lookup_typeinfo ("typing.AbstractSet" )
3102
3104
left = map_instance_to_supertype (left , abstract_set )
3103
3105
right = map_instance_to_supertype (right , abstract_set )
3104
- return not is_overlapping_types (left .args [0 ], right .args [0 ])
3106
+ return self .dangerous_comparison (left .args [0 ], right .args [0 ])
3107
+ elif left_name in ("builtins.list" , "builtins.tuple" ) and right_name == left_name :
3108
+ return self .dangerous_comparison (left .args [0 ], right .args [0 ])
3105
3109
if isinstance (left , LiteralType ) and isinstance (right , LiteralType ):
3106
3110
if isinstance (left .value , bool ) and isinstance (right .value , bool ):
3107
3111
# Comparing different booleans is not dangerous.
0 commit comments