Skip to content

Commit 56afa92

Browse files
matys18ilevkivskyi
authored andcommitted
Update error message for incompatible args (#6796)
Closes #5025 Updated the error message that is displayed when the argument types of a method in a subclass are incompatible with the arguments of the same method in the superclass. ```python # sample.py class A: def kek(self, lol: int = 0) -> None: print("Kek in A") class B(A): def kek(self, haha: str = "") -> None: super().kek(1) print("Kek in B") ``` Output before: ```sh mypy sample.py sample.py:11: error: Argument 1 of "kek" incompatible with supertype "A" ``` Output now: ``` mypy sample.py sample.py:11: error: Argument 1 of "kek" is incompatible with supertype "A"; supertype defines the argument type as "int" ```
1 parent 7560ee0 commit 56afa92

File tree

8 files changed

+39
-28
lines changed

8 files changed

+39
-28
lines changed

mypy/checker.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1534,8 +1534,16 @@ def erase_override(t: Type) -> Type:
15341534
for i in range(len(override.arg_types)):
15351535
if not is_subtype(original.arg_types[i],
15361536
erase_override(override.arg_types[i])):
1537+
arg_type_in_super = original.arg_types[i]
15371538
self.msg.argument_incompatible_with_supertype(
1538-
i + 1, name, type_name, name_in_super, supertype, node)
1539+
i + 1,
1540+
name,
1541+
type_name,
1542+
name_in_super,
1543+
arg_type_in_super,
1544+
supertype,
1545+
node
1546+
)
15391547
emitted_msg = True
15401548

15411549
if not is_subtype(erase_override(override.ret_type),

mypy/messages.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -799,10 +799,13 @@ def signature_incompatible_with_supertype(
799799

800800
def argument_incompatible_with_supertype(
801801
self, arg_num: int, name: str, type_name: Optional[str],
802-
name_in_supertype: str, supertype: str, context: Context) -> None:
802+
name_in_supertype: str, arg_type_in_supertype: Type, supertype: str,
803+
context: Context) -> None:
803804
target = self.override_target(name, name_in_supertype, supertype)
804-
self.fail('Argument {} of "{}" incompatible with {}'
805-
.format(arg_num, name, target), context)
805+
arg_type_in_supertype_f = self.format_bare(arg_type_in_supertype)
806+
self.fail('Argument {} of "{}" is incompatible with {}; '
807+
'supertype defines the argument type as "{}"'
808+
.format(arg_num, name, target, arg_type_in_supertype_f), context)
806809

807810
if name == "__eq__" and type_name:
808811
multiline_msg = self.comparison_method_example_msg(class_name=type_name)

test-data/unit/check-abstract.test

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ class A(metaclass=ABCMeta):
308308
def g(self, x: int) -> int: pass
309309
class B(A):
310310
def f(self, x: str) -> int: \
311-
# E: Argument 1 of "f" incompatible with supertype "A"
311+
# E: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "int"
312312
pass
313313
def g(self, x: int) -> int: pass
314314
[out]
@@ -324,7 +324,7 @@ class J(metaclass=ABCMeta):
324324
def g(self, x: str) -> str: pass
325325
class A(I, J):
326326
def f(self, x: str) -> int: pass \
327-
# E: Argument 1 of "f" incompatible with supertype "I"
327+
# E: Argument 1 of "f" is incompatible with supertype "I"; supertype defines the argument type as "int"
328328
def g(self, x: str) -> int: pass \
329329
# E: Return type of "g" incompatible with supertype "J"
330330
def h(self) -> int: pass # Not related to any base class
@@ -339,7 +339,7 @@ class J(metaclass=ABCMeta):
339339
class I(J): pass
340340
class A(I):
341341
def f(self, x: str) -> int: pass \
342-
# E: Argument 1 of "f" incompatible with supertype "J"
342+
# E: Argument 1 of "f" is incompatible with supertype "J"; supertype defines the argument type as "int"
343343
[out]
344344

345345
[case testInvalidOverridingAbstractMethod]
@@ -350,7 +350,7 @@ class J(metaclass=ABCMeta):
350350
def f(self, x: 'J') -> None: pass
351351
class I(J):
352352
@abstractmethod
353-
def f(self, x: 'I') -> None: pass # E: Argument 1 of "f" incompatible with supertype "J"
353+
def f(self, x: 'I') -> None: pass # E: Argument 1 of "f" is incompatible with supertype "J"; supertype defines the argument type as "J"
354354
[out]
355355

356356
[case testAbstractClassCoAndContraVariance]
@@ -371,7 +371,7 @@ class A(I):
371371
def g(self, a: 'A') -> 'A':
372372
pass
373373
[out]
374-
main:11: error: Argument 1 of "h" incompatible with supertype "I"
374+
main:11: error: Argument 1 of "h" is incompatible with supertype "I"; supertype defines the argument type as "I"
375375
main:11: error: Return type of "h" incompatible with supertype "I"
376376

377377

test-data/unit/check-classes.test

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,15 @@ class B(A):
280280
def g(self, x: A, y: A) -> A: pass
281281
def h(self, x: A, y: 'B') -> object: pass # Fail
282282
[out]
283-
main:7: error: Argument 1 of "f" incompatible with supertype "A"
283+
main:7: error: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "A"
284284
main:9: error: Return type of "h" incompatible with supertype "A"
285285

286286
[case testEqMethodsOverridingWithNonObjects]
287287
class A:
288288
def __eq__(self, other: A) -> bool: pass # Fail
289289
[builtins fixtures/attr.pyi]
290290
[out]
291-
main:2: error: Argument 1 of "__eq__" incompatible with supertype "object"
291+
main:2: error: Argument 1 of "__eq__" is incompatible with supertype "object"; supertype defines the argument type as "object"
292292
main:2: note: It is recommended for "__eq__" to work with arbitrary objects, for example:
293293
main:2: note: def __eq__(self, other: object) -> bool:
294294
main:2: note: if not isinstance(other, A):
@@ -316,7 +316,7 @@ class C(B): # with gap in implementations
316316
def f(self, x: 'C') -> None: # Fail
317317
pass
318318
[out]
319-
main:6: error: Argument 1 of "f" incompatible with supertype "A"
319+
main:6: error: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "B"
320320

321321
[case testMethodOverridingAcrossDeepInheritanceHierarchy2]
322322
import typing
@@ -458,7 +458,7 @@ class B(A):
458458
@staticmethod
459459
def f(x: int, y: str) -> None: pass
460460
@staticmethod
461-
def g(x: str, y: str) -> None: pass # E: Argument 1 of "g" incompatible with supertype "A"
461+
def g(x: str, y: str) -> None: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "int"
462462
[builtins fixtures/classmethod.pyi]
463463

464464
[case testOverrideClassMethodWithClassMethod]
@@ -472,7 +472,7 @@ class B(A):
472472
@classmethod
473473
def f(cls, x: int, y: str) -> None: pass
474474
@classmethod
475-
def g(cls, x: str, y: str) -> None: pass # E: Argument 1 of "g" incompatible with supertype "A"
475+
def g(cls, x: str, y: str) -> None: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "int"
476476
[builtins fixtures/classmethod.pyi]
477477

478478
[case testOverrideClassMethodWithStaticMethod]
@@ -488,7 +488,7 @@ class B(A):
488488
@staticmethod
489489
def f(x: int) -> None: pass
490490
@staticmethod
491-
def g(x: str) -> int: pass # E: Argument 1 of "g" incompatible with supertype "A"
491+
def g(x: str) -> int: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "int"
492492
@staticmethod
493493
def h() -> int: pass
494494
[builtins fixtures/classmethod.pyi]
@@ -506,7 +506,7 @@ class B(A):
506506
@classmethod
507507
def f(cls, x: int) -> None: pass
508508
@classmethod
509-
def g(cls, x: int) -> int: pass # E: Argument 1 of "g" incompatible with supertype "A"
509+
def g(cls, x: int) -> int: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "str"
510510
@classmethod
511511
def h(cls) -> int: pass
512512
[builtins fixtures/classmethod.pyi]
@@ -2452,7 +2452,7 @@ class D(A):
24522452
def __iadd__(self, x: 'A') -> 'B': pass
24532453
[out]
24542454
main:6: error: Return type of "__iadd__" incompatible with "__add__" of supertype "A"
2455-
main:8: error: Argument 1 of "__iadd__" incompatible with "__add__" of supertype "A"
2455+
main:8: error: Argument 1 of "__iadd__" is incompatible with "__add__" of supertype "A"; supertype defines the argument type as "A"
24562456
main:8: error: Signatures of "__iadd__" and "__add__" are incompatible
24572457

24582458
[case testGetattribute]

test-data/unit/check-dynamic-typing.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ class C:
698698
class B(C):
699699
def f(self, a): pass
700700
class A(B):
701-
def f(self, a: 'D') -> None: # E: Argument 1 of "f" incompatible with supertype "C"
701+
def f(self, a: 'D') -> None: # E: Argument 1 of "f" is incompatible with supertype "C"; supertype defines the argument type as "A"
702702
pass
703703
class D: pass
704704
[out]

test-data/unit/check-functions.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class A(object):
4545
def f(self, a: int, b: str) -> None: pass
4646

4747
class B(A):
48-
def f(self, b: str, a: int) -> None: pass # E: Argument 1 of "f" incompatible with supertype "A" # E: Argument 2 of "f" incompatible with supertype "A"
48+
def f(self, b: str, a: int) -> None: pass # E: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "int" # E: Argument 2 of "f" is incompatible with supertype "A"; supertype defines the argument type as "str"
4949

5050
class C(A):
5151
def f(self, foo: int, bar: str) -> None: pass

test-data/unit/check-generic-subtyping.test

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class C: pass
186186
class D: pass
187187
class A(B[C]):
188188
def f(self, a: D) -> None: pass \
189-
# E: Argument 1 of "f" incompatible with supertype "B"
189+
# E: Argument 1 of "f" is incompatible with supertype "B"; supertype defines the argument type as "C"
190190
def g(self, a: C) -> None: pass
191191
[out]
192192

@@ -199,7 +199,7 @@ class B:
199199
def g(self, a: C) -> None: pass
200200
class A(B, Generic[T]):
201201
def f(self, a: T) -> None: pass \
202-
# E: Argument 1 of "f" incompatible with supertype "B"
202+
# E: Argument 1 of "f" is incompatible with supertype "B"; supertype defines the argument type as "C"
203203
def g(self, a: 'C') -> None: pass
204204
[out]
205205

@@ -212,7 +212,7 @@ class B(Generic[T]):
212212
def g(self, a: T) -> None: pass
213213
class A(B[S], Generic[T, S]):
214214
def f(self, a: T) -> None: pass \
215-
# E: Argument 1 of "f" incompatible with supertype "B"
215+
# E: Argument 1 of "f" is incompatible with supertype "B"; supertype defines the argument type as "S"
216216
def g(self, a: S) -> None: pass
217217
[out]
218218

@@ -230,7 +230,7 @@ class C(Generic[T, U, V]):
230230
class B(C[D, D, T], Generic[T]): pass
231231
class A(B[S], Generic[T, S]):
232232
def f(self, a: T) -> None: pass \
233-
# E: Argument 1 of "f" incompatible with supertype "C"
233+
# E: Argument 1 of "f" is incompatible with supertype "C"; supertype defines the argument type as "S"
234234
def g(self, a: S) -> None: pass
235235
[out]
236236

@@ -279,7 +279,7 @@ class C(A):
279279
class D(A):
280280
def f(self, x: T1, y: S) -> None: pass # TODO: This error could be more specific.
281281
[out]
282-
main:12: error: Argument 2 of "f" incompatible with supertype "A"
282+
main:12: error: Argument 2 of "f" is incompatible with supertype "A"; supertype defines the argument type as "S"
283283
main:14: error: Signature of "f" incompatible with supertype "A"
284284

285285

@@ -533,7 +533,7 @@ class I(Generic[T]):
533533
def g(self, a: T) -> None: pass
534534
class A(I[C]):
535535
def f(self, a: 'D') -> None: pass \
536-
# E: Argument 1 of "f" incompatible with supertype "I"
536+
# E: Argument 1 of "f" is incompatible with supertype "I"; supertype defines the argument type as "C"
537537
def g(self, a: 'C') -> None: pass
538538
class C: pass
539539
class D: pass
@@ -565,7 +565,7 @@ class B(I[C]):
565565
def g(self, a: 'C', b: Any) -> None: pass
566566
class A(B):
567567
def g(self, a: 'C', b: 'C') -> None: pass \
568-
# E: Argument 2 of "g" incompatible with supertype "I"
568+
# E: Argument 2 of "g" is incompatible with supertype "I"; supertype defines the argument type as "D"
569569
def f(self, a: 'C', b: 'C') -> None: pass
570570
class C: pass
571571
class D: pass
@@ -581,7 +581,7 @@ class B(I[C]):
581581
def f(self, a: 'C', b: Any) -> None: pass
582582
class A(B):
583583
def f(self, a: 'C', b: 'D') -> None: pass \
584-
# E: Argument 2 of "f" incompatible with supertype "I"
584+
# E: Argument 2 of "f" is incompatible with supertype "I"; supertype defines the argument type as "C"
585585
class C: pass
586586
class D: pass
587587
[out]

test-data/unit/check-multiple-inheritance.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ class Flag:
538538
class IntFlag(int, Flag):
539539
def __or__(self: _T, other: str) -> _T: ...
540540
[out]
541-
main:8: error: Argument 1 of "__or__" incompatible with supertype "Flag"
541+
main:8: error: Argument 1 of "__or__" is incompatible with supertype "Flag"; supertype defines the argument type as "IntFlag"
542542

543543
[case testMultipleInheritance_MethodDefinitionsCompatibleNoOverride]
544544
from typing import TypeVar, Union

0 commit comments

Comments
 (0)