Skip to content

Commit

Permalink
Specify return types for the return types incompatible with supertype…
Browse files Browse the repository at this point in the history
… error (#6979)

Fixes #2797
  • Loading branch information
joejuzl authored and ilevkivskyi committed Jun 13, 2019
1 parent 7692f56 commit dfd50fc
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 21 deletions.
2 changes: 1 addition & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@ def erase_override(t: Type) -> Type:
if not is_subtype(erase_override(override.ret_type),
original.ret_type):
self.msg.return_type_incompatible_with_supertype(
name, name_in_super, supertype, node)
name, name_in_super, supertype, original.ret_type, override.ret_type, node)
emitted_msg = True
elif isinstance(override, Overloaded) and isinstance(original, Overloaded):
# Give a more detailed message in the case where the user is trying to
Expand Down
5 changes: 3 additions & 2 deletions mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -826,10 +826,11 @@ def __eq__(self, other: object) -> bool:

def return_type_incompatible_with_supertype(
self, name: str, name_in_supertype: str, supertype: str,
original: Type, override: Type,
context: Context) -> None:
target = self.override_target(name, name_in_supertype, supertype)
self.fail('Return type of "{}" incompatible with {}'
.format(name, target), context)
self.fail('Return type {} of "{}" incompatible with return type {} in {}'
.format(self.format(override), name, self.format(original), target), context)

def override_target(self, name: str, name_in_super: str,
supertype: str) -> str:
Expand Down
6 changes: 3 additions & 3 deletions test-data/unit/check-abstract.test
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ class A(I, J):
def f(self, x: str) -> int: pass \
# E: Argument 1 of "f" is incompatible with supertype "I"; supertype defines the argument type as "int"
def g(self, x: str) -> int: pass \
# E: Return type of "g" incompatible with supertype "J"
# E: Return type "int" of "g" incompatible with return type "str" in supertype "J"
def h(self) -> int: pass # Not related to any base class
[out]

Expand Down Expand Up @@ -372,7 +372,7 @@ class A(I):
pass
[out]
main:11: error: Argument 1 of "h" is incompatible with supertype "I"; supertype defines the argument type as "I"
main:11: error: Return type of "h" incompatible with supertype "I"
main:11: error: Return type "I" of "h" incompatible with return type "A" in supertype "I"


-- Accessing abstract members
Expand Down Expand Up @@ -770,7 +770,7 @@ class A(metaclass=ABCMeta):
def x(self) -> int: pass
class B(A):
@property
def x(self) -> str: pass # E: Return type of "x" incompatible with supertype "A"
def x(self) -> str: pass # E: Return type "str" of "x" incompatible with return type "int" in supertype "A"
b = B()
b.x() # E: "str" not callable
[builtins fixtures/property.pyi]
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-class-namedtuple.test
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ class Child(Base):
return self.x
def good_override(self) -> int:
return 0
def bad_override(self) -> str: # E: Return type of "bad_override" incompatible with supertype "Base"
def bad_override(self) -> str: # E: Return type "str" of "bad_override" incompatible with return type "int" in supertype "Base"
return 'incompatible'

def takes_base(base: Base) -> int:
Expand Down
8 changes: 4 additions & 4 deletions test-data/unit/check-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ class B(A):
def h(self, x: A, y: 'B') -> object: pass # Fail
[out]
main:7: error: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "A"
main:9: error: Return type of "h" incompatible with supertype "A"
main:9: error: Return type "object" of "h" incompatible with return type "A" in supertype "A"

[case testEqMethodsOverridingWithNonObjects]
class A:
Expand Down Expand Up @@ -328,7 +328,7 @@ class C(B): # with multiple implementations
def f(self) -> B: # Fail
pass
[out]
main:7: error: Return type of "f" incompatible with supertype "B"
main:7: error: Return type "B" of "f" incompatible with return type "C" in supertype "B"

[case testMethodOverridingWithVoidReturnValue]
import typing
Expand All @@ -339,7 +339,7 @@ class B(A):
def f(self) -> A: pass # Fail
def g(self) -> None: pass
[out]
main:6: error: Return type of "f" incompatible with supertype "A"
main:6: error: Return type "A" of "f" incompatible with return type "None" in supertype "A"

[case testOverride__new__WithDifferentSignature]
class A:
Expand Down Expand Up @@ -2451,7 +2451,7 @@ class C(A):
class D(A):
def __iadd__(self, x: 'A') -> 'B': pass
[out]
main:6: error: Return type of "__iadd__" incompatible with "__add__" of supertype "A"
main:6: error: Return type "A" of "__iadd__" incompatible with return type "B" in "__add__" of supertype "A"
main:8: error: Argument 1 of "__iadd__" is incompatible with "__add__" of supertype "A"; supertype defines the argument type as "A"
main:8: error: Signatures of "__iadd__" and "__add__" are incompatible

Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-selftype.test
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class C(A):
pass

class D(A):
def copy(self: A) -> A: # E: Return type of "copy" incompatible with supertype "A"
def copy(self: A) -> A: # E: Return type "A" of "copy" incompatible with return type "D" in supertype "A"
pass

TB = TypeVar('TB', bound='B', covariant=True)
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-typevar-values.test
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ class B(A[str]):
def f(self) -> 'B': pass
class C(A[str]):
@abstractmethod
def f(self) -> int: # E: Return type of "f" incompatible with supertype "A"
def f(self) -> int: # E: Return type "int" of "f" incompatible with return type "A[str]" in supertype "A"
pass
[out]

Expand Down
16 changes: 8 additions & 8 deletions test-data/unit/fine-grained.test
Original file line number Diff line number Diff line change
Expand Up @@ -1063,9 +1063,9 @@ class A:
[file n.py.3]
[out]
==
main:3: error: Return type of "f" incompatible with supertype "A"
main:3: error: Return type "str" of "f" incompatible with return type "int" in supertype "A"
==
main:3: error: Return type of "f" incompatible with supertype "A"
main:3: error: Return type "str" of "f" incompatible with return type "int" in supertype "A"

[case testModifyBaseClassMethodCausingInvalidOverride]
import m
Expand All @@ -1079,7 +1079,7 @@ class A:
def f(self) -> int: pass
[out]
==
main:3: error: Return type of "f" incompatible with supertype "A"
main:3: error: Return type "str" of "f" incompatible with return type "int" in supertype "A"

[case testAddBaseClassAttributeCausingErrorInSubclass]
import m
Expand Down Expand Up @@ -1985,11 +1985,11 @@ class B:
class B:
def foo(self) -> int: return 12
[out]
a.py:9: error: Return type of "foo" incompatible with supertype "B"
a.py:9: error: Return type "int" of "foo" incompatible with return type "str" in supertype "B"
==
a.py:9: error: Return type of "foo" incompatible with supertype "B"
a.py:9: error: Return type "int" of "foo" incompatible with return type "str" in supertype "B"
==
a.py:9: error: Return type of "foo" incompatible with supertype "B"
a.py:9: error: Return type "int" of "foo" incompatible with return type "str" in supertype "B"
==

[case testPreviousErrorInMethodSemanal1]
Expand Down Expand Up @@ -7449,7 +7449,7 @@ def deco(f: F) -> F:
[out]
main:7: error: Unsupported operand types for + ("str" and "int")
==
main:5: error: Return type of "m" incompatible with supertype "B"
main:5: error: Return type "str" of "m" incompatible with return type "int" in supertype "B"

[case testLiskovFineVariableClean-only_when_nocache]
import b
Expand Down Expand Up @@ -7553,7 +7553,7 @@ def deco(f: F) -> F:
pass
[out]
==
main:5: error: Return type of "m" incompatible with supertype "B"
main:5: error: Return type "str" of "m" incompatible with return type "int" in supertype "B"

[case testAddAbstractMethod]
from b import D
Expand Down

0 comments on commit dfd50fc

Please sign in to comment.