@@ -1568,12 +1568,9 @@ def union_overload_matches(self, types: Sequence[Type]) -> Union[AnyType, Callab
15681568 def erased_signature_similarity (self , arg_types : List [Type ], arg_kinds : List [int ],
15691569 arg_names : Optional [Sequence [Optional [str ]]],
15701570 callee : CallableType ,
1571- context : Context ) -> int :
1572- """Determine whether arguments could match the signature at runtime.
1573-
1574- Return similarity level (0 = no match, 1 = can match, 2 = non-promotion match). See
1575- overload_arg_similarity for a discussion of similarity levels.
1576- """
1571+ context : Context ) -> bool :
1572+ """Determine whether arguments could match the signature at runtime, after
1573+ erasing types."""
15771574 formal_to_actual = map_actuals_to_formals (arg_kinds ,
15781575 arg_names ,
15791576 callee .arg_kinds ,
@@ -1583,55 +1580,22 @@ def erased_signature_similarity(self, arg_types: List[Type], arg_kinds: List[int
15831580 if not self .check_argument_count (callee , arg_types , arg_kinds , arg_names ,
15841581 formal_to_actual , None , None ):
15851582 # Too few or many arguments -> no match.
1586- return 0
1587-
1588- similarity = 2
1583+ return False
15891584
15901585 def check_arg (caller_type : Type , original_caller_type : Type , caller_kind : int ,
15911586 callee_type : Type , n : int , m : int , callee : CallableType ,
15921587 context : Context , messages : MessageBuilder ) -> None :
1593- nonlocal similarity
1594- similarity = min (similarity ,
1595- overload_arg_similarity (caller_type , callee_type ))
1596- if similarity == 0 :
1588+ if not arg_approximate_similarity (caller_type , callee_type ):
15971589 # No match -- exit early since none of the remaining work can change
15981590 # the result.
15991591 raise Finished
16001592
16011593 try :
16021594 self .check_argument_types (arg_types , arg_kinds , callee , formal_to_actual ,
16031595 context = context , check_arg = check_arg )
1596+ return True
16041597 except Finished :
1605- pass
1606-
1607- return similarity
1608-
1609- def match_signature_types (self , arg_types : List [Type ], arg_kinds : List [int ],
1610- arg_names : Optional [Sequence [Optional [str ]]], callee : CallableType ,
1611- context : Context ) -> bool :
1612- """Determine whether arguments types match the signature.
1613-
1614- Assume that argument counts are compatible.
1615-
1616- Return True if arguments match.
1617- """
1618- formal_to_actual = map_actuals_to_formals (arg_kinds ,
1619- arg_names ,
1620- callee .arg_kinds ,
1621- callee .arg_names ,
1622- lambda i : arg_types [i ])
1623- ok = True
1624-
1625- def check_arg (caller_type : Type , original_caller_type : Type , caller_kind : int ,
1626- callee_type : Type , n : int , m : int , callee : CallableType ,
1627- context : Context , messages : MessageBuilder ) -> None :
1628- nonlocal ok
1629- if not is_subtype (caller_type , callee_type ):
1630- ok = False
1631-
1632- self .check_argument_types (arg_types , arg_kinds , callee , formal_to_actual ,
1633- context = context , check_arg = check_arg )
1634- return ok
1598+ return False
16351599
16361600 def apply_generic_arguments (self , callable : CallableType , types : Sequence [Optional [Type ]],
16371601 context : Context ) -> CallableType :
@@ -3295,101 +3259,68 @@ def visit_uninhabited_type(self, t: UninhabitedType) -> bool:
32953259 return True
32963260
32973261
3298- def overload_arg_similarity (actual : Type , formal : Type ) -> int :
3299- """Return if caller argument (actual) is compatible with overloaded signature arg (formal).
3262+ def arg_approximate_similarity (actual : Type , formal : Type ) -> bool :
3263+ """Return if caller argument (actual) is roughly compatible with signature arg (formal).
33003264
3301- Return a similarity level:
3302- 0: no match
3303- 1: actual is compatible, but only using type promotions (e.g. int vs float)
3304- 2: actual is compatible without type promotions (e.g. int vs object)
3265+ This function is deliberately loose and will report two types are similar
3266+ as long as their "shapes" are plausibly the same.
33053267
3306- The distinction is important in cases where multiple overload items match. We want
3307- give priority to higher similarity matches.
3268+ This is useful when we're doing error reporting: for example, if we're trying
3269+ to select an overload alternative and there's no exact match, we can use
3270+ this function to help us identify which alternative the user might have
3271+ *meant* to match.
33083272 """
3309- # Replace type variables with their upper bounds. Overloading
3310- # resolution is based on runtime behavior which erases type
3311- # parameters, so no need to handle type variables occurring within
3312- # a type.
3273+
3274+ # Erase typevars: we'll consider them all to have the same "shape".
3275+
33133276 if isinstance (actual , TypeVarType ):
33143277 actual = actual .erase_to_union_or_bound ()
33153278 if isinstance (formal , TypeVarType ):
33163279 formal = formal .erase_to_union_or_bound ()
3317- if (isinstance (actual , UninhabitedType ) or isinstance (actual , AnyType ) or
3318- isinstance (formal , AnyType ) or
3319- (isinstance (actual , Instance ) and actual .type .fallback_to_any )):
3320- # These could match anything at runtime.
3321- return 2
3280+
3281+ # Callable or Type[...]-ish types
3282+
3283+ def is_typetype_like (typ : Type ) -> bool :
3284+ return (isinstance (typ , TypeType )
3285+ or (isinstance (typ , FunctionLike ) and typ .is_type_obj ())
3286+ or (isinstance (typ , Instance ) and typ .type .fullname () == "builtins.object" ))
3287+
33223288 if isinstance (formal , CallableType ):
3323- if isinstance (actual , (CallableType , Overloaded )):
3324- # TODO: do more sophisticated callable matching
3325- return 2
3326- if isinstance (actual , TypeType ):
3327- return 2 if is_subtype (actual , formal ) else 0
3328- if isinstance (actual , NoneTyp ):
3329- if not experiments .STRICT_OPTIONAL :
3330- # NoneTyp matches anything if we're not doing strict Optional checking
3331- return 2
3332- else :
3333- # NoneType is a subtype of object
3334- if isinstance (formal , Instance ) and formal .type .fullname () == "builtins.object" :
3335- return 2
3289+ if isinstance (actual , (CallableType , Overloaded , TypeType )):
3290+ return True
3291+ if is_typetype_like (actual ) and is_typetype_like (formal ):
3292+ return True
3293+
3294+ # Unions
3295+
33363296 if isinstance (actual , UnionType ):
3337- return max (overload_arg_similarity (item , formal )
3338- for item in actual .relevant_items ())
3297+ return any (arg_approximate_similarity (item , formal ) for item in actual .relevant_items ())
33393298 if isinstance (formal , UnionType ):
3340- return max (overload_arg_similarity (actual , item )
3341- for item in formal .relevant_items ())
3342- if isinstance (formal , TypeType ):
3343- if isinstance (actual , TypeType ):
3344- # Since Type[T] is covariant, check if actual = Type[A] is
3345- # a subtype of formal = Type[F].
3346- return overload_arg_similarity (actual .item , formal .item )
3347- elif isinstance (actual , FunctionLike ) and actual .is_type_obj ():
3348- # Check if the actual is a constructor of some sort.
3349- # Note that this is this unsound, since we don't check the __init__ signature.
3350- return overload_arg_similarity (actual .items ()[0 ].ret_type , formal .item )
3351- else :
3352- return 0
3299+ return any (arg_approximate_similarity (actual , item ) for item in formal .relevant_items ())
3300+
3301+ # TypedDicts
3302+
33533303 if isinstance (actual , TypedDictType ):
33543304 if isinstance (formal , TypedDictType ):
3355- # Don't support overloading based on the keys or value types of a TypedDict since
3356- # that would be complicated and probably only marginally useful.
3357- return 2
3358- return overload_arg_similarity (actual .fallback , formal )
3305+ return True
3306+ return arg_approximate_similarity (actual .fallback , formal )
3307+
3308+ # Instances
3309+ # For instances, we mostly defer to the existing is_subtype check.
3310+
33593311 if isinstance (formal , Instance ):
33603312 if isinstance (actual , CallableType ):
33613313 actual = actual .fallback
33623314 if isinstance (actual , Overloaded ):
33633315 actual = actual .items ()[0 ].fallback
33643316 if isinstance (actual , TupleType ):
33653317 actual = actual .fallback
3366- if isinstance (actual , Instance ):
3367- # First perform a quick check (as an optimization) and fall back to generic
3368- # subtyping algorithm if type promotions are possible (e.g., int vs. float).
3369- if formal .type in actual .type .mro :
3370- return 2
3371- elif formal .type .is_protocol and is_subtype (actual , erasetype .erase_type (formal )):
3372- return 2
3373- elif actual .type ._promote and is_subtype (actual , formal ):
3374- return 1
3375- else :
3376- return 0
3377- elif isinstance (actual , TypeType ):
3378- item = actual .item
3379- if formal .type .fullname () in {"builtins.object" , "builtins.type" }:
3380- return 2
3381- elif isinstance (item , Instance ) and item .type .metaclass_type :
3382- # FIX: this does not handle e.g. Union of instances
3383- return overload_arg_similarity (item .type .metaclass_type , formal )
3384- else :
3385- return 0
3386- else :
3387- return 0
3388- if isinstance (actual , UnboundType ) or isinstance (formal , UnboundType ):
3389- # Either actual or formal is the result of an error; shut up.
3390- return 2
3391- # Fall back to a conservative equality check for the remaining kinds of type.
3392- return 2 if is_same_type (erasetype .erase_type (actual ), erasetype .erase_type (formal )) else 0
3318+ if isinstance (actual , Instance ) and formal .type in actual .type .mro :
3319+ # Try performing a quick check as an optimization
3320+ return True
3321+
3322+ # Fall back to a standard subtype check for the remaining kinds of type.
3323+ return is_subtype (erasetype .erase_type (actual ), erasetype .erase_type (formal ))
33933324
33943325
33953326def any_causes_overload_ambiguity (items : List [CallableType ],
0 commit comments