Skip to content

Commit 57495db

Browse files
committed
(very) initial steps on conformance tests
1 parent eed0815 commit 57495db

File tree

10 files changed

+180
-52
lines changed

10 files changed

+180
-52
lines changed
Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
conformant = "Pass"
1+
conformant = "Partial"
2+
notes = """
3+
Does not allow an overload with no implementation in an abstract base class.
4+
"""
25
output = """
3-
overloads_basic.py:37: error: No overload variant of "__getitem__" of "Bytes" matches argument type "str" [call-overload]
4-
overloads_basic.py:37: note: Possible overload variants:
5-
overloads_basic.py:37: note: def __getitem__(self, int, /) -> int
6-
overloads_basic.py:37: note: def __getitem__(self, slice[Any, Any, Any], /) -> bytes
7-
overloads_basic.py:62: error: Single overload definition, multiple required [misc]
8-
overloads_basic.py:74: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
6+
overloads_basic.py:41: error: No overload variant of "__getitem__" of "Bytes" matches argument type "str" [call-overload]
7+
overloads_basic.py:41: note: Possible overload variants:
8+
overloads_basic.py:41: note: def __getitem__(self, int, /) -> int
9+
overloads_basic.py:41: note: def __getitem__(self, slice[Any, Any, Any], /) -> bytes
10+
overloads_basic.py:66: error: Single overload definition, multiple required [misc]
11+
overloads_basic.py:78: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
12+
overloads_basic.py:101: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
13+
overloads_basic.py:116: error: Overload does not consistently use the "@staticmethod" decorator on all function signatures. [misc]
14+
overloads_basic.py:126: error: Overloaded function implementation does not accept all possible arguments of signature 1 [misc]
15+
overloads_basic.py:126: error: Overloaded function implementation does not accept all possible arguments of signature 2 [misc]
16+
overloads_basic.py:129: error: Overload does not consistently use the "@classmethod" decorator on all function signatures. [misc]
917
"""
10-
conformance_automated = "Pass"
18+
conformance_automated = "Fail"
1119
errors_diff = """
20+
Line 101: Unexpected errors ['overloads_basic.py:101: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]']
1221
"""
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version = "mypy 1.14.0"
2-
test_duration = 1.6
1+
version = "mypy 1.14.1"
2+
test_duration = 1.7
Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
1-
conformant = "Pass"
1+
conformant = "Partial"
22
notes = """
3+
Does not allow an overload with no implementation in a Protocol or an abstract base class.
34
"""
45
output = """
5-
overloads_basic.py:37:2 Incompatible parameter type [6]: In call `Bytes.__getitem__`, for 1st positional argument, expected `int` but got `str`.
6-
overloads_basic.py:63:0 Incompatible overload [43]: At least two overload signatures must be present.
7-
overloads_basic.py:75:0 Missing overload implementation [42]: Overloaded function `func2` must have an implementation.
6+
overloads_basic.py:41:2 Incompatible parameter type [6]: In call `Bytes.__getitem__`, for 1st positional argument, expected `int` but got `str`.
7+
overloads_basic.py:67:0 Incompatible overload [43]: At least two overload signatures must be present.
8+
overloads_basic.py:79:0 Missing overload implementation [42]: Overloaded function `func2` must have an implementation.
9+
overloads_basic.py:92:4 Missing overload implementation [42]: Overloaded function `MyProto.func3` must have an implementation.
10+
overloads_basic.py:102:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.func4` must have an implementation.
11+
overloads_basic.py:118:4 Incompatible overload [43]: The implementation of `C.func5` does not accept all possible arguments of overload defined on line `118`.
12+
overloads_basic.py:123:4 Incompatible overload [43]: The implementation of `C.func5` does not accept all possible arguments of overload defined on line `123`.
13+
overloads_basic.py:126:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
14+
overloads_basic.py:131:4 Incompatible overload [43]: The implementation of `C.func6` does not accept all possible arguments of overload defined on line `131`.
15+
overloads_basic.py:136:4 Incompatible overload [43]: The implementation of `C.func6` does not accept all possible arguments of overload defined on line `136`.
16+
overloads_basic.py:139:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
817
"""
9-
conformance_automated = "Pass"
18+
conformance_automated = "Fail"
1019
errors_diff = """
20+
Line 92: Unexpected errors ['overloads_basic.py:92:4 Missing overload implementation [42]: Overloaded function `MyProto.func3` must have an implementation.']
21+
Line 102: Unexpected errors ['overloads_basic.py:102:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.func4` must have an implementation.']
1122
"""
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 = 7.3
2+
test_duration = 5.9
Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
1-
conformant = "Pass"
1+
conformant = "Partial"
2+
notes = """
3+
Does not allow an overload with no implementation in an abstract base class.
4+
"""
25
output = """
3-
overloads_basic.py:37:1 - error: No overloads for "__getitem__" match the provided arguments (reportCallIssue)
4-
overloads_basic.py:37:1 - error: Argument of type "Literal['']" cannot be assigned to parameter "__s" of type "slice[Any, Any, Any]" in function "__getitem__"
6+
overloads_basic.py:41:1 - error: No overloads for "__getitem__" match the provided arguments (reportCallIssue)
7+
overloads_basic.py:41:1 - error: Argument of type "Literal['']" cannot be assigned to parameter "__s" of type "slice[Any, Any, Any]" in function "__getitem__"
58
  "Literal['']" is not assignable to "slice[Any, Any, Any]" (reportArgumentType)
6-
overloads_basic.py:63:5 - error: "func1" is marked as overload, but additional overloads are missing (reportInconsistentOverload)
7-
overloads_basic.py:75:5 - error: "func2" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)
9+
overloads_basic.py:67:5 - error: "func1" is marked as overload, but additional overloads are missing (reportInconsistentOverload)
10+
overloads_basic.py:79:5 - error: "func2" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)
11+
overloads_basic.py:102:9 - error: "func4" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)
12+
overloads_basic.py:118:9 - error: Overloads for "func5" use @staticmethod inconsistently (reportInconsistentOverload)
13+
overloads_basic.py:126:9 - error: Overloaded implementation is not consistent with signature of overload 1
14+
  Type "(self: Self@C, x: int | str) -> (int | str)" is not assignable to type "(x: int) -> int"
15+
    Parameter name mismatch: "x" versus "self"
16+
    Parameter 1: type "int" is incompatible with type "Self@C"
17+
      Type "int" is not assignable to type "Self@C"
18+
    Extra parameter "x" (reportInconsistentOverload)
19+
overloads_basic.py:126:9 - error: Overloaded implementation is not consistent with signature of overload 2
20+
  Type "(self: Self@C, x: int | str) -> (int | str)" is not assignable to type "(x: str) -> str"
21+
    Parameter name mismatch: "x" versus "self"
22+
    Parameter 1: type "str" is incompatible with type "Self@C"
23+
      Type "str" is not assignable to type "Self@C"
24+
    Extra parameter "x" (reportInconsistentOverload)
25+
overloads_basic.py:131:9 - error: Overloads for "func6" use @classmethod inconsistently (reportInconsistentOverload)
26+
overloads_basic.py:139:15 - warning: Instance methods should take a "self" parameter (reportSelfClsParameterName)
827
"""
9-
conformance_automated = "Pass"
28+
conformance_automated = "Fail"
1029
errors_diff = """
30+
Line 102: Unexpected errors ['overloads_basic.py:102:9 - error: "func4" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)']
1131
"""
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.2
2+
test_duration = 1.5

conformance/results/pytype/overloads_basic.toml

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,57 @@ conformant = "Partial"
22
notes = """
33
Does not reject a function with a single @overload signature.
44
Does not reject a function with @overload signature but no implementation.
5+
Does not allow an overload with no implementation in a Protocol or an abstract base class.
6+
Does not exempt overloads from checking of return type in body, when also decorated with `@staticmethod`.
7+
Does not error on overloads inconsistently decorated with `@staticmethod` or `@classmethod`.
58
"""
69
output = """
7-
overloads_basic.py:31:20: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in __getitem__: bad return type [bad-return-type]
10+
overloads_basic.py:35:20: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in __getitem__: bad return type [bad-return-type]
811
912
return b""
1013
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
1114
12-
overloads_basic.py:37:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: unsupported operand type(s) for item retrieval: Bytes and str [unsupported-operands]
15+
overloads_basic.py:41:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: unsupported operand type(s) for item retrieval: Bytes and str [unsupported-operands]
1316
1417
b[""] # E: no matching overload
1518
\u001b[1m\u001b[31m~~~~~\u001b[39m\u001b[0m
1619
17-
overloads_basic.py:58:5: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in map: bad return type [bad-return-type]
20+
overloads_basic.py:62:5: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in map: bad return type [bad-return-type]
1821
1922
pass
2023
\u001b[1m\u001b[31m~~~~\u001b[39m\u001b[0m
2124
25+
overloads_basic.py:98:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func3: @typing.overload-decorated 'MyProto.func3' object is not callable [not-callable]
26+
27+
...
28+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
29+
30+
overloads_basic.py:108:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func4: @typing.overload-decorated 'MyAbstractBase.func4' object is not callable [not-callable]
31+
32+
...
33+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
34+
35+
overloads_basic.py:119:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func5: bad return type [bad-return-type]
36+
37+
...
38+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
39+
40+
overloads_basic.py:124:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func5: bad return type [bad-return-type]
41+
42+
...
43+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
44+
2245
"""
2346
conformance_automated = "Fail"
2447
errors_diff = """
25-
Lines 62, 63: Expected error (tag 'func1')
26-
Lines 74, 75: Expected error (tag 'func2')
27-
Line 31: Unexpected errors ['overloads_basic.py:31:20: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in __getitem__: bad return type [bad-return-type]']
28-
Line 58: Unexpected errors ['overloads_basic.py:58:5: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in map: bad return type [bad-return-type]']
48+
Lines 66, 67: Expected error (tag 'func1')
49+
Lines 78, 79: Expected error (tag 'func2')
50+
Lines 116, 118, 123, 126: Expected error (tag 'func5')
51+
Lines 129, 131, 136, 139: Expected error (tag 'func6')
52+
Line 35: Unexpected errors ['overloads_basic.py:35:20: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in __getitem__: bad return type [bad-return-type]']
53+
Line 62: Unexpected errors ['overloads_basic.py:62:5: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in map: bad return type [bad-return-type]']
54+
Line 98: Unexpected errors ["overloads_basic.py:98:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func3: @typing.overload-decorated 'MyProto.func3' object is not callable [not-callable]"]
55+
Line 108: Unexpected errors ["overloads_basic.py:108:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func4: @typing.overload-decorated 'MyAbstractBase.func4' object is not callable [not-callable]"]
56+
Line 119: Unexpected errors ['overloads_basic.py:119:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func5: bad return type [bad-return-type]']
57+
Line 124: Unexpected errors ['overloads_basic.py:124:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func5: bad return type [bad-return-type]']
2958
"""
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 = 37.2
2+
test_duration = 30.3

conformance/results/results.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,17 @@ <h3>Python Type System Conformance Test Results</h3>
158158
</header>
159159
<div class="table_container"><table><tbody>
160160
<tr><th class="col1">&nbsp;</th>
161-
<th class='tc-header'><div class='tc-name'>mypy 1.14.0</div>
162-
<div class='tc-time'>1.6sec</div>
161+
<th class='tc-header'><div class='tc-name'>mypy 1.14.1</div>
162+
<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.2sec</div>
165+
<div class='tc-time'>1.5sec</div>
166166
</th>
167167
<th class='tc-header'><div class='tc-name'>pyre 0.9.23</div>
168-
<div class='tc-time'>7.3sec</div>
168+
<div class='tc-time'>5.9sec</div>
169169
</th>
170170
<th class='tc-header'><div class='tc-name'>pytype 2024.10.11</div>
171-
<div class='tc-time'>37.2sec</div>
171+
<div class='tc-time'>30.3sec</div>
172172
</th>
173173
</tr>
174174
<tr><th class="column" colspan="5">
@@ -667,10 +667,10 @@ <h3>Python Type System Conformance Test Results</h3>
667667
<a class="test_group" href="https://typing.readthedocs.io/en/latest/spec/overload.html">Overloads</a>
668668
</th></tr>
669669
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;overloads_basic</th>
670-
<th class="column col2 conformant">Pass</th>
671-
<th class="column col2 conformant">Pass</th>
672-
<th class="column col2 conformant">Pass</th>
673-
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not reject a function with a single @overload signature.</p><p>Does not reject a function with @overload signature but no implementation.</p></span></div></th>
670+
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not allow an overload with no implementation in an abstract base class.</p></span></div></th>
671+
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not allow an overload with no implementation in an abstract base class.</p></span></div></th>
672+
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not allow an overload with no implementation in a Protocol or an abstract base class.</p></span></div></th>
673+
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not reject a function with a single @overload signature.</p><p>Does not reject a function with @overload signature but no implementation.</p><p>Does not allow an overload with no implementation in a Protocol or an abstract base class.</p><p>Does not exempt overloads from checking of return type in body, when also decorated with `@staticmethod`.</p><p>Does not error on overloads inconsistently decorated with `@staticmethod`.</p></span></div></th>
674674
</tr>
675675
<tr><th class="column" colspan="5">
676676
<a class="test_group" href="https://typing.readthedocs.io/en/latest/spec/exceptions.html">Exceptions</a>

conformance/tests/overloads_basic.py

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
"""
2-
Tests the basic typing.overload behavior described in PEP 484.
2+
Tests the behavior of typing.overload.
33
"""
44

55
# Specification: https://typing.readthedocs.io/en/latest/spec/overload.html#overload
66

7-
# Note: The behavior of @overload is severely under-specified by PEP 484 leading
8-
# to significant divergence in behavior across type checkers. This is something
9-
# we will likely want to address in a future update to the typing spec. For now,
10-
# this conformance test will cover only the most basic functionality described
11-
# in PEP 484.
12-
13-
from typing import Any, Callable, Iterable, Iterator, TypeVar, assert_type, overload
7+
from abc import ABC
8+
from typing import (
9+
Any,
10+
Callable,
11+
Iterable,
12+
Iterator,
13+
Protocol,
14+
TypeVar,
15+
assert_type,
16+
overload,
17+
)
1418

1519

1620
class Bytes:
@@ -58,7 +62,7 @@ def map(func: Any, iter1: Any, iter2: Any = ...) -> Any:
5862
pass
5963

6064

61-
# At least two overload signatures should be provided.
65+
# > At least two @overload-decorated definitions must be present.
6266
@overload # E[func1]
6367
def func1() -> None: # E[func1]: At least two overloads must be present
6468
...
@@ -68,9 +72,9 @@ def func1() -> None:
6872
pass
6973

7074

71-
# > In regular modules, a series of @overload-decorated definitions must be
72-
# > followed by exactly one non-@overload-decorated definition (for the same
73-
# > function/method).
75+
# > The ``@overload``-decorated definitions must be followed by an overload
76+
# > implementation, which does not include an ``@overload`` decorator. Type
77+
# > checkers should report an error or warning if an implementation is missing.
7478
@overload # E[func2]
7579
def func2(x: int) -> int: # E[func2]: no implementation
7680
...
@@ -79,3 +83,58 @@ def func2(x: int) -> int: # E[func2]: no implementation
7983
@overload
8084
def func2(x: str) -> str:
8185
...
86+
87+
88+
# > Overload definitions within stub files, protocols, and abstract base classes
89+
# > are exempt from this check.
90+
class MyProto(Protocol):
91+
@overload
92+
def func3(self, x: int) -> int:
93+
...
94+
95+
96+
@overload
97+
def func3(self, x: str) -> str:
98+
...
99+
100+
class MyAbstractBase(ABC):
101+
@overload
102+
def func4(self, x: int) -> int:
103+
...
104+
105+
106+
@overload
107+
def func4(self, x: str) -> str:
108+
...
109+
110+
111+
# > If one overload signature is decorated with ``@staticmethod`` or
112+
# > ``@classmethod``, all overload signatures must be similarly decorated. The
113+
# > implementation, if present, must also have a consistent decorator. Type
114+
# > checkers should report an error if these conditions are not met.
115+
class C:
116+
@overload # E[func5]
117+
@staticmethod
118+
def func5(x: int) -> int: # E[func5]
119+
...
120+
121+
@overload
122+
@staticmethod
123+
def func5(x: str) -> str: # E[func5]
124+
...
125+
126+
def func5(self, x: int | str) -> int | str: # E[func5]
127+
return 1
128+
129+
@overload # E[func6]
130+
@classmethod
131+
def func6(cls, x: int) -> int: # E[func6]
132+
...
133+
134+
@overload
135+
@classmethod
136+
def func6(cls, x: str) -> str: # E[func6]
137+
...
138+
139+
def func6(cls, x: int | str) -> int | str: # E[func6]
140+
return 1

0 commit comments

Comments
 (0)