@@ -399,3 +399,142 @@ def _(x: SomeEnum):
399399 # TODO : This should be `A | B | C` once enums are supported and are expanded
400400 reveal_type(f(x)) # revealed: A
401401```
402+
403+ ## Filtering overloads with variadic arguments and parameters
404+
405+ TODO
406+
407+ ## Filtering based on ` Any ` / ` Unknown `
408+
409+ This is the step 5 of the overload call evluation algorithm which specifies that:
410+
411+ > For all arguments, determine whether all possible materializations of the argument’s type are
412+ > assignable to the corresponding parameter type for each of the remaining overloads. If so,
413+ > eliminate all of the subsequent remaining overloads.
414+
415+ This is only performed if the previous step resulted in more than one matching overload.
416+
417+ ### Single list argument
418+
419+ ` overloaded.pyi ` :
420+
421+ ``` pyi
422+ from typing import Any, overload
423+
424+ @overload
425+ def f (x : list[int ]) -> int : ...
426+ @overload
427+ def f (x : list[Any]) -> int : ...
428+ @overload
429+ def f (x : Any) -> str : ...
430+ ```
431+
432+ For the above definition, anything other than ` list ` should match the last overload:
433+
434+ ``` py
435+ from typing import Any
436+
437+ from overloaded import f
438+
439+ # Anything other than `list` should match the last overload
440+ reveal_type(f(1 )) # revealed: str
441+
442+ def _ (list_int : list[int ], list_any : list[Any]):
443+ reveal_type(f(list_int)) # revealed: int
444+ reveal_type(f(list_any)) # revealed: int
445+ ```
446+
447+ ### Single list argument (ambiguous)
448+
449+ The overload definition is the same as above, but the return type of the second overload is changed
450+ to ` str ` to make the overload matching ambiguous if the argument is a ` list[Any] ` .
451+
452+ ` overloaded.pyi ` :
453+
454+ ``` pyi
455+ from typing import Any, overload
456+
457+ @overload
458+ def f (x : list[int ]) -> int : ...
459+ @overload
460+ def f (x : list[Any]) -> str : ...
461+ @overload
462+ def f (x : Any) -> str : ...
463+ ```
464+
465+ ``` py
466+ from typing import Any
467+
468+ from overloaded import f
469+
470+ # Anything other than `list` should match the last overload
471+ reveal_type(f(1 )) # revealed: str
472+
473+ def _ (list_int : list[int ], list_any : list[Any]):
474+ # All materializations of `list[int]` are assignable to `list[int]`, so it matches the first
475+ # overload.
476+ reveal_type(f(list_int)) # revealed: int
477+
478+ # All materializations of `list[Any]` are assignable to `list[int]` and `list[Any]`, but the
479+ # return type of first and second overloads are not equivalent, so the overload matching
480+ # is ambiguous.
481+ reveal_type(f(list_any)) # revealed: Any
482+ ```
483+
484+ ### Single tuple argument
485+
486+ ` overloaded.pyi ` :
487+
488+ ``` pyi
489+ from typing import Any, overload
490+
491+ @overload
492+ def f (x : tuple[int , str ]) -> int : ...
493+ @overload
494+ def f (x : tuple[int , Any]) -> int : ...
495+ @overload
496+ def f (x : Any) -> str : ...
497+ ```
498+
499+ ``` py
500+ from typing import Any
501+
502+ from overloaded import f
503+
504+ reveal_type(f(" a" )) # revealed: str
505+ reveal_type(f((1 , " b" ))) # revealed: int
506+ reveal_type(f((1 , 2 ))) # revealed: int
507+
508+ def _ (int_str : tuple[int , str ], int_any : tuple[int , Any], any_any : tuple[Any, Any]):
509+ reveal_type(f(int_str)) # revealed: int
510+ reveal_type(f(int_any)) # revealed: int
511+
512+ # All materializations of `tuple[Any, Any]` are assignable to the parameters of all the
513+ # overloads, but the return types aren't equivalent, so the overload matching is ambiguous.
514+ reveal_type(f(any_any)) # revealed: Any
515+ ```
516+
517+ ### Multiple arguments
518+
519+ ` overloaded.pyi ` :
520+
521+ ``` pyi
522+ from typing import Any, overload
523+
524+ class A : ...
525+ class B : ...
526+ class C : ...
527+ class D : ...
528+
529+ ```
530+
531+ ### Multiple arguments (ambiguous)
532+
533+ TODO:
534+
535+ - Starred arguments
536+ - Generics
537+ - Multiple arguments where one of them is ` Any ` or ` Unknown `
538+ - Combined with argument type expansion
539+ - Overloaded method (` self ` )
540+ - Overloaded class method (` cls ` )
0 commit comments