@@ -289,13 +289,46 @@ def visit_overloaded(self, left: Overloaded) -> bool:
289289 return True
290290 return False
291291 elif isinstance (right , Overloaded ):
292- # TODO: this may be too restrictive
293- if len (left .items ()) != len (right .items ()):
294- return False
295- for i in range (len (left .items ())):
296- if not is_subtype (left .items ()[i ], right .items ()[i ], self .check_type_parameter ,
297- ignore_pos_arg_names = self .ignore_pos_arg_names ):
292+ # Ensure each overload in the right side (the supertype) is accounted for.
293+ previous_match_left_index = - 1
294+ matched_overloads = set ()
295+ possible_invalid_overloads = set ()
296+
297+ for right_index , right_item in enumerate (right .items ()):
298+ found_match = False
299+
300+ for left_index , left_item in enumerate (left .items ()):
301+ subtype_match = is_subtype (left_item , right_item , self .check_type_parameter ,
302+ ignore_pos_arg_names = self .ignore_pos_arg_names )
303+
304+ # Order matters: we need to make sure that the index of
305+ # this item is at least the index of the previous one.
306+ if subtype_match and previous_match_left_index <= left_index :
307+ if not found_match :
308+ # Update the index of the previous match.
309+ previous_match_left_index = left_index
310+ found_match = True
311+ matched_overloads .add (left_item )
312+ possible_invalid_overloads .discard (left_item )
313+ else :
314+ # If this one overlaps with the supertype in any way, but it wasn't
315+ # an exact match, then it's a potential error.
316+ if (is_callable_subtype (left_item , right_item , ignore_return = True ,
317+ ignore_pos_arg_names = self .ignore_pos_arg_names ) or
318+ is_callable_subtype (right_item , left_item , ignore_return = True ,
319+ ignore_pos_arg_names = self .ignore_pos_arg_names )):
320+ # If this is an overload that's already been matched, there's no
321+ # problem.
322+ if left_item not in matched_overloads :
323+ possible_invalid_overloads .add (left_item )
324+
325+ if not found_match :
298326 return False
327+
328+ if possible_invalid_overloads :
329+ # There were potentially invalid overloads that were never matched to the
330+ # supertype.
331+ return False
299332 return True
300333 elif isinstance (right , UnboundType ):
301334 return True
0 commit comments