Skip to content

Commit 02f0652

Browse files
committed
add tests for steps 2 and 3 of overload evaluation
1 parent 17d3e15 commit 02f0652

File tree

9 files changed

+118
-51
lines changed

9 files changed

+118
-51
lines changed

conformance/results/mypy/overloads_evaluation.toml

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,24 @@ Does not pick a winning overload based on arity, prior to considering argument t
44
"""
55
conformance_automated = "Fail"
66
errors_diff = """
7-
Line 36: Unexpected errors ['overloads_evaluation.py:36: error: Expression is of type "Any", not "int" [assert-type]']
8-
Line 42: Unexpected errors ['overloads_evaluation.py:42: error: Expression is of type "Any", not "str" [assert-type]']
7+
Line 35: Unexpected errors ['overloads_evaluation.py:35: error: Expression is of type "Any", not "int" [assert-type]']
8+
Line 41: Unexpected errors ['overloads_evaluation.py:41: error: Expression is of type "Any", not "str" [assert-type]']
99
"""
1010
output = """
11-
overloads_evaluation.py:26: error: All overload variants of "num_args" require at least one argument [call-overload]
11+
overloads_evaluation.py:26: error: All overload variants of "example1" require at least one argument [call-overload]
1212
overloads_evaluation.py:26: note: Possible overload variants:
13-
overloads_evaluation.py:26: note: def num_args(x: int, y: str) -> int
14-
overloads_evaluation.py:26: note: def num_args(x: str) -> str
15-
overloads_evaluation.py:35: error: No overload variant of "num_args" matches argument types "int", "int" [call-overload]
16-
overloads_evaluation.py:35: note: Possible overload variants:
17-
overloads_evaluation.py:35: note: def num_args(x: int, y: str) -> int
18-
overloads_evaluation.py:35: note: def num_args(x: str) -> str
19-
overloads_evaluation.py:36: error: Expression is of type "Any", not "int" [assert-type]
20-
overloads_evaluation.py:41: error: No overload variant of "num_args" matches argument type "int" [call-overload]
21-
overloads_evaluation.py:41: note: Possible overload variants:
22-
overloads_evaluation.py:41: note: def num_args(x: int, y: str) -> int
23-
overloads_evaluation.py:41: note: def num_args(x: str) -> str
24-
overloads_evaluation.py:42: error: Expression is of type "Any", not "str" [assert-type]
13+
overloads_evaluation.py:26: note: def example1(x: int, y: str) -> int
14+
overloads_evaluation.py:26: note: def example1(x: str) -> str
15+
overloads_evaluation.py:34: error: No overload variant of "example1" matches argument types "int", "int" [call-overload]
16+
overloads_evaluation.py:34: note: Possible overload variants:
17+
overloads_evaluation.py:34: note: def example1(x: int, y: str) -> int
18+
overloads_evaluation.py:34: note: def example1(x: str) -> str
19+
overloads_evaluation.py:35: error: Expression is of type "Any", not "int" [assert-type]
20+
overloads_evaluation.py:40: error: No overload variant of "example1" matches argument type "int" [call-overload]
21+
overloads_evaluation.py:40: note: Possible overload variants:
22+
overloads_evaluation.py:40: note: def example1(x: int, y: str) -> int
23+
overloads_evaluation.py:40: note: def example1(x: str) -> str
24+
overloads_evaluation.py:41: error: Expression is of type "Any", not "str" [assert-type]
25+
overloads_evaluation.py:85: error: Argument 1 to "example2" has incompatible type "int | str"; expected "int" [arg-type]
26+
overloads_evaluation.py:85: error: Argument 2 to "example2" has incompatible type "int | str"; expected "str" [arg-type]
2527
"""

conformance/results/pyre/overloads_evaluation.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ conformance_automated = "Pass"
33
errors_diff = """
44
"""
55
output = """
6-
overloads_evaluation.py:26:0 Missing argument [20]: Call `num_args` expects argument `x`.
7-
overloads_evaluation.py:35:19 Incompatible parameter type [6]: In call `num_args`, for 2nd positional argument, expected `str` but got `int`.
8-
overloads_evaluation.py:41:16 Incompatible parameter type [6]: In call `num_args`, for 1st positional argument, expected `str` but got `int`.
6+
overloads_evaluation.py:26:0 Missing argument [20]: Call `example1` expects argument `x`.
7+
overloads_evaluation.py:34:19 Incompatible parameter type [6]: In call `example1`, for 2nd positional argument, expected `str` but got `int`.
8+
overloads_evaluation.py:40:16 Incompatible parameter type [6]: In call `example1`, for 1st positional argument, expected `str` but got `int`.
9+
overloads_evaluation.py:85:13 Incompatible parameter type [6]: In call `example2`, for 1st positional argument, expected `int` but got `Union[int, str]`.
10+
overloads_evaluation.py:85:16 Incompatible parameter type [6]: In call `example2`, for 2nd positional argument, expected `str` but got `Union[int, str]`.
911
"""

conformance/results/pyre/version.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "pyre 0.9.23"
2-
test_duration = 6.7
2+
test_duration = 6.1

conformance/results/pyright/overloads_evaluation.toml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@ conformance_automated = "Pass"
33
errors_diff = """
44
"""
55
output = """
6-
overloads_evaluation.py:26:1 - error: No overloads for "num_args" match the provided arguments
6+
overloads_evaluation.py:26:1 - error: No overloads for "example1" match the provided arguments
77
  Argument types: () (reportCallIssue)
8-
overloads_evaluation.py:35:20 - error: Argument of type "Literal[1]" cannot be assigned to parameter "y" of type "str" in function "num_args"
8+
overloads_evaluation.py:34:20 - error: Argument of type "Literal[1]" cannot be assigned to parameter "y" of type "str" in function "example1"
99
  "Literal[1]" is not assignable to "str" (reportArgumentType)
10-
overloads_evaluation.py:41:17 - error: Argument of type "Literal[1]" cannot be assigned to parameter "x" of type "str" in function "num_args"
10+
overloads_evaluation.py:40:17 - error: Argument of type "Literal[1]" cannot be assigned to parameter "x" of type "str" in function "example1"
1111
  "Literal[1]" is not assignable to "str" (reportArgumentType)
12+
overloads_evaluation.py:85:5 - error: No overloads for "example2" match the provided arguments (reportCallIssue)
13+
overloads_evaluation.py:85:14 - error: Argument of type "int | str" cannot be assigned to parameter "x" of type "int" in function "example2"
14+
  Type "int | str" is not assignable to type "int"
15+
    "str" is not assignable to "int" (reportArgumentType)
16+
overloads_evaluation.py:85:17 - error: Argument of type "int | str" cannot be assigned to parameter "y" of type "int" in function "example2"
17+
  Type "int | str" is not assignable to type "int"
18+
    "str" is not assignable to "int" (reportArgumentType)
1219
"""
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "pyright 1.1.391"
2-
test_duration = 1.5
2+
test_duration = 1.6
Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,58 @@
11
conformant = "Partial"
22
notes = """
33
Does not pick a winning overload based on arity, prior to considering argument types.
4+
Does not perform argument expansion on unions and union return types of all matching overloads.
45
"""
56
conformance_automated = "Fail"
67
errors_diff = """
7-
Line 24: Unexpected errors ['overloads_evaluation.py:24:12: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in num_args: bad return type [bad-return-type]']
8-
Line 36: Unexpected errors ['overloads_evaluation.py:36:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in <module>: Any [assert-type]']
9-
Line 42: Unexpected errors ['overloads_evaluation.py:42:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in <module>: Any [assert-type]']
8+
Line 85: Expected 1 errors
9+
Line 22: Unexpected errors ['overloads_evaluation.py:22:12: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in example1: bad return type [bad-return-type]']
10+
Line 35: Unexpected errors ['overloads_evaluation.py:35:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in <module>: Any [assert-type]']
11+
Line 41: Unexpected errors ['overloads_evaluation.py:41:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in <module>: Any [assert-type]']
12+
Line 59: Unexpected errors ['overloads_evaluation.py:59:12: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in example2: bad return type [bad-return-type]']
13+
Line 78: Unexpected errors ['overloads_evaluation.py:78:5: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in _: str [assert-type]']
1014
"""
1115
output = """
12-
overloads_evaluation.py:24:12: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in num_args: bad return type [bad-return-type]
16+
overloads_evaluation.py:22:12: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in example1: bad return type [bad-return-type]
1317
1418
return 1
1519
\u001b[1m\u001b[31m~\u001b[39m\u001b[0m
1620
1721
Called from (traceback):
18-
line 38, in current file
19-
overloads_evaluation.py:26:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Missing parameter 'x' in call to function num_args [missing-parameter]
22+
line 37, in current file
23+
overloads_evaluation.py:26:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Missing parameter 'x' in call to function example1 [missing-parameter]
2024
21-
num_args() # E: no matching overload
25+
example1() # E: no matching overload
2226
\u001b[1m\u001b[31m~~~~~~~~~~\u001b[39m\u001b[0m
2327
24-
overloads_evaluation.py:35:8: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Function num_args was called with the wrong arguments [wrong-arg-types]
28+
overloads_evaluation.py:34:8: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Function example1 was called with the wrong arguments [wrong-arg-types]
2529
26-
ret2 = num_args(1, 1) # E: Literal[1] not assignable to str
30+
ret2 = example1(1, 1) # E: Literal[1] not assignable to str
2731
\u001b[1m\u001b[31m~~~~~~~~~~~~~~\u001b[39m\u001b[0m
2832
29-
overloads_evaluation.py:36:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Any [assert-type]
33+
overloads_evaluation.py:35:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Any [assert-type]
3034
3135
assert_type(ret2, int)
3236
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
3337
34-
overloads_evaluation.py:41:8: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Function num_args was called with the wrong arguments [wrong-arg-types]
38+
overloads_evaluation.py:40:8: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Function example1 was called with the wrong arguments [wrong-arg-types]
3539
36-
ret4 = num_args(1) # E: Literal[1] not assignable to str
40+
ret4 = example1(1) # E: Literal[1] not assignable to str
3741
\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m
3842
39-
overloads_evaluation.py:42:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Any [assert-type]
43+
overloads_evaluation.py:41:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Any [assert-type]
4044
4145
assert_type(ret4, str)
4246
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
4347
48+
overloads_evaluation.py:59:12: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in example2: bad return type [bad-return-type]
49+
50+
return 1
51+
\u001b[1m\u001b[31m~\u001b[39m\u001b[0m
52+
53+
overloads_evaluation.py:78:5: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in _: str [assert-type]
54+
55+
assert_type(ret1, int | str)
56+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
57+
4458
"""
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "pytype 2024.10.11"
2-
test_duration = 30.7
2+
test_duration = 31.5

conformance/results/results.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,13 @@ <h3>Python Type System Conformance Test Results</h3>
162162
<div class='tc-time'>1.7sec</div>
163163
</th>
164164
<th class='tc-header'><div class='tc-name'>pyright 1.1.391</div>
165-
<div class='tc-time'>1.5sec</div>
165+
<div class='tc-time'>1.6sec</div>
166166
</th>
167167
<th class='tc-header'><div class='tc-name'>pyre 0.9.23</div>
168-
<div class='tc-time'>6.7sec</div>
168+
<div class='tc-time'>6.1sec</div>
169169
</th>
170170
<th class='tc-header'><div class='tc-name'>pytype 2024.10.11</div>
171-
<div class='tc-time'>30.7sec</div>
171+
<div class='tc-time'>31.5sec</div>
172172
</th>
173173
</tr>
174174
<tr><th class="column" colspan="5">
@@ -694,7 +694,7 @@ <h3>Python Type System Conformance Test Results</h3>
694694
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not pick a winning overload based on arity, prior to considering argument types.</p></span></div></th>
695695
<th class="column col2 conformant">Pass</th>
696696
<th class="column col2 conformant">Pass</th>
697-
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not pick a winning overload based on arity, prior to considering argument types.</p></span></div></th>
697+
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not pick a winning overload based on arity, prior to considering argument types.</p><p>Does not perform argument expansion on unions and union return types of all matching overloads.</p></span></div></th>
698698
</tr>
699699
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;overloads_overlap</th>
700700
<th class="column col2 conformant">Pass</th>

conformance/tests/overloads_evaluation.py

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,77 @@
1010
# > overload candidates that are not plausible based on their
1111
# > input signatures.
1212

13-
# > - If no candidate overloads remain, generate an error and stop.
14-
1513
@overload
16-
def num_args(x: int, y: str) -> int:
14+
def example1(x: int, y: str) -> int:
1715
...
1816

1917
@overload
20-
def num_args(x: str) -> str:
18+
def example1(x: str) -> str:
2119
...
2220

23-
def num_args(x: int | str, y: str = "") -> int | str:
21+
def example1(x: int | str, y: str = "") -> int | str:
2422
return 1
2523

26-
num_args() # E: no matching overload
24+
# > - If no candidate overloads remain, generate an error and stop.
2725

26+
example1() # E: no matching overload
2827

2928
# > - If only one candidate overload remains, it is the winning match. Evaluate
3029
# > it as if it were a non-overloaded function call and stop.
3130

32-
ret1 = num_args(1, "")
31+
ret1 = example1(1, "")
3332
assert_type(ret1, int)
3433

35-
ret2 = num_args(1, 1) # E: Literal[1] not assignable to str
34+
ret2 = example1(1, 1) # E: Literal[1] not assignable to str
3635
assert_type(ret2, int)
3736

38-
ret3 = num_args("")
37+
ret3 = example1("")
3938
assert_type(ret3, str)
4039

41-
ret4 = num_args(1) # E: Literal[1] not assignable to str
40+
ret4 = example1(1) # E: Literal[1] not assignable to str
4241
assert_type(ret4, str)
4342

4443

44+
# > Step 2: Evaluate each remaining overload as a regular (non-overloaded)
45+
# > call to determine whether it is compatible with the supplied
46+
# > argument list. Unlike step 1, this step considers the types of the parameters
47+
# > and arguments. During this step, do not generate any user-visible errors.
48+
# > Simply record which of the overloads result in evaluation errors.
49+
50+
@overload
51+
def example2(x: int, y: str, z: int) -> str:
52+
...
53+
54+
@overload
55+
def example2(x: int, y: int, z: int) -> int:
56+
...
57+
58+
def example2(x: int, y: int | str, z: int) -> int | str:
59+
return 1
60+
61+
# > - If only one overload evaluates without error, it is the winning match.
62+
# > Evaluate it as if it were a non-overloaded function call and stop.
63+
64+
ret5 = example2(1, 2, 3)
65+
assert_type(ret5, int)
66+
67+
# > Step 3: If step 2 produces errors for all overloads, perform
68+
# > "argument type expansion". Union types can be expanded
69+
# > into their constituent subtypes. For example, the type ``int | str`` can
70+
# > be expanded into ``int`` and ``str``.
71+
72+
# > - If all argument lists evaluate successfully, combine their
73+
# > respective return types by union to determine the final return type
74+
# > for the call, and stop.
75+
76+
def _(v: int | str) -> None:
77+
ret1 = example2(1, v, 1)
78+
assert_type(ret1, int | str)
79+
80+
# > - If argument expansion has been applied to all arguments and one or
81+
# > more of the expanded argument lists cannot be evaluated successfully,
82+
# > generate an error and stop.
83+
84+
def _(v: int | str) -> None:
85+
example2(v, v, 1) # E: no overload matches (str, ..., ...)
86+

0 commit comments

Comments
 (0)