Skip to content

Commit 8875a4a

Browse files
committed
add test for final with overload
1 parent 535075f commit 8875a4a

File tree

7 files changed

+202
-53
lines changed

7 files changed

+202
-53
lines changed

conformance/results/mypy/overloads_invalid.toml

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,26 @@ notes = """
44
Does not allow an overload with no implementation in an abstract base class.
55
"""
66
errors_diff = """
7-
Line 47: Unexpected errors ['overloads_invalid.py:47: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]']
7+
Line 49: Unexpected errors ['overloads_invalid.py:49: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]']
88
"""
99
output = """
10-
overloads_invalid.py:12: error: Single overload definition, multiple required [misc]
11-
overloads_invalid.py:24: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
12-
overloads_invalid.py:47: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
13-
overloads_invalid.py:61: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
14-
overloads_invalid.py:76: error: Overload does not consistently use the "@staticmethod" decorator on all function signatures. [misc]
15-
overloads_invalid.py:86: error: Overloaded function implementation does not accept all possible arguments of signature 1 [misc]
16-
overloads_invalid.py:86: error: Overloaded function implementation does not accept all possible arguments of signature 2 [misc]
17-
overloads_invalid.py:89: error: Overload does not consistently use the "@classmethod" decorator on all function signatures. [misc]
10+
overloads_invalid.py:14: error: Single overload definition, multiple required [misc]
11+
overloads_invalid.py:26: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
12+
overloads_invalid.py:49: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
13+
overloads_invalid.py:63: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]
14+
overloads_invalid.py:78: error: Overload does not consistently use the "@staticmethod" decorator on all function signatures. [misc]
15+
overloads_invalid.py:88: error: Overloaded function implementation does not accept all possible arguments of signature 1 [misc]
16+
overloads_invalid.py:88: error: Overloaded function implementation does not accept all possible arguments of signature 2 [misc]
17+
overloads_invalid.py:91: error: Overload does not consistently use the "@classmethod" decorator on all function signatures. [misc]
18+
overloads_invalid.py:127: error: @final should be applied only to overload implementation [misc]
19+
overloads_invalid.py:139: error: @final should be applied only to overload implementation [misc]
20+
overloads_invalid.py:155: error: Cannot override final attribute "final_method" (previously declared in base class "Base") [misc]
21+
overloads_invalid.py:155: error: Signature of "final_method" incompatible with supertype "Base" [override]
22+
overloads_invalid.py:155: note: Superclass:
23+
overloads_invalid.py:155: note: @overload
24+
overloads_invalid.py:155: note: def final_method(self, x: int) -> int
25+
overloads_invalid.py:155: note: @overload
26+
overloads_invalid.py:155: note: def final_method(self, x: str) -> str
27+
overloads_invalid.py:155: note: Subclass:
28+
overloads_invalid.py:155: note: def final_method(self, x: int | str) -> int | str
1829
"""

conformance/results/pyre/overloads_invalid.toml

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,26 @@ conformant = "Partial"
22
conformance_automated = "Fail"
33
notes = """
44
Does not allow an overload with no implementation in a Protocol or an abstract base class.
5+
Expects @final on all overloads and implementation, instead of implementation only.
56
"""
67
errors_diff = """
7-
Line 38: Unexpected errors ['overloads_invalid.py:38:4 Missing overload implementation [42]: Overloaded function `MyProto.func3` must have an implementation.']
8-
Line 49: Unexpected errors ['overloads_invalid.py:49:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.func4` must have an implementation.']
8+
Lines 139, 141: Expected error (tag 'invalid_final_2')
9+
Line 40: Unexpected errors ['overloads_invalid.py:40:4 Missing overload implementation [42]: Overloaded function `MyProto.func3` must have an implementation.']
10+
Line 51: Unexpected errors ['overloads_invalid.py:51:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.func4` must have an implementation.']
11+
Line 124: Unexpected errors ['overloads_invalid.py:124:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).']
912
"""
1013
output = """
11-
overloads_invalid.py:13:0 Incompatible overload [43]: At least two overload signatures must be present.
12-
overloads_invalid.py:25:0 Missing overload implementation [42]: Overloaded function `func2` must have an implementation.
13-
overloads_invalid.py:38:4 Missing overload implementation [42]: Overloaded function `MyProto.func3` must have an implementation.
14-
overloads_invalid.py:49:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.func4` must have an implementation.
15-
overloads_invalid.py:62:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.not_abstract` must have an implementation.
16-
overloads_invalid.py:78:4 Incompatible overload [43]: The implementation of `C.func5` does not accept all possible arguments of overload defined on line `78`.
17-
overloads_invalid.py:83:4 Incompatible overload [43]: The implementation of `C.func5` does not accept all possible arguments of overload defined on line `83`.
18-
overloads_invalid.py:86:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
19-
overloads_invalid.py:91:4 Incompatible overload [43]: The implementation of `C.func6` does not accept all possible arguments of overload defined on line `91`.
20-
overloads_invalid.py:96:4 Incompatible overload [43]: The implementation of `C.func6` does not accept all possible arguments of overload defined on line `96`.
21-
overloads_invalid.py:99:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
14+
overloads_invalid.py:15:0 Incompatible overload [43]: At least two overload signatures must be present.
15+
overloads_invalid.py:27:0 Missing overload implementation [42]: Overloaded function `func2` must have an implementation.
16+
overloads_invalid.py:40:4 Missing overload implementation [42]: Overloaded function `MyProto.func3` must have an implementation.
17+
overloads_invalid.py:51:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.func4` must have an implementation.
18+
overloads_invalid.py:64:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.not_abstract` must have an implementation.
19+
overloads_invalid.py:80:4 Incompatible overload [43]: The implementation of `C.func5` does not accept all possible arguments of overload defined on line `80`.
20+
overloads_invalid.py:85:4 Incompatible overload [43]: The implementation of `C.func5` does not accept all possible arguments of overload defined on line `85`.
21+
overloads_invalid.py:88:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
22+
overloads_invalid.py:97:4 Incompatible overload [43]: The implementation of `C.func6` does not accept all possible arguments of overload defined on line `97`.
23+
overloads_invalid.py:97:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
24+
overloads_invalid.py:124:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
25+
overloads_invalid.py:133:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
26+
overloads_invalid.py:155:4 Invalid override [40]: `overloads_invalid.Child.final_method` cannot override final method defined in `Base`.
2227
"""
Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
1-
conformant = "Pass"
2-
conformance_automated = "Pass"
1+
conformant = "Partial"
2+
notes = """
3+
Allows @final on all overloads and implementation; should be implementation-only.
4+
"""
5+
conformance_automated = "Fail"
36
errors_diff = """
7+
Lines 139, 141: Expected error (tag 'invalid_final_2')
48
"""
59
output = """
6-
overloads_invalid.py:13:5 - error: "func1" is marked as overload, but additional overloads are missing (reportInconsistentOverload)
7-
overloads_invalid.py:25:5 - error: "func2" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)
8-
overloads_invalid.py:62:9 - error: "not_abstract" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)
9-
overloads_invalid.py:78:9 - error: Overloads for "func5" use @staticmethod inconsistently (reportInconsistentOverload)
10-
overloads_invalid.py:86:9 - error: Overloaded implementation is not consistent with signature of overload 1
10+
overloads_invalid.py:15:5 - error: "func1" is marked as overload, but additional overloads are missing (reportInconsistentOverload)
11+
overloads_invalid.py:27:5 - error: "func2" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)
12+
overloads_invalid.py:64:9 - error: "not_abstract" is marked as overload, but no implementation is provided (reportNoOverloadImplementation)
13+
overloads_invalid.py:80:9 - error: Overloads for "func5" use @staticmethod inconsistently (reportInconsistentOverload)
14+
overloads_invalid.py:88:9 - error: Overloaded implementation is not consistent with signature of overload 1
1115
  Type "(self: Self@C, x: int | str) -> (int | str)" is not assignable to type "(x: int) -> int"
1216
    Parameter name mismatch: "x" versus "self"
1317
    Parameter 1: type "int" is incompatible with type "Self@C"
1418
      Type "int" is not assignable to type "Self@C"
1519
    Extra parameter "x" (reportInconsistentOverload)
16-
overloads_invalid.py:86:9 - error: Overloaded implementation is not consistent with signature of overload 2
20+
overloads_invalid.py:88:9 - error: Overloaded implementation is not consistent with signature of overload 2
1721
  Type "(self: Self@C, x: int | str) -> (int | str)" is not assignable to type "(x: str) -> str"
1822
    Parameter name mismatch: "x" versus "self"
1923
    Parameter 1: type "str" is incompatible with type "Self@C"
2024
      Type "str" is not assignable to type "Self@C"
2125
    Extra parameter "x" (reportInconsistentOverload)
22-
overloads_invalid.py:91:9 - error: Overloads for "func6" use @classmethod inconsistently (reportInconsistentOverload)
23-
overloads_invalid.py:99:15 - warning: Instance methods should take a "self" parameter (reportSelfClsParameterName)
26+
overloads_invalid.py:93:9 - error: Overloads for "func6" use @classmethod inconsistently (reportInconsistentOverload)
27+
overloads_invalid.py:97:15 - warning: Instance methods should take a "self" parameter (reportSelfClsParameterName)
28+
overloads_invalid.py:129:9 - error: Overload for "invalid_final" is marked @final but implementation is not (reportInconsistentOverload)
29+
overloads_invalid.py:155:9 - error: Method "final_method" cannot override final method defined in class "Base" (reportIncompatibleMethodOverride)
30+
overloads_invalid.py:155:9 - error: Method "final_method" overrides class "Base" in an incompatible manner
31+
  Return type mismatch: base method returns type "int", override returns type "int | str"
32+
    Type "int | str" is not assignable to type "int"
33+
      "str" is not assignable to "int" (reportIncompatibleMethodOverride)
2434
"""

conformance/results/pytype/overloads_invalid.toml

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,109 @@ Does not reject a function with a single @overload signature.
44
Does not reject a function with @overload signature but no implementation.
55
Does not allow an overload with no implementation in a Protocol or an abstract base class.
66
Does not error on overloads inconsistently decorated with `@staticmethod` or `@classmethod`.
7+
Does not enforce any rules on location of @final decorator.
78
"""
89
conformance_automated = "Fail"
910
errors_diff = """
10-
Lines 12, 13: Expected error (tag 'func1')
11-
Lines 24, 25: Expected error (tag 'func2')
12-
Lines 61, 62: Expected error (tag 'not_abstract')
13-
Lines 76, 78, 83, 86: Expected error (tag 'func5')
14-
Lines 89, 91, 96, 99: Expected error (tag 'func6')
15-
Line 44: Unexpected errors ["overloads_invalid.py:44:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func3: @typing.overload-decorated 'MyProto.func3' object is not callable [not-callable]"]
16-
Line 56: Unexpected errors ["overloads_invalid.py:56:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func4: @typing.overload-decorated 'MyAbstractBase.func4' object is not callable [not-callable]"]
17-
Line 68: Unexpected errors ["overloads_invalid.py:68:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in not_abstract: @typing.overload-decorated 'MyAbstractBase.not_abstract' object is not callable [not-callable]"]
18-
Line 79: Unexpected errors ['overloads_invalid.py:79:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func5: bad return type [bad-return-type]']
19-
Line 84: Unexpected errors ['overloads_invalid.py:84:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func5: bad return type [bad-return-type]']
11+
Lines 14, 15: Expected error (tag 'func1')
12+
Lines 26, 27: Expected error (tag 'func2')
13+
Lines 63, 64: Expected error (tag 'not_abstract')
14+
Lines 78, 80, 85, 88: Expected error (tag 'func5')
15+
Lines 91, 93, 97, 101: Expected error (tag 'func6')
16+
Lines 127, 129, 133: Expected error (tag 'invalid_final')
17+
Lines 139, 141: Expected error (tag 'invalid_final_2')
18+
Line 6: Unexpected errors ['overloads_invalid.py:6:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in <module>: typing.override not supported yet [not-supported-yet]']
19+
Line 46: Unexpected errors ["overloads_invalid.py:46:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func3: @typing.overload-decorated 'MyProto.func3' object is not callable [not-callable]"]
20+
Line 58: Unexpected errors ["overloads_invalid.py:58:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func4: @typing.overload-decorated 'MyAbstractBase.func4' object is not callable [not-callable]"]
21+
Line 70: Unexpected errors ["overloads_invalid.py:70:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in not_abstract: @typing.overload-decorated 'MyAbstractBase.not_abstract' object is not callable [not-callable]"]
22+
Line 81: Unexpected errors ['overloads_invalid.py:81:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func5: bad return type [bad-return-type]']
23+
Line 86: Unexpected errors ['overloads_invalid.py:86:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in func5: bad return type [bad-return-type]']
24+
Line 125: Unexpected errors ['overloads_invalid.py:125:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in final_method: bad return type [bad-return-type]', 'overloads_invalid.py:125:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in final_method: bad return type [bad-return-type]']
25+
Line 137: Unexpected errors ['overloads_invalid.py:137:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final: bad return type [bad-return-type]', 'overloads_invalid.py:137:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final: bad return type [bad-return-type]']
26+
Line 151: Unexpected errors ['overloads_invalid.py:151:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final_2: bad return type [bad-return-type]', 'overloads_invalid.py:151:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final_2: bad return type [bad-return-type]']
27+
Line 156: Unexpected errors ['overloads_invalid.py:156:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in final_method: bad return type [bad-return-type]']
2028
"""
2129
output = """
22-
overloads_invalid.py:44:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func3: @typing.overload-decorated 'MyProto.func3' object is not callable [not-callable]
30+
overloads_invalid.py:6:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: typing.override not supported yet [not-supported-yet]
31+
32+
from typing import (
33+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
34+
final,
35+
\u001b[1m\u001b[31m~~~~~~~~~~\u001b[39m\u001b[0m
36+
Protocol,
37+
\u001b[1m\u001b[31m~~~~~~~~~~~~~\u001b[39m\u001b[0m
38+
overload,
39+
\u001b[1m\u001b[31m~~~~~~~~~~~~~\u001b[39m\u001b[0m
40+
override,
41+
\u001b[1m\u001b[31m~~~~~~~~~~~~~\u001b[39m\u001b[0m
42+
)
43+
\u001b[1m\u001b[31m~\u001b[39m\u001b[0m
44+
45+
overloads_invalid.py:46:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func3: @typing.overload-decorated 'MyProto.func3' object is not callable [not-callable]
2346
2447
...
2548
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
2649
27-
overloads_invalid.py:56:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func4: @typing.overload-decorated 'MyAbstractBase.func4' object is not callable [not-callable]
50+
overloads_invalid.py:58:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func4: @typing.overload-decorated 'MyAbstractBase.func4' object is not callable [not-callable]
2851
2952
...
3053
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
3154
32-
overloads_invalid.py:68:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in not_abstract: @typing.overload-decorated 'MyAbstractBase.not_abstract' object is not callable [not-callable]
55+
overloads_invalid.py:70:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in not_abstract: @typing.overload-decorated 'MyAbstractBase.not_abstract' object is not callable [not-callable]
3356
3457
...
3558
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
3659
37-
overloads_invalid.py:79:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func5: bad return type [bad-return-type]
60+
overloads_invalid.py:81:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func5: bad return type [bad-return-type]
3861
3962
...
4063
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
4164
42-
overloads_invalid.py:84:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func5: bad return type [bad-return-type]
65+
overloads_invalid.py:86:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in func5: bad return type [bad-return-type]
66+
67+
...
68+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
69+
70+
overloads_invalid.py:125:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in final_method: bad return type [bad-return-type]
71+
72+
...
73+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
74+
75+
overloads_invalid.py:125:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in final_method: bad return type [bad-return-type]
76+
77+
...
78+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
79+
80+
overloads_invalid.py:137:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in invalid_final: bad return type [bad-return-type]
81+
82+
...
83+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
84+
85+
overloads_invalid.py:137:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in invalid_final: bad return type [bad-return-type]
86+
87+
...
88+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
89+
90+
overloads_invalid.py:151:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in invalid_final_2: bad return type [bad-return-type]
91+
92+
...
93+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
94+
95+
overloads_invalid.py:151:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in invalid_final_2: bad return type [bad-return-type]
96+
97+
...
98+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
99+
100+
overloads_invalid.py:154:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: Class Child overrides final method final_method, defined in base class Base [final-error]
101+
102+
class Child(Base): # E[override-final]
103+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
104+
def final_method(self, x: int | str) -> int | str: # E[override-final] can't override final method
105+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
106+
...
107+
\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m
108+
109+
overloads_invalid.py:156:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in final_method: bad return type [bad-return-type]
43110
44111
...
45112
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
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 = 29.9
2+
test_duration = 30.4

0 commit comments

Comments
 (0)