2Tests for evaluation of calls to overloaded functions.
6from typing import Any, assert_type, Literal, overload, TypeVar
8# mypy: disable-error-code=overload-overlap
13# > Step 1: Examine the argument list to determine the number of
14# > positional and keyword arguments. Use this information to eliminate any
15# > overload candidates that are not plausible based on their
18# (There is no way to observe via conformance tests whether an implementation
19# performs this step separately from the argument-type-testing step 2 below, so
20# the separation of step 1 from step 2 is purely a presentation choice for the
21# algorithm, not a conformance requirement.)
25def example1_1(x: int, y: str) -> int: ...
29def example1_1(x: str) -> str: ...
32def example1_1(x: int | str, y: str = "") -> int | str:
36# > - If no candidate overloads remain, generate an error and stop.
38example1_1() # E: no matching overload
[no-matching-overload] No overload of function `example1_1` matches arguments
40# > - If only one candidate overload remains, it is the winning match. Evaluate
41# > it as if it were a non-overloaded function call and stop.
43ret1 = example1_1(1, "")
46example1_1(1, 1) # E: Literal[1] not assignable to str
[invalid-argument-type] Argument to function `example1_1` is incorrect: Expected `str`, found `Literal[1]`
51example1_1(1) # E: Literal[1] not assignable to str
[invalid-argument-type] Argument to function `example1_1` is incorrect: Expected `str`, found `Literal[1]`
55def example1_2(b: Literal[True] = ...) -> int: ...
59def example1_2(b: bool) -> float: ...
62def example1_2(b: bool = True) -> float:
63 raise NotImplementedError
66def check_example1_2() -> None:
67 assert_type(example1_2(), int)
70# > Step 2: Evaluate each remaining overload as a regular (non-overloaded)
71# > call to determine whether it is compatible with the supplied
72# > argument list. Unlike step 1, this step considers the types of the parameters
73# > and arguments. During this step, do not generate any user-visible errors.
74# > Simply record which of the overloads result in evaluation errors.
78def example2(x: int, y: str, z: int) -> str: ...
82def example2(x: int, y: int, z: int) -> int: ...
85def example2(x: int, y: int | str, z: int) -> int | str:
89# > - If only one overload evaluates without error, it is the winning match.
90# > Evaluate it as if it were a non-overloaded function call and stop.
92ret5 = example2(1, 2, 3)
95# > Step 3: If step 2 produces errors for all overloads, perform
96# > "argument type expansion". Union types can be expanded
97# > into their constituent subtypes. For example, the type ``int | str`` can
98# > be expanded into ``int`` and ``str``.
100# > - If all argument lists evaluate successfully, combine their
101# > respective return types by union to determine the final return type
102# > for the call, and stop.
105def check_expand_union(v: int | str) -> None:
106 ret1 = example2(1, v, 1)
107 assert_type(ret1, int | str)
110# > - If argument expansion has been applied to all arguments and one or
111# > more of the expanded argument lists cannot be evaluated successfully,
112# > generate an error and stop.
115def check_expand_union_2(v: int | str) -> None:
116 example2(v, v, 1) # E: no overload matches (str, ..., ...)
[no-matching-overload] No overload of function `example2` matches arguments
119# > 2. ``bool`` should be expanded into ``Literal[True]`` and ``Literal[False]``.
123def expand_bool(x: Literal[False]) -> Literal[0]: ...
127def expand_bool(x: Literal[True]) -> Literal[1]: ...
130def expand_bool(x: bool) -> int:
134def check_expand_bool(v: bool) -> None:
135 ret1 = expand_bool(v)
136 assert_type(ret1, Literal[0, 1])
139# > 3. ``Enum`` types (other than those that derive from ``enum.Flag``) should
140# > be expanded into their literal members.
149def expand_enum(x: Literal[Color.RED]) -> Literal[0]: ...
153def expand_enum(x: Literal[Color.BLUE]) -> Literal[1]: ...
156def expand_enum(x: Color) -> int:
160def check_expand_enum(v: Color) -> None:
161 ret1 = expand_enum(v)
162 assert_type(ret1, Literal[0, 1])
165# > 4. ``type[A | B]`` should be expanded into ``type[A]`` and ``type[B]``.
169def expand_type_union(x: type[int]) -> int: ...
173def expand_type_union(x: type[str]) -> str: ...
176def expand_type_union(x: type[int] | type[str]) -> int | str:
180def check_expand_type_union(v: type[int | str]) -> None:
181 ret1 = expand_type_union(v)
182 assert_type(ret1, int | str)
185# > 5. Tuples of known length that contain expandable types should be expanded
186# > into all possible combinations of their element types. For example, the type
187# > ``tuple[int | str, bool]`` should be expanded into ``(int, Literal[True])``,
188# > ``(int, Literal[False])``, ``(str, Literal[True])``, and
189# > ``(str, Literal[False])``.
193def expand_tuple(x: tuple[int, int]) -> int: ...
197def expand_tuple(x: tuple[int, str]) -> str: ...
200def expand_tuple(x: tuple[int, int | str]) -> int | str:
204def check_expand_tuple(v: int | str) -> None:
205 ret1 = expand_tuple((1, v))
206 assert_type(ret1, int | str)
209# > Step 4: If the argument list is compatible with two or more overloads,
210# > determine whether one or more of the overloads has a variadic parameter
211# > (either ``*args`` or ``**kwargs``) that maps to a corresponding argument
212# > that supplies an indeterminate number of positional or keyword arguments.
213# > If so, eliminate overloads that do not have a variadic parameter.
217def variadic(x: int, /) -> str: ...
221def variadic(x: int, y: int, /, *args: int) -> int: ...
224def variadic(*args: int) -> int | str:
228# > - If this results in only one remaining candidate overload, it is
229# > the winning match. Evaluate it as if it were a non-overloaded function
233def check_variadic(v: list[int]) -> None:
235 assert_type(ret1, int)
238# > Step 5: For all arguments, determine whether all possible
239# > :term:`materializations <materialize>` of the argument's type are assignable to
240# > the corresponding parameter type for each of the remaining overloads. If so,
241# > eliminate all of the subsequent remaining overloads.
245def example4(x: list[int], y: int) -> list[int]: ...
249def example4(x: list[str], y: str) -> list[int]: ...
253def example4(x: int, y: int) -> list[str]: ...
256def example4(x: list[int] | list[str] | int, y: int | str) -> list[int] | list[str]:
260def check_example4(v1: list[Any], v2: Any) -> None:
261 ret1 = example4(v1, v2)
262 assert_type(ret1, list[int])
264 ret2 = example4(v2, 1)
265 assert_type(ret2, Any)
269def example5(obj: list[int]) -> list[int]: ...
273def example5(obj: list[str]) -> list[str]: ...
276def example5(obj: Any) -> list[Any]:
280def check_example5(b: list[Any]) -> None:
281 assert_type(example5(b), Any)
285def example6(a: int, b: Any) -> float: ...
289def example6(a: float, b: T) -> T: ...
292def example6(a: float, b: T) -> T:
293 raise NotImplementedError
296def check_example6(a: list[Any], b: Any, c: str) -> None:
299 # All possible materializations of list[Any] are
300 # assignable to Any, so this matches the first overload
301 # and eliminates all subsequent overloads.
303 assert_type(v1, float)
305 # All possible materializations of Any are
306 # assignable to Any, so this matches the first overload
307 # and eliminates all subsequent overloads.
309 assert_type(v2, float)
311 # All possible materializations of list[int] are
312 # assignable to Any, so this matches the first overload
313 # and eliminates all subsequent overloads.
315 assert_type(v3, float)
317 v4 = example6(1.0, c)
320 v5 = example6(1.0, b)
323 v6 = example6(1.0, m)
324 assert_type(v6, list[int])
328def example7(x: list[Any], y: int) -> list[int]: ...
332def example7(x: list[Any], y: str) -> list[str]: ...
335def example7(x: list[Any], y: int | str) -> list[int] | list[str]:
339def check_example7(v1: list[Any], v2: Any) -> None:
340 ret1 = example7(v1, 1)
341 assert_type(ret1, list[int])
343 ret2 = example7(v1, "")
344 assert_type(ret2, list[str])
346 ret3 = example7(v1, v2)
347 assert_type(ret3, Any)