Skip to content

Commit 5eabe53

Browse files
committed
add test for wrong use of override with overload
1 parent cb04dd6 commit 5eabe53

File tree

8 files changed

+129
-46
lines changed

8 files changed

+129
-46
lines changed

conformance/results/mypy/overloads_invalid.toml

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Does not allow an overload with no implementation in an abstract base class.
55
"""
66
errors_diff = """
77
Line 49: Unexpected errors ['overloads_invalid.py:49: error: An overloaded function outside a stub file must have an implementation [no-overload-impl]']
8-
Line 199: Unexpected errors ['overloads_invalid.py:199: error: Signature of "good_override" incompatible with supertype "Base" [override]']
8+
Line 202: Unexpected errors ['overloads_invalid.py:202: error: Signature of "good_override" incompatible with supertype "Base" [override]']
99
"""
1010
output = """
1111
overloads_invalid.py:14: error: Single overload definition, multiple required [misc]
@@ -18,22 +18,30 @@ overloads_invalid.py:88: error: Overloaded function implementation does not acce
1818
overloads_invalid.py:91: error: Overload does not consistently use the "@classmethod" decorator on all function signatures. [misc]
1919
overloads_invalid.py:133: error: @final should be applied only to overload implementation [misc]
2020
overloads_invalid.py:148: error: @final should be applied only to overload implementation [misc]
21-
overloads_invalid.py:173: error: Cannot override final attribute "final_method" (previously declared in base class "Base") [misc]
22-
overloads_invalid.py:173: error: Signature of "final_method" incompatible with supertype "Base" [override]
23-
overloads_invalid.py:173: note: Superclass:
24-
overloads_invalid.py:173: note: @overload
25-
overloads_invalid.py:173: note: def final_method(self, x: int) -> int
26-
overloads_invalid.py:173: note: @overload
27-
overloads_invalid.py:173: note: def final_method(self, x: str) -> str
28-
overloads_invalid.py:173: note: Subclass:
29-
overloads_invalid.py:173: note: def final_method(self, x: int | str) -> int | str
30-
overloads_invalid.py:180: error: Method "bad_override" is marked as an override, but no base method was found with this name [misc]
31-
overloads_invalid.py:199: error: Signature of "good_override" incompatible with supertype "Base" [override]
32-
overloads_invalid.py:199: note: Superclass:
33-
overloads_invalid.py:199: note: def good_override(self, x: int | str) -> int | str
34-
overloads_invalid.py:199: note: Subclass:
35-
overloads_invalid.py:199: note: @overload
36-
overloads_invalid.py:199: note: def good_override(self, x: int) -> int
37-
overloads_invalid.py:199: note: @overload
38-
overloads_invalid.py:199: note: def good_override(self, x: str) -> str
21+
overloads_invalid.py:176: error: Cannot override final attribute "final_method" (previously declared in base class "Base") [misc]
22+
overloads_invalid.py:176: error: Signature of "final_method" incompatible with supertype "Base" [override]
23+
overloads_invalid.py:176: note: Superclass:
24+
overloads_invalid.py:176: note: @overload
25+
overloads_invalid.py:176: note: def final_method(self, x: int) -> int
26+
overloads_invalid.py:176: note: @overload
27+
overloads_invalid.py:176: note: def final_method(self, x: str) -> str
28+
overloads_invalid.py:176: note: Subclass:
29+
overloads_invalid.py:176: note: def final_method(self, x: int | str) -> int | str
30+
overloads_invalid.py:183: error: Method "bad_override" is marked as an override, but no base method was found with this name [misc]
31+
overloads_invalid.py:202: error: Signature of "good_override" incompatible with supertype "Base" [override]
32+
overloads_invalid.py:202: note: Superclass:
33+
overloads_invalid.py:202: note: def good_override(self, x: int | str) -> int | str
34+
overloads_invalid.py:202: note: Subclass:
35+
overloads_invalid.py:202: note: @overload
36+
overloads_invalid.py:202: note: def good_override(self, x: int) -> int
37+
overloads_invalid.py:202: note: @overload
38+
overloads_invalid.py:202: note: def good_override(self, x: str) -> str
39+
overloads_invalid.py:217: error: Signature of "to_override" incompatible with supertype "Base" [override]
40+
overloads_invalid.py:217: note: Superclass:
41+
overloads_invalid.py:217: note: def to_override(self, x: int | str) -> int | str
42+
overloads_invalid.py:217: note: Subclass:
43+
overloads_invalid.py:217: note: @overload
44+
overloads_invalid.py:217: note: def to_override(self, x: int) -> int
45+
overloads_invalid.py:217: note: @overload
46+
overloads_invalid.py:217: note: def to_override(self, x: str) -> str
3947
"""

conformance/results/pyre/overloads_invalid.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ Does not allow an overload with no implementation in a Protocol or an abstract b
55
Expects @final/@override on all overloads and implementation, instead of implementation only.
66
"""
77
errors_diff = """
8+
Line 217: Expected 1 errors
89
Lines 148, 150: Expected error (tag 'invalid_final_2')
910
Line 40: Unexpected errors ['overloads_invalid.py:40:4 Missing overload implementation [42]: Overloaded function `MyProto.func3` must have an implementation.']
1011
Line 51: Unexpected errors ['overloads_invalid.py:51:4 Missing overload implementation [42]: Overloaded function `MyAbstractBase.func4` must have an implementation.']
1112
Line 128: Unexpected errors ['overloads_invalid.py:128:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).']
12-
Line 208: Unexpected errors ['overloads_invalid.py:208:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).']
13+
Line 211: Unexpected errors ['overloads_invalid.py:211:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).']
1314
"""
1415
output = """
1516
overloads_invalid.py:15:0 Incompatible overload [43]: At least two overload signatures must be present.
@@ -24,8 +25,8 @@ overloads_invalid.py:97:4 Incompatible overload [43]: The implementation of `C.f
2425
overloads_invalid.py:97:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
2526
overloads_invalid.py:128:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
2627
overloads_invalid.py:139:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
27-
overloads_invalid.py:173:4 Invalid override [40]: `overloads_invalid.Child.final_method` cannot override final method defined in `Base`.
28-
overloads_invalid.py:189:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
29-
overloads_invalid.py:189:4 Invalid override [40]: `overloads_invalid.Child.bad_override` is decorated with @override, but no method of the same name exists in superclasses of `Child`.
30-
overloads_invalid.py:208:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
28+
overloads_invalid.py:176:4 Invalid override [40]: `overloads_invalid.Child.final_method` cannot override final method defined in `Base`.
29+
overloads_invalid.py:192:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
30+
overloads_invalid.py:192:4 Invalid override [40]: `overloads_invalid.Child.bad_override` is decorated with @override, but no method of the same name exists in superclasses of `Child`.
31+
overloads_invalid.py:211:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s).
3132
"""

conformance/results/pyright/overloads_invalid.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
conformant = "Partial"
22
notes = """
3-
Allows @final on all overloads and implementation; should be implementation-only.
3+
Allows @final/@override on all overloads and implementation; should be implementation-only.
44
"""
55
conformance_automated = "Fail"
66
errors_diff = """
7+
Line 217: Expected 1 errors
78
Lines 148, 150: Expected error (tag 'invalid_final_2')
89
"""
910
output = """
@@ -26,10 +27,10 @@ overloads_invalid.py:88:9 - error: Overloaded implementation is not consistent w
2627
overloads_invalid.py:93:9 - error: Overloads for "func6" use @classmethod inconsistently (reportInconsistentOverload)
2728
overloads_invalid.py:97:15 - warning: Instance methods should take a "self" parameter (reportSelfClsParameterName)
2829
overloads_invalid.py:135:9 - error: Overload for "invalid_final" is marked @final but implementation is not (reportInconsistentOverload)
29-
overloads_invalid.py:173:9 - error: Method "final_method" cannot override final method defined in class "Base" (reportIncompatibleMethodOverride)
30-
overloads_invalid.py:173:9 - error: Method "final_method" overrides class "Base" in an incompatible manner
30+
overloads_invalid.py:176:9 - error: Method "final_method" cannot override final method defined in class "Base" (reportIncompatibleMethodOverride)
31+
overloads_invalid.py:176:9 - error: Method "final_method" overrides class "Base" in an incompatible manner
3132
  Return type mismatch: base method returns type "int", override returns type "int | str"
3233
    Type "int | str" is not assignable to type "int"
3334
      "str" is not assignable to "int" (reportIncompatibleMethodOverride)
34-
overloads_invalid.py:189:9 - error: Method "bad_override" is marked as override, but no base method of same name is present (reportGeneralTypeIssues)
35+
overloads_invalid.py:192:9 - error: Method "bad_override" is marked as override, but no base method of same name is present (reportGeneralTypeIssues)
3536
"""
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

conformance/results/pytype/overloads_invalid.toml

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ 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.
7+
Does not enforce any rules on location of @final or @override decorators.
88
"""
99
conformance_automated = "Fail"
1010
errors_diff = """
11+
Line 217: Expected 1 errors
1112
Lines 14, 15: Expected error (tag 'func1')
1213
Lines 26, 27: Expected error (tag 'func2')
1314
Lines 63, 64: Expected error (tag 'not_abstract')
@@ -25,9 +26,11 @@ Line 129: Unexpected errors ['overloads_invalid.py:129:9: \\x1b[1m\\x1b[31merror
2526
Line 143: Unexpected errors ['overloads_invalid.py:143:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final: bad return type [bad-return-type]', 'overloads_invalid.py:143:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final: bad return type [bad-return-type]']
2627
Line 160: Unexpected errors ['overloads_invalid.py:160:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final_2: bad return type [bad-return-type]', 'overloads_invalid.py:160:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in invalid_final_2: bad return type [bad-return-type]']
2728
Line 165: Unexpected errors ['overloads_invalid.py:165:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in good_override: bad return type [bad-return-type]']
28-
Line 174: Unexpected errors ['overloads_invalid.py:174:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in final_method: bad return type [bad-return-type]']
29-
Line 190: Unexpected errors ['overloads_invalid.py:190:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in bad_override: bad return type [bad-return-type]', 'overloads_invalid.py:190:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in bad_override: bad return type [bad-return-type]']
30-
Line 209: Unexpected errors ['overloads_invalid.py:209:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in good_override: bad return type [bad-return-type]', 'overloads_invalid.py:209:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in good_override: bad return type [bad-return-type]']
29+
Line 168: Unexpected errors ['overloads_invalid.py:168:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in to_override: bad return type [bad-return-type]']
30+
Line 177: Unexpected errors ['overloads_invalid.py:177:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in final_method: bad return type [bad-return-type]']
31+
Line 193: Unexpected errors ['overloads_invalid.py:193:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in bad_override: bad return type [bad-return-type]', 'overloads_invalid.py:193:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in bad_override: bad return type [bad-return-type]']
32+
Line 212: Unexpected errors ['overloads_invalid.py:212:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in good_override: bad return type [bad-return-type]', 'overloads_invalid.py:212:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in good_override: bad return type [bad-return-type]']
33+
Line 229: Unexpected errors ['overloads_invalid.py:229:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in to_override: bad return type [bad-return-type]', 'overloads_invalid.py:229:9: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in to_override: bad return type [bad-return-type]']
3134
"""
3235
output = """
3336
overloads_invalid.py:6:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in <module>: typing.override not supported yet [not-supported-yet]
@@ -105,7 +108,12 @@ overloads_invalid.py:165:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in good
105108
...
106109
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
107110
108-
overloads_invalid.py:168: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]
111+
overloads_invalid.py:168:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in to_override: bad return type [bad-return-type]
112+
113+
...
114+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
115+
116+
overloads_invalid.py:171: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]
109117
110118
class Child(Base): # E[override-final]
111119
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
@@ -192,34 +200,78 @@ class Child(Base): # E[override-final]
192200
...
193201
\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m
194202
195-
overloads_invalid.py:174:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in final_method: bad return type [bad-return-type]
203+
\u001b[1m\u001b[31m\u001b[39m\u001b[0m
204+
# This is the wrong way to use @override with an overloaded method, and
205+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
206+
# should emit an error:
207+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
208+
209+
\u001b[1m\u001b[31m\u001b[39m\u001b[0m
210+
@overload # E: @override should appear only on implementation
211+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
212+
@override
213+
\u001b[1m\u001b[31m~~~~~~~~~~~~~\u001b[39m\u001b[0m
214+
def to_override(self, x: int) -> int:
215+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
216+
...
217+
\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m
218+
219+
\u001b[1m\u001b[31m\u001b[39m\u001b[0m
220+
@overload
221+
\u001b[1m\u001b[31m~~~~~~~~~~~~~\u001b[39m\u001b[0m
222+
@override
223+
\u001b[1m\u001b[31m~~~~~~~~~~~~~\u001b[39m\u001b[0m
224+
def to_override(self, x: str) -> str:
225+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
226+
...
227+
\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m
228+
229+
\u001b[1m\u001b[31m\u001b[39m\u001b[0m
230+
@override
231+
\u001b[1m\u001b[31m~~~~~~~~~~~~~\u001b[39m\u001b[0m
232+
def to_override(self, x: int | str) -> int | str:
233+
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
234+
...
235+
\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m
236+
237+
overloads_invalid.py:177:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in final_method: bad return type [bad-return-type]
196238
197239
...
198240
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
199241
200-
overloads_invalid.py:181:5: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in Child: Attribute 'bad_override' not found on any parent class [override-error]
242+
overloads_invalid.py:184:5: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in Child: Attribute 'bad_override' not found on any parent class [override-error]
201243
202244
def bad_override(self, x: int) -> int: # E[bad_override]
203245
\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m
204246
...
205247
\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m
206248
207-
overloads_invalid.py:190:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in bad_override: bad return type [bad-return-type]
249+
overloads_invalid.py:193:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in bad_override: bad return type [bad-return-type]
250+
251+
...
252+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
253+
254+
overloads_invalid.py:193:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in bad_override: bad return type [bad-return-type]
255+
256+
...
257+
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
258+
259+
overloads_invalid.py:212:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in good_override: bad return type [bad-return-type]
208260
209261
...
210262
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
211263
212-
overloads_invalid.py:190:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in bad_override: bad return type [bad-return-type]
264+
overloads_invalid.py:212:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in good_override: bad return type [bad-return-type]
213265
214266
...
215267
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
216268
217-
overloads_invalid.py:209:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in good_override: bad return type [bad-return-type]
269+
overloads_invalid.py:229:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in to_override: bad return type [bad-return-type]
218270
219271
...
220272
\u001b[1m\u001b[31m~~~\u001b[39m\u001b[0m
221273
222-
overloads_invalid.py:209:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in good_override: bad return type [bad-return-type]
274+
overloads_invalid.py:229:9: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in to_override: bad return type [bad-return-type]
223275
224276
...
225277
\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 = 30.6
2+
test_duration = 30.7

0 commit comments

Comments
 (0)