Skip to content

Commit 4e7c475

Browse files
committed
Clarifications
* "remaining" overloads => "candidate" overloads * moar tests
1 parent 89e6130 commit 4e7c475

File tree

6 files changed

+86
-14
lines changed

6 files changed

+86
-14
lines changed

conformance/results/mypy/overloads_evaluation.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Line 268: Unexpected errors ['overloads_evaluation.py:268: error: Expression is
1818
Line 284: Unexpected errors ['overloads_evaluation.py:284: error: Expression is of type "list[Any]", not "Any" [assert-type]']
1919
Line 306: Unexpected errors ['overloads_evaluation.py:306: error: Expression is of type "Any", not "float" [assert-type]']
2020
Line 350: Unexpected errors ['overloads_evaluation.py:350: error: Expression is of type "list[Any]", not "Any" [assert-type]']
21+
Line 395: Unexpected errors ['overloads_evaluation.py:395: error: Expression is of type "Any", not "int" [assert-type]']
2122
"""
2223
output = """
2324
overloads_evaluation.py:38: error: All overload variants of "example1_1" require at least one argument [call-overload]
@@ -50,4 +51,5 @@ overloads_evaluation.py:268: error: Expression is of type "list[Any]", not "Any"
5051
overloads_evaluation.py:284: error: Expression is of type "list[Any]", not "Any" [assert-type]
5152
overloads_evaluation.py:306: error: Expression is of type "Any", not "float" [assert-type]
5253
overloads_evaluation.py:350: error: Expression is of type "list[Any]", not "Any" [assert-type]
54+
overloads_evaluation.py:395: error: Expression is of type "Any", not "int" [assert-type]
5355
"""

conformance/results/pyright/overloads_evaluation.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Picks first overload instead of most general return type in some cases where ove
66
conformance_automated = "Fail"
77
errors_diff = """
88
Line 284: Unexpected errors ['overloads_evaluation.py:284:17 - error: "assert_type" mismatch: expected "Any" but received "list[int]" (reportAssertTypeFailure)']
9-
Line 398: Unexpected errors ['overloads_evaluation.py:398:17 - error: "assert_type" mismatch: expected "A[Any]" but received "A[None]" (reportAssertTypeFailure)']
9+
Line 464: Unexpected errors ['overloads_evaluation.py:464:17 - error: "assert_type" mismatch: expected "A[Any]" but received "A[None]" (reportAssertTypeFailure)']
1010
"""
1111
output = """
1212
overloads_evaluation.py:38:1 - error: No overloads for "example1_1" match the provided arguments
@@ -23,5 +23,5 @@ overloads_evaluation.py:116:17 - error: Argument of type "int | str" cannot be a
2323
  Type "int | str" is not assignable to type "int"
2424
    "str" is not assignable to "int" (reportArgumentType)
2525
overloads_evaluation.py:284:17 - error: "assert_type" mismatch: expected "Any" but received "list[int]" (reportAssertTypeFailure)
26-
overloads_evaluation.py:398:17 - error: "assert_type" mismatch: expected "A[Any]" but received "A[None]" (reportAssertTypeFailure)
26+
overloads_evaluation.py:464:17 - error: "assert_type" mismatch: expected "A[Any]" but received "A[None]" (reportAssertTypeFailure)
2727
"""

conformance/results/ty/overloads_evaluation.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ Returns Any instead of most general return type for ambiguous calls.
44
"""
55
conformance_automated = "Fail"
66
errors_diff = """
7-
Line 398: Unexpected errors ['overloads_evaluation.py:398:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `A[Any]`']
7+
Line 395: Unexpected errors ['overloads_evaluation.py:395:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `int`']
8+
Line 464: Unexpected errors ['overloads_evaluation.py:464:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `A[Any]`']
89
"""
910
output = """
1011
overloads_evaluation.py:38:1: error[no-matching-overload] No overload of function `example1_1` matches arguments
1112
overloads_evaluation.py:46:15: error[invalid-argument-type] Argument to function `example1_1` is incorrect: Expected `str`, found `Literal[1]`
1213
overloads_evaluation.py:51:12: error[invalid-argument-type] Argument to function `example1_1` is incorrect: Expected `str`, found `Literal[1]`
1314
overloads_evaluation.py:116:5: error[no-matching-overload] No overload of function `example2` matches arguments
14-
overloads_evaluation.py:398:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `A[Any]`
15+
overloads_evaluation.py:395:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `int`
16+
overloads_evaluation.py:464:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `A[Any]`
1517
"""

conformance/results/zuban/overloads_evaluation.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Returns Any instead of most general return type for ambiguous calls.
44
"""
55
conformance_automated = "Fail"
66
errors_diff = """
7-
Line 398: Unexpected errors ['overloads_evaluation.py:398: error: Expression is of type "Any", not "A[Any]" [misc]']
7+
Line 395: Unexpected errors ['overloads_evaluation.py:395: error: Expression is of type "Any", not "int" [misc]']
8+
Line 464: Unexpected errors ['overloads_evaluation.py:464: error: Expression is of type "Any", not "A[Any]" [misc]']
89
"""
910
output = """
1011
overloads_evaluation.py:38: error: All overload variants of "example1_1" require at least one argument [call-overload]
@@ -21,5 +22,6 @@ overloads_evaluation.py:51: note: def example1_1(x: int, y: str) -> int
2122
overloads_evaluation.py:51: note: def example1_1(x: str) -> str
2223
overloads_evaluation.py:116: error: Argument 1 to "example2" has incompatible type "int | str"; expected "int" [arg-type]
2324
overloads_evaluation.py:116: error: Argument 2 to "example2" has incompatible type "int | str"; expected "str" [arg-type]
24-
overloads_evaluation.py:398: error: Expression is of type "Any", not "A[Any]" [misc]
25+
overloads_evaluation.py:395: error: Expression is of type "Any", not "int" [misc]
26+
overloads_evaluation.py:464: error: Expression is of type "Any", not "A[Any]" [misc]
2527
"""

conformance/tests/overloads_evaluation.py

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,72 @@ def check_example8(x: Any):
371371
assert_type(ret, bool)
372372

373373

374+
@overload
375+
def example9(x: str, y: Literal['o1']) -> bool: ...
376+
377+
378+
@overload
379+
def example9(x: bytes, y: Literal['o1', 'o2']) -> bool: ...
380+
381+
382+
@overload
383+
def example9(x: bytes, y: str) -> int: ...
384+
385+
386+
def example9(x: str | bytes, y: str) -> bool | int:
387+
return True
388+
389+
390+
def check_example9(x: Any):
391+
# All three overloads are candidates. The parameter types corresponding to
392+
# argument `x` are `str` and `bytes`, which are not equivalent, so none of
393+
# the overloads can be eliminated. We pick the most general return type.
394+
ret1 = example9(x, 'o1')
395+
assert_type(ret1, int)
396+
# The second and third overload are candidates. The parameter type
397+
# corresponding to argument `x` is `bytes` in both candidates, so we can
398+
# eliminate the third overload.
399+
ret2 = example9(x, 'o2')
400+
assert_type(ret2, bool)
401+
402+
403+
@overload
404+
def example10(x: int) -> bool: ...
405+
406+
407+
@overload
408+
def example10(*args: int) -> int: ...
409+
410+
411+
def example10(*args: int, **kwargs: int) -> int:
412+
return 0
413+
414+
415+
def check_example10(x: Any):
416+
# The parameters corresponding to argument `x` (`x` in the first overload
417+
# and `*args` in the second) both have type `int`, so the second overload
418+
# can be eliminated.
419+
assert_type(example10(x), bool)
420+
421+
422+
@overload
423+
def example11(x: int) -> bool: ...
424+
425+
426+
@overload
427+
def example11(**kwargs: int) -> int: ...
428+
429+
430+
def example11(*args: int, **kwargs: int) -> int:
431+
return 0
432+
433+
def check_example11(x: Any):
434+
# The parameters corresponding to argument `x` (`x` in the first overload
435+
# and `**kwargs` in the second) both have type `int`, so the second
436+
# overload can be eliminated.
437+
assert_type(example11(x=x), bool)
438+
439+
374440
class A[T]:
375441
x: T
376442

@@ -379,20 +445,20 @@ def f(self) -> T:
379445

380446

381447
@overload
382-
def example9(x: A[None]) -> A[None]: ...
448+
def example12(x: A[None]) -> A[None]: ...
383449

384450

385451
@overload
386-
def example9(x: A[Any]) -> A[Any]: ...
452+
def example12(x: A[Any]) -> A[Any]: ...
387453

388454

389-
def example9(x: A[Any]) -> A[Any]:
455+
def example12(x: A[Any]) -> A[Any]:
390456
return x
391457

392458

393-
def check_example9(x: Any):
459+
def check_example12(x: Any):
394460
# Step 5 eliminates the first overload because there exists a
395461
# materialization of `A[Any]` that is not assignable to `A[None]`. Step 6
396462
# picks the second overload.
397-
ret = example9(x)
463+
ret = example12(x)
398464
assert_type(ret, A[Any])

docs/spec/overload.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,15 @@ If so, eliminate overloads that do not have a variadic parameter.
268268
Step 5
269269
~~~~~~
270270

271-
For each of the remaining overloads, determine whether all arguments satisfy at
271+
For each of the candidate overloads, determine whether all arguments satisfy at
272272
least one of the following conditions:
273273

274274
- All possible :term:`materializations <materialize>` of the argument's type are
275275
assignable to the corresponding parameter type, or
276-
- The parameter types corresponding to this argument in all of the remaining overloads
276+
- The parameter types corresponding to this argument in all of the candidate overloads
277277
are :term:`equivalent`.
278278

279-
If so, eliminate all of the subsequent remaining overloads.
279+
If so, eliminate all of the subsequent candidate overloads.
280280

281281
Consider the following examples::
282282

0 commit comments

Comments
 (0)