Repository: python/mypy

Issue:
Internal type representation used for invalid return value type
Some error messages (see commit 5c9cbc73a8110c879455a60af58de60264d2f4cf) use the internal type representation, which looks confusing. For example:

```
Incompatible return value type: expected __main__.p[T`-2, __main__.A], got __main__.p[S`-1, __main__.A*]
```



Discussion:

Resolving patch:
diff --git a/mypy/checker.py b/mypy/checker.py
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -1593,10 +1593,12 @@ def visit_return_stmt(self, s: ReturnStmt) -> Type:
                     self.fail(messages.NO_RETURN_VALUE_EXPECTED, s)
                 else:
                     self.check_subtype(
-                        typ, return_type, s,
-                        messages.INCOMPATIBLE_RETURN_VALUE_TYPE
-                        + ": expected {}, got {}".format(return_type, typ)
-                    )
+                        subtype_label='got',
+                        subtype=typ,
+                        supertype_label='expected',
+                        supertype=return_type,
+                        context=s,
+                        msg=messages.INCOMPATIBLE_RETURN_VALUE_TYPE)
             else:
                 # Empty returns are valid in Generators with Any typed returns.
                 if (self.function_stack[-1].is_generator and isinstance(return_type, AnyType)):


Test patch:
diff --git a/mypy/test/data/check-basic.test b/mypy/test/data/check-basic.test
--- a/mypy/test/data/check-basic.test
+++ b/mypy/test/data/check-basic.test
@@ -193,7 +193,7 @@ class A: pass
 class B: pass
 [out]
 main: note: In function "f":
-main:3: error: Incompatible return value type: expected __main__.A, got __main__.B
+main:3: error: Incompatible return value type (got "B", expected "A")
 
 [case testTopLevelContextAndInvalidReturn]
 import typing
@@ -204,7 +204,7 @@ class A: pass
 class B: pass
 [out]
 main: note: In function "f":
-main:3: error: Incompatible return value type: expected __main__.A, got __main__.B
+main:3: error: Incompatible return value type (got "B", expected "A")
 main: note: At top level:
 main:4: error: Incompatible types in assignment (expression has type "B", variable has type "A")
 
@@ -289,7 +289,7 @@ def f(x): # type: (int) -> str
 f('')
 [out]
 main: note: In function "f":
-main:2: error: Incompatible return value type: expected builtins.str, got builtins.int
+main:2: error: Incompatible return value type (got "int", expected "str")
 main: note: At top level:
 main:3: error: Argument 1 to "f" has incompatible type "str"; expected "int"
 
@@ -303,7 +303,7 @@ A().f('') # Fail
 [out]
 main: note: In member "f" of class "A":
 main:4: error: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
-main:5: error: Incompatible return value type: expected builtins.str, got builtins.int
+main:5: error: Incompatible return value type (got "int", expected "str")
 main: note: At top level:
 main:6: error: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
 
diff --git a/mypy/test/data/check-bound.test b/mypy/test/data/check-bound.test
--- a/mypy/test/data/check-bound.test
+++ b/mypy/test/data/check-bound.test
@@ -130,7 +130,7 @@ def k(x: TA) -> B:
 main: note: In function "g2":
 main:16: error: Type argument 1 of "h" has incompatible value "TA"
 main: note: In function "k":
-main:21: error: Incompatible return value type: expected __main__.B, got TA`-1
+main:21: error: Incompatible return value type (got "TA", expected "B")
 
 
 [case testBoundMethodUsage]
diff --git a/mypy/test/data/check-classes.test b/mypy/test/data/check-classes.test
--- a/mypy/test/data/check-classes.test
+++ b/mypy/test/data/check-classes.test
@@ -96,7 +96,7 @@ class A:
 class B: pass
 [out]
 main: note: In member "f" of class "A":
-main:4: error: Incompatible return value type: expected __main__.A, got __main__.B
+main:4: error: Incompatible return value type (got "B", expected "A")
 
 [case testSelfArgument]
 import typing
diff --git a/mypy/test/data/check-expressions.test b/mypy/test/data/check-expressions.test
--- a/mypy/test/data/check-expressions.test
+++ b/mypy/test/data/check-expressions.test
@@ -1040,7 +1040,7 @@ f = lambda: ''.x
 f = lambda: ''
 [out]
 main:3: error: "str" has no attribute "x"
-main:4: error: Incompatible return value type: expected builtins.int, got builtins.str
+main:4: error: Incompatible return value type (got "str", expected "int")
 main:4: error: Incompatible types in assignment (expression has type Callable[[], str], variable has type Callable[[], int])
 
 [case testVoidLambda]
diff --git a/mypy/test/data/check-functions.test b/mypy/test/data/check-functions.test
--- a/mypy/test/data/check-functions.test
+++ b/mypy/test/data/check-functions.test
@@ -428,9 +428,9 @@ class A: pass
 class B: pass
 [out]
 main: note: In function "g":
-main:4: error: Incompatible return value type: expected __main__.B, got __main__.A
+main:4: error: Incompatible return value type (got "A", expected "B")
 main: note: In function "f":
-main:6: error: Incompatible return value type: expected __main__.A, got __main__.B
+main:6: error: Incompatible return value type (got "B", expected "A")
 
 [case testDynamicallyTypedNestedFunction]
 import typing
@@ -1432,7 +1432,7 @@ def f(x, y):
       int: The sum.
     """
     v = realtypes(x, y) # E: Argument 2 to "realtypes" has incompatible type "object"; expected "int"
-    return v # E: Incompatible return value type: expected builtins.int, got builtins.str
+    return v # E: Incompatible return value type (got "str", expected "int")
 [out]
 main: note: In function "f":
 
diff --git a/mypy/test/data/check-generics.test b/mypy/test/data/check-generics.test
--- a/mypy/test/data/check-generics.test
+++ b/mypy/test/data/check-generics.test
@@ -387,7 +387,7 @@ def f(s: S, t: T) -> p[T, A]:
     s = t           # E: Incompatible types in assignment (expression has type "T", variable has type "S")
     p_s_a = None  # type: p[S, A]
     if s:
-        return p_s_a # E: Incompatible return value type: expected __main__.p[T`-2, __main__.A], got __main__.p[S`-1, __main__.A]
+        return p_s_a # E: Incompatible return value type (got p[S, A], expected p[T, A])
     b = t # type: T
     c = s # type: S
     p_t_a = None  # type: p[T, A]
@@ -406,10 +406,10 @@ class A(Generic[T]):
         s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S")
         p_s_s = None  # type: p[S, S]
         if s:
-            return p_s_s # E: Incompatible return value type: expected __main__.p[S`-1, T`1], got __main__.p[S`-1, S`-1]
+            return p_s_s # E: Incompatible return value type (got p[S, S], expected p[S, T])
         p_t_t = None  # type: p[T, T]
         if s:
-            return p_t_t # E: Incompatible return value type: expected __main__.p[S`-1, T`1], got __main__.p[T`1, T`1]
+            return p_t_t # E: Incompatible return value type (got p[T, T], expected p[S, T])
         t = t
         s = s
         p_s_t = None  # type: p[S, T]
diff --git a/mypy/test/data/check-inference-context.test b/mypy/test/data/check-inference-context.test
--- a/mypy/test/data/check-inference-context.test
+++ b/mypy/test/data/check-inference-context.test
@@ -602,7 +602,7 @@ f4 = lambda x: x # type: Callable[..., int]
 g = lambda x: 1 # type: Callable[..., str]
 [builtins fixtures/dict.py]
 [out]
-main:6: error: Incompatible return value type: expected builtins.str, got builtins.int
+main:6: error: Incompatible return value type (got "int", expected "str")
 main:6: error: Incompatible types in assignment (expression has type Callable[[Any], int], variable has type Callable[..., str])
 
 [case testEllipsisContextForLambda2]
diff --git a/mypy/test/data/check-statements.test b/mypy/test/data/check-statements.test
--- a/mypy/test/data/check-statements.test
+++ b/mypy/test/data/check-statements.test
@@ -14,7 +14,7 @@ class B:
     pass
 [out]
 main: note: In function "g":
-main:5: error: Incompatible return value type: expected __main__.B, got __main__.A
+main:5: error: Incompatible return value type (got "A", expected "B")
 
 [case testReturnSubtype]
 import typing
@@ -28,7 +28,7 @@ class B(A):
     pass
 [out]
 main: note: In function "f":
-main:3: error: Incompatible return value type: expected __main__.B, got __main__.A
+main:3: error: Incompatible return value type (got "A", expected "B")
 
 [case testReturnWithoutAValue]
 import typing
diff --git a/mypy/test/data/check-typevar-values.test b/mypy/test/data/check-typevar-values.test
--- a/mypy/test/data/check-typevar-values.test
+++ b/mypy/test/data/check-typevar-values.test
@@ -70,9 +70,9 @@ def g(x: AB) -> AB:
     return x.g() # Error
 [out]
 main: note: In function "f":
-main:10: error: Incompatible return value type: expected __main__.B*, got __main__.A
+main:10: error: Incompatible return value type (got "A", expected "B")
 main: note: In function "g":
-main:12: error: Incompatible return value type: expected __main__.A*, got __main__.B
+main:12: error: Incompatible return value type (got "B", expected "A")
 
 [case testTypeInferenceAndTypeVarValues]
 from typing import TypeVar
@@ -88,7 +88,7 @@ def f(x: AB) -> AB:
     if y:
         return y.f()
     else:
-        return y.g() # E: Incompatible return value type: expected __main__.A*, got __main__.B
+        return y.g() # E: Incompatible return value type (got "B", expected "A")
 [out]
 main: note: In function "f":
 
@@ -116,7 +116,7 @@ def g(x: T) -> T:
         return ''
 def h(x: T) -> T:
     if isinstance(x, int):
-        return '' # E: Incompatible return value type: expected builtins.int*, got builtins.str
+        return '' # E: Incompatible return value type (got "str", expected "int")
     return x
 [builtins fixtures/isinstance.py]
 [out]
@@ -132,9 +132,9 @@ def f(x: T) -> T:
         return ''
 def g(x: T) -> T:
     if isinstance(x, int):
-        return '' # E: Incompatible return value type: expected builtins.int*, got builtins.str
+        return '' # E: Incompatible return value type (got "str", expected "int")
     else:
-        return 2  # E: Incompatible return value type: expected builtins.str*, got builtins.int
+        return 2  # E: Incompatible return value type (got "int", expected "str")
     return x
 [builtins fixtures/isinstance.py]
 [out]
@@ -159,7 +159,7 @@ def f(x: T) -> T:
         y = 1
     else:
         y = object()
-    return y # E: Incompatible return value type: expected builtins.str*, got builtins.object
+    return y # E: Incompatible return value type (got "object", expected "str")
 [builtins fixtures/isinstance.py]
 [out]
 main: note: In function "f":
@@ -172,7 +172,7 @@ def f(x: T) -> T:
         y = object()
     else:
         y = ''
-    return y # E: Incompatible return value type: expected builtins.int*, got builtins.object
+    return y # E: Incompatible return value type (got "object", expected "int")
 [builtins fixtures/isinstance.py]
 [out]
 main: note: In function "f":
diff --git a/mypy/test/data/pythoneval-asyncio.test b/mypy/test/data/pythoneval-asyncio.test
--- a/mypy/test/data/pythoneval-asyncio.test
+++ b/mypy/test/data/pythoneval-asyncio.test
@@ -302,7 +302,7 @@ loop.close()
 
 [out]
 _program.py: note: In function "compute":
-_program.py:9: error: Incompatible return value type: expected builtins.int, got builtins.str
+_program.py:9: error: Incompatible return value type (got "str", expected "int")
 
 [case testErrorSetFutureDifferentInternalType]
 from typing import Generator, Any
@@ -428,7 +428,7 @@ loop.run_until_complete(h())
 loop.close()
 [out]
 _program.py: note: In function "h3":
-_program.py:18: error: Incompatible return value type: expected asyncio.futures.Future[asyncio.futures.Future[asyncio.futures.Future[builtins.int]]], got asyncio.futures.Future[asyncio.futures.Future[builtins.int]]
+_program.py:18: error: Incompatible return value type (got Future[Future[int]], expected Future[...])
 
 [case testErrorOneLessFutureInReturnType]
 import typing
@@ -463,7 +463,7 @@ loop.run_until_complete(h())
 loop.close()
 [out]
 _program.py: note: In function "h3":
-_program.py:18: error: Incompatible return value type: expected asyncio.futures.Future[builtins.int], got asyncio.futures.Future[asyncio.futures.Future[builtins.int]]
+_program.py:18: error: Incompatible return value type (got Future[Future[int]], expected Future[int])
 
 [case testErrorAssignmentDifferentType]
 import typing