From 014b1e1ee55ac3c9cf4affe7c4007106bb312bdf Mon Sep 17 00:00:00 2001 From: Mark Lindberg Date: Tue, 15 May 2018 13:53:39 -0400 Subject: [PATCH] Better error messages for calling overloaded function with invalid types. --- mypy/messages.py | 4 + test-data/unit/check-abstract.test | 25 ++- test-data/unit/check-class-namedtuple.test | 16 +- test-data/unit/check-classes.test | 73 +++++++- test-data/unit/check-expressions.test | 14 +- test-data/unit/check-functions.test | 9 +- test-data/unit/check-inference.test | 11 +- test-data/unit/check-overloading.test | 208 +++++++++++++++++---- test-data/unit/check-protocols.test | 22 ++- test-data/unit/check-serialize.test | 10 + test-data/unit/check-typeddict.test | 35 +++- test-data/unit/fine-grained.test | 20 ++ test-data/unit/python2eval.test | 5 + test-data/unit/pythoneval.test | 15 +- 14 files changed, 394 insertions(+), 73 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 9922d9d16a2c..646b950373e8 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -752,6 +752,10 @@ def no_variant_matches_arguments(self, overload: Overloaded, arg_types: List[Typ .format(name, arg_types), context) else: self.fail('No overload variant matches argument types {}'.format(arg_types), context) + OFFSET = 2 + MAX_ITEMS = 2 + self.note('Possible overload variants:', context) + self.pretty_overload(overload, context, OFFSET, MAX_ITEMS) def wrong_number_values_to_unpack(self, provided: int, expected: int, context: Context) -> None: diff --git a/test-data/unit/check-abstract.test b/test-data/unit/check-abstract.test index a164af44f6fe..7cf19783aa28 100644 --- a/test-data/unit/check-abstract.test +++ b/test-data/unit/check-abstract.test @@ -519,13 +519,21 @@ class B(A): def f(self, x: int) -> int: pass @overload def f(self, x: str) -> str: pass -A() # E: Cannot instantiate abstract class 'A' with abstract attribute 'f' +A() B() B().f(1) a = B() # type: A a.f(1) a.f('') -a.f(B()) # E: No overload variant of "f" of "A" matches argument types [foo.B] +a.f(B()) +[out] +tmp/foo.pyi:17: error: Cannot instantiate abstract class 'A' with abstract attribute 'f' +tmp/foo.pyi:23: error: No overload variant of "f" of "A" matches argument types [foo.B] +tmp/foo.pyi:23: note: Possible overload variants: +tmp/foo.pyi:23: note: @overload +tmp/foo.pyi:23: note: def f(self, x: int) -> int +tmp/foo.pyi:23: note: @overload +tmp/foo.pyi:23: note: def f(self, x: str) -> str [case testOverloadedAbstractMethodWithAlternativeDecoratorOrder] from foo import * @@ -546,13 +554,22 @@ class B(A): def f(self, x: int) -> int: pass @overload def f(self, x: str) -> str: pass -A() # E: Cannot instantiate abstract class 'A' with abstract attribute 'f' +A() B() B().f(1) a = B() # type: A a.f(1) a.f('') -a.f(B()) # E: No overload variant of "f" of "A" matches argument types [foo.B] +a.f(B()) +[out] +tmp/foo.pyi:17: error: Cannot instantiate abstract class 'A' with abstract attribute 'f' +tmp/foo.pyi:23: error: No overload variant of "f" of "A" matches argument types [foo.B] +tmp/foo.pyi:23: note: Possible overload variants: +tmp/foo.pyi:23: note: @overload +tmp/foo.pyi:23: note: def f(self, x: int) -> int +tmp/foo.pyi:23: note: @overload +tmp/foo.pyi:23: note: def f(self, x: str) -> str + [case testOverloadedAbstractMethodVariantMissingDecorator1] from foo import * diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index 017a1b8dad5d..c681a3944898 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -521,9 +521,19 @@ class Overloader(NamedTuple): def method(self, y): return y -reveal_type(Overloader(1).method('string')) # E: Revealed type is 'builtins.str' -reveal_type(Overloader(1).method(1)) # E: Revealed type is 'builtins.int' -Overloader(1).method(('tuple',)) # E: No overload variant of "method" of "Overloader" matches argument types [Tuple[builtins.str]] +reveal_type(Overloader(1).method('string')) +reveal_type(Overloader(1).method(1)) +Overloader(1).method(('tuple',)) +[out] +main:12: error: Revealed type is 'builtins.str' +main:13: error: Revealed type is 'builtins.int' +main:14: error: No overload variant of "method" of "Overloader" matches argument types [Tuple[builtins.str]] +main:14: note: Possible overload variants: +main:14: note: @overload +main:14: note: def method(self, y: str) -> str +main:14: note: @overload +main:14: note: def method(self, y: int) -> int + [case testNewNamedTupleMethodInheritance] from typing import NamedTuple, TypeVar diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 721e684c04a4..6048727f3aa9 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -1225,8 +1225,18 @@ class D: [out] main:5: error: Revealed type is 'Any' main:5: error: No overload variant of "__get__" of "D" matches argument types [builtins.None, Type[__main__.A]] +main:5: note: Possible overload variants: +main:5: note: @overload +main:5: note: def __get__(self, inst: None, own: Type[Base]) -> D +main:5: note: @overload +main:5: note: def __get__(self, inst: Base, own: Type[Base]) -> str main:6: error: Revealed type is 'Any' main:6: error: No overload variant of "__get__" of "D" matches argument types [__main__.A, Type[__main__.A]] +main:6: note: Possible overload variants: +main:6: note: @overload +main:6: note: def __get__(self, inst: None, own: Type[Base]) -> D +main:6: note: @overload +main:6: note: def __get__(self, inst: Base, own: Type[Base]) -> str [case testAccessingGenericNonDataDescriptor] @@ -1325,6 +1335,11 @@ class D(Generic[T, V]): [out] main:5: error: Revealed type is 'Any' main:5: error: No overload variant of "__get__" of "D" matches argument types [builtins.None, Type[__main__.A]] +main:5: note: Possible overload variants: +main:5: note: @overload +main:5: note: def __get__(self, inst: None, own: None) -> D[A, int] +main:5: note: @overload +main:5: note: def __get__(self, inst: A, own: Type[A]) -> int [case testAccessingNonDataDescriptorSubclass] from typing import Any @@ -2092,10 +2107,18 @@ class C: obj = object.__new__(cls) return obj c = C(1) -c.a # E: "C" has no attribute "a" +c.a C('', '') -C('') # E: No overload variant of "C" matches argument types [builtins.str] +C('') [builtins fixtures/__new__.pyi] +[out] +tmp/foo.pyi:12: error: "C" has no attribute "a" +tmp/foo.pyi:14: error: No overload variant of "C" matches argument types [builtins.str] +tmp/foo.pyi:14: note: Possible overload variants: +tmp/foo.pyi:14: note: @overload +tmp/foo.pyi:14: note: def __new__(cls, foo: int) -> C +tmp/foo.pyi:14: note: @overload +tmp/foo.pyi:14: note: def __new__(cls, x: str, y: str) -> C -- Special cases @@ -2517,6 +2540,11 @@ u = new(User) [builtins fixtures/classmethod.pyi] [out] tmp/foo.pyi:16: error: No overload variant of "User" matches argument types [builtins.str] +tmp/foo.pyi:16: note: Possible overload variants: +tmp/foo.pyi:16: note: @overload +tmp/foo.pyi:16: note: def __init__(self) -> U +tmp/foo.pyi:16: note: @overload +tmp/foo.pyi:16: note: def __init__(self, arg: int) -> U tmp/foo.pyi:17: error: Too many arguments for "foo" of "User" [case testTypeUsingTypeCInUpperBound] @@ -2712,9 +2740,15 @@ def f(a: int) -> None: pass def mock() -> type: return User f(User) -f(mock()) # E: No overload variant of "f" matches argument types [builtins.type] +f(mock()) [builtins fixtures/classmethod.pyi] [out] +tmp/foo.pyi:13: error: No overload variant of "f" matches argument types [builtins.type] +tmp/foo.pyi:13: note: Possible overload variants: +tmp/foo.pyi:13: note: @overload +tmp/foo.pyi:13: note: def f(a: Type[User]) -> None +tmp/foo.pyi:13: note: @overload +tmp/foo.pyi:13: note: def f(a: int) -> None [case testNonTypeDoesNotMatchOverloadedFunctions] from foo import * @@ -2728,9 +2762,15 @@ def f(a: Type[User]) -> None: pass @overload def f(a: type) -> None: pass -f(3) # E: No overload variant of "f" matches argument types [builtins.int] +f(3) [builtins fixtures/classmethod.pyi] [out] +tmp/foo.pyi:10: error: No overload variant of "f" matches argument types [builtins.int] +tmp/foo.pyi:10: note: Possible overload variants: +tmp/foo.pyi:10: note: @overload +tmp/foo.pyi:10: note: def f(a: Type[User]) -> None +tmp/foo.pyi:10: note: @overload +tmp/foo.pyi:10: note: def f(a: type) -> None [case testInstancesDoNotMatchTypeInOverloadedFunctions] from foo import * @@ -2745,9 +2785,15 @@ def f(a: Type[User]) -> None: pass def f(a: int) -> None: pass f(User) -f(User()) # E: No overload variant of "f" matches argument types [foo.User] +f(User()) [builtins fixtures/classmethod.pyi] [out] +tmp/foo.pyi:11: error: No overload variant of "f" matches argument types [foo.User] +tmp/foo.pyi:11: note: Possible overload variants: +tmp/foo.pyi:11: note: @overload +tmp/foo.pyi:11: note: def f(a: Type[User]) -> None +tmp/foo.pyi:11: note: @overload +tmp/foo.pyi:11: note: def f(a: int) -> None [case testTypeCovarianceWithOverloadedFunctions] from foo import * @@ -2766,15 +2812,26 @@ def f(a: Type[B]) -> None: pass @overload def f(a: int) -> None: pass -f(A) # E: No overload variant of "f" matches argument types [def () -> foo.A] +f(A) f(B) f(C) -f(AType) # E: No overload variant of "f" matches argument types [Type[foo.A]] +f(AType) f(BType) f(CType) [builtins fixtures/classmethod.pyi] [out] - +tmp/foo.pyi:15: error: No overload variant of "f" matches argument types [def () -> foo.A] +tmp/foo.pyi:15: note: Possible overload variants: +tmp/foo.pyi:15: note: @overload +tmp/foo.pyi:15: note: def f(a: Type[B]) -> None +tmp/foo.pyi:15: note: @overload +tmp/foo.pyi:15: note: def f(a: int) -> None +tmp/foo.pyi:18: error: No overload variant of "f" matches argument types [Type[foo.A]] +tmp/foo.pyi:18: note: Possible overload variants: +tmp/foo.pyi:18: note: @overload +tmp/foo.pyi:18: note: def f(a: Type[B]) -> None +tmp/foo.pyi:18: note: @overload +tmp/foo.pyi:18: note: def f(a: int) -> None [case testOverloadedCovariantTypesFail] from foo import * diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index 94ec7dd437e5..5d1720576a58 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -866,12 +866,12 @@ from typing import overload a, b, c = None, None, None # type: (A, B, C) a[b] a[c] -a[1] # E: No overload variant of "__getitem__" of "A" matches argument types [builtins.int] +a[1] i, s = None, None # type: (int, str) i = a[b] -s = a[b] # E: Incompatible types in assignment (expression has type "int", variable has type "str") -i = a[c] # E: Incompatible types in assignment (expression has type "str", variable has type "int") +s = a[b] +i = a[c] s = a[c] class A: @@ -884,6 +884,14 @@ class A: class B: pass class C: pass [out] +tmp/foo.pyi:6: error: No overload variant of "__getitem__" of "A" matches argument types [builtins.int] +tmp/foo.pyi:6: note: Possible overload variants: +tmp/foo.pyi:6: note: @overload +tmp/foo.pyi:6: note: def __getitem__(self, B) -> int +tmp/foo.pyi:6: note: @overload +tmp/foo.pyi:6: note: def __getitem__(self, C) -> str +tmp/foo.pyi:10: error: Incompatible types in assignment (expression has type "int", variable has type "str") +tmp/foo.pyi:11: error: Incompatible types in assignment (expression has type "str", variable has type "int") -- Cast expression diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 183561ca2836..876b45db9b72 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -534,7 +534,14 @@ class A: a = None # type: A a.g() a.g(B()) -a.g(a) # E: No overload variant matches argument types [foo.A] +a.g(a) +[out] +tmp/foo.pyi:12: error: No overload variant matches argument types [foo.A] +tmp/foo.pyi:12: note: Possible overload variants: +tmp/foo.pyi:12: note: @overload +tmp/foo.pyi:12: note: def f(self) -> None +tmp/foo.pyi:12: note: @overload +tmp/foo.pyi:12: note: def f(self, b: B) -> None [case testMethodAsDataAttributeInferredFromDynamicallyTypedMethod] diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 14f6ca04a154..8c808f060cb0 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -1469,10 +1469,17 @@ def f(blocks: Any): # E: Name 'Any' is not defined [case testSpecialCaseEmptyListInitialization2] def f(blocks: object): - to_process = [] # E: Need type annotation for 'to_process' - to_process = list(blocks) # E: No overload variant of "list" matches argument types [builtins.object] + to_process = [] + to_process = list(blocks) [builtins fixtures/list.pyi] [out] +main:2: error: Need type annotation for 'to_process' +main:3: error: No overload variant of "list" matches argument types [builtins.object] +main:3: note: Possible overload variants: +main:3: note: @overload +main:3: note: def [T] __init__(self) -> List[T] +main:3: note: @overload +main:3: note: def [T] __init__(self, x: Iterable[T]) -> List[T] -- Inferring types of variables first initialized to None (partial types) diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 88eabcaf4a61..1ea9bf1cf0ec 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -328,7 +328,7 @@ class B: pass from foo import * [file foo.pyi] from typing import overload -f(C()) # E: No overload variant of "f" matches argument types [foo.C] +f(C()) f(A()) f(B()) @@ -340,6 +340,13 @@ def f(x: 'B') -> None: pass class A: pass class B: pass class C: pass +[out] +tmp/foo.pyi:2: error: No overload variant of "f" matches argument types [foo.C] +tmp/foo.pyi:2: note: Possible overload variants: +tmp/foo.pyi:2: note: @overload +tmp/foo.pyi:2: note: def f(x: A) -> None +tmp/foo.pyi:2: note: @overload +tmp/foo.pyi:2: note: def f(x: B) -> None [case testOverloadedFunctionReturnValue] from foo import * @@ -362,7 +369,7 @@ class B: pass from foo import * [file foo.pyi] from typing import overload -A().f(C()) # E: No overload variant of "f" of "A" matches argument types [foo.C] +A().f(C()) A().f(A()) A().f(B()) @@ -374,6 +381,13 @@ class A: class B: pass class C: pass +[out] +tmp/foo.pyi:2: error: No overload variant of "f" of "A" matches argument types [foo.C] +tmp/foo.pyi:2: note: Possible overload variants: +tmp/foo.pyi:2: note: @overload +tmp/foo.pyi:2: note: def f(self, x: A) -> None +tmp/foo.pyi:2: note: @overload +tmp/foo.pyi:2: note: def f(self, x: B) -> None [case testOverloadedMethodReturnValue] from foo import * @@ -398,12 +412,12 @@ from foo import * from typing import overload a, b = None, None # type: (A, B) a = f(a) -b = f(a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") -f(b) # E: No overload variant of "f" matches argument types [foo.B] +b = f(a) +f(b) b = f(b, a) -a = f(b, a) # E: Incompatible types in assignment (expression has type "B", variable has type "A") -f(a, a) # E: No overload variant of "f" matches argument types [foo.A, foo.A] -f(b, b) # E: No overload variant of "f" matches argument types [foo.B, foo.B] +a = f(b, a) +f(a, a) +f(b, b) @overload def f(x: 'A') -> 'A': pass @@ -411,6 +425,27 @@ def f(x: 'A') -> 'A': pass def f(x: 'B', y: 'A') -> 'B': pass class A: pass class B: pass +[out] +tmp/foo.pyi:4: error: Incompatible types in assignment (expression has type "A", variable has type "B") +tmp/foo.pyi:5: error: No overload variant of "f" matches argument types [foo.B] +tmp/foo.pyi:5: note: Possible overload variants: +tmp/foo.pyi:5: note: @overload +tmp/foo.pyi:5: note: def f(x: A) -> A +tmp/foo.pyi:5: note: @overload +tmp/foo.pyi:5: note: def f(x: B, y: A) -> B +tmp/foo.pyi:7: error: Incompatible types in assignment (expression has type "B", variable has type "A") +tmp/foo.pyi:8: error: No overload variant of "f" matches argument types [foo.A, foo.A] +tmp/foo.pyi:8: note: Possible overload variants: +tmp/foo.pyi:8: note: @overload +tmp/foo.pyi:8: note: def f(x: A) -> A +tmp/foo.pyi:8: note: @overload +tmp/foo.pyi:8: note: def f(x: B, y: A) -> B +tmp/foo.pyi:9: error: No overload variant of "f" matches argument types [foo.B, foo.B] +tmp/foo.pyi:9: note: Possible overload variants: +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(x: A) -> A +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(x: B, y: A) -> B [case testGenericOverloadVariant] from foo import * @@ -438,7 +473,7 @@ from typing import overload a, b = None, None # type: (A, B) a = A(a) a = A(b) -a = A(object()) # E: No overload variant of "A" matches argument types [builtins.object] +a = A(object()) class A: @overload @@ -446,6 +481,13 @@ class A: @overload def __init__(self, b: 'B') -> None: pass class B: pass +[out] +tmp/foo.pyi:5: error: No overload variant of "A" matches argument types [builtins.object] +tmp/foo.pyi:5: note: Possible overload variants: +tmp/foo.pyi:5: note: @overload +tmp/foo.pyi:5: note: def __init__(self, a: A) -> A +tmp/foo.pyi:5: note: @overload +tmp/foo.pyi:5: note: def __init__(self, b: B) -> A [case testIntersectionTypeCompatibility] from foo import * @@ -559,10 +601,17 @@ f(A(), A, A) f(B()) f(B(), B) f(B(), B, B) -f(object()) # E: No overload variant of "f" matches argument types [builtins.object] +f(object()) class A: pass class B: pass [builtins fixtures/list.pyi] +[out] +tmp/foo.pyi:11: error: No overload variant of "f" matches argument types [builtins.object] +tmp/foo.pyi:11: note: Possible overload variants: +tmp/foo.pyi:11: note: @overload +tmp/foo.pyi:11: note: def f(x: A, *more: Any) -> A +tmp/foo.pyi:11: note: @overload +tmp/foo.pyi:11: note: def f(x: B, *more: Any) -> A [case testVarArgsOverload2] from foo import * @@ -574,11 +623,24 @@ def f(x: 'A', *more: 'B') -> 'A': pass def f(x: 'B', *more: 'A') -> 'A': pass f(A(), B()) f(A(), B(), B()) -f(A(), A(), B()) # E: No overload variant of "f" matches argument types [foo.A, foo.A, foo.B] -f(A(), B(), A()) # E: No overload variant of "f" matches argument types [foo.A, foo.B, foo.A] +f(A(), A(), B()) +f(A(), B(), A()) class A: pass class B: pass [builtins fixtures/list.pyi] +[out] +tmp/foo.pyi:8: error: No overload variant of "f" matches argument types [foo.A, foo.A, foo.B] +tmp/foo.pyi:8: note: Possible overload variants: +tmp/foo.pyi:8: note: @overload +tmp/foo.pyi:8: note: def f(x: A, *more: B) -> A +tmp/foo.pyi:8: note: @overload +tmp/foo.pyi:8: note: def f(x: B, *more: A) -> A +tmp/foo.pyi:9: error: No overload variant of "f" matches argument types [foo.A, foo.B, foo.A] +tmp/foo.pyi:9: note: Possible overload variants: +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(x: A, *more: B) -> A +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(x: B, *more: A) -> A [case testOverloadWithTypeObject] from foo import * @@ -740,8 +802,16 @@ A() < A() A() < B() B() < A() B() < B() -A() < object() # E: Unsupported operand types for < ("A" and "object") -B() < object() # E: No overload variant of "__lt__" of "B" matches argument types [builtins.object] +A() < object() +B() < object() +[out] +tmp/foo.pyi:18: error: Unsupported operand types for < ("A" and "object") +tmp/foo.pyi:19: error: No overload variant of "__lt__" of "B" matches argument types [builtins.object] +tmp/foo.pyi:19: note: Possible overload variants: +tmp/foo.pyi:19: note: @overload +tmp/foo.pyi:19: note: def __lt__(self, B) -> int +tmp/foo.pyi:19: note: @overload +tmp/foo.pyi:19: note: def __lt__(self, A) -> int [case testOverloadedForwardMethodAndCallingReverseMethod] from foo import * @@ -757,7 +827,14 @@ class B: A() + A() A() + 1 A() + B() -A() + '' # E: No overload variant of "__add__" of "A" matches argument types [builtins.str] +A() + '' +[out] +tmp/foo.pyi:12: error: No overload variant of "__add__" of "A" matches argument types [builtins.str] +tmp/foo.pyi:12: note: Possible overload variants: +tmp/foo.pyi:12: note: @overload +tmp/foo.pyi:12: note: def __add__(self, A) -> int +tmp/foo.pyi:12: note: @overload +tmp/foo.pyi:12: note: def __add__(self, int) -> int [case testOverrideOverloadedMethodWithMoreGeneralArgumentTypes] from foo import * @@ -842,9 +919,15 @@ def f(x: str) -> None: pass f(1.1) f('') f(1) -f(()) # E: No overload variant of "f" matches argument types [Tuple[]] +f(()) [builtins fixtures/primitives.pyi] [out] +tmp/foo.pyi:9: error: No overload variant of "f" matches argument types [Tuple[]] +tmp/foo.pyi:9: note: Possible overload variants: +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(x: float) -> None +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(x: str) -> None [case testOverloadingVariableInputs] from foo import * @@ -908,10 +991,25 @@ from typing import overload def f(x: int, y: str) -> int: pass @overload def f(*x: str) -> str: pass -f(*(1,))() # E: No overload variant of "f" matches argument types [Tuple[builtins.int]] -f(*('',))() # E: "str" not callable -f(*(1, ''))() # E: "int" not callable -f(*(1, '', 1))() # E: No overload variant of "f" matches argument types [Tuple[builtins.int, builtins.str, builtins.int]] +f(*(1,))() +f(*('',))() +f(*(1, ''))() +f(*(1, '', 1))() +[out] +tmp/foo.pyi:6: error: No overload variant of "f" matches argument types [Tuple[builtins.int]] +tmp/foo.pyi:6: note: Possible overload variants: +tmp/foo.pyi:6: note: @overload +tmp/foo.pyi:6: note: def f(x: int, y: str) -> int +tmp/foo.pyi:6: note: @overload +tmp/foo.pyi:6: note: def f(*x: str) -> str +tmp/foo.pyi:7: error: "str" not callable +tmp/foo.pyi:8: error: "int" not callable +tmp/foo.pyi:9: error: No overload variant of "f" matches argument types [Tuple[builtins.int, builtins.str, builtins.int]] +tmp/foo.pyi:9: note: Possible overload variants: +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(x: int, y: str) -> int +tmp/foo.pyi:9: note: @overload +tmp/foo.pyi:9: note: def f(*x: str) -> str [case testPreferExactSignatureMatchInOverload] from foo import * @@ -956,11 +1054,21 @@ def f(x: T) -> T: pass def f(x: int) -> bool: pass class mystr(str): pass -f('x')() # E: "str" not callable -f(1)() # E: "bool" not callable -f(1.1) # E: No overload variant of "f" matches argument types [builtins.float] -f(mystr())() # E: "mystr" not callable +f('x')() +f(1)() +f(1.1) +f(mystr())() [builtins fixtures/primitives.pyi] +[out] +tmp/foo.pyi:9: error: "str" not callable +tmp/foo.pyi:10: error: "bool" not callable +tmp/foo.pyi:11: error: No overload variant of "f" matches argument types [builtins.float] +tmp/foo.pyi:11: note: Possible overload variants: +tmp/foo.pyi:11: note: @overload +tmp/foo.pyi:11: note: def [T <: str] f(x: T) -> T +tmp/foo.pyi:11: note: @overload +tmp/foo.pyi:11: note: def f(x: int) -> bool +tmp/foo.pyi:12: error: "mystr" not callable [case testOverloadedCallWithVariableTypes] from foo import * @@ -976,13 +1084,23 @@ class mystr(str): pass U = TypeVar('U', bound=mystr) V = TypeVar('V') def g(x: U, y: V) -> None: - f(x)() # E: "mystr" not callable - f(y) # E: No overload variant of "f" matches argument types [V`-2] - a = f([x]) # E: "f" does not return a value - f([y]) # E: Value of type variable "T" of "f" cannot be "V" - f([x, y]) # E: Value of type variable "T" of "f" cannot be "object" + f(x)() + f(y) + a = f([x]) + f([y]) + f([x, y]) [builtins fixtures/list.pyi] [out] +tmp/foo.pyi:12: error: "mystr" not callable +tmp/foo.pyi:13: error: No overload variant of "f" matches argument types [V`-2] +tmp/foo.pyi:13: note: Possible overload variants: +tmp/foo.pyi:13: note: @overload +tmp/foo.pyi:13: note: def [T <: str] f(x: T) -> T +tmp/foo.pyi:13: note: @overload +tmp/foo.pyi:13: note: def [T <: str] f(x: List[T]) -> None +tmp/foo.pyi:14: error: "f" does not return a value +tmp/foo.pyi:15: error: Value of type variable "T" of "f" cannot be "V" +tmp/foo.pyi:16: error: Value of type variable "T" of "f" cannot be "object" [case testOverlapWithTypeVars] from foo import * @@ -1008,10 +1126,10 @@ def f(x: int) -> int: pass @overload def f(x: AnyStr) -> str: pass -f(1)() # E: "int" not callable -f('1')() # E: "str" not callable -f(b'1')() # E: "str" not callable -f(1.0) # E: No overload variant of "f" matches argument types [builtins.float] +f(1)() +f('1')() +f(b'1')() +f(1.0) @overload def g(x: AnyStr, *a: AnyStr) -> None: pass @@ -1020,11 +1138,23 @@ def g(x: int, *a: AnyStr) -> None: pass g('foo') g('foo', 'bar') -g('foo', b'bar') # E: Value of type variable "AnyStr" of "g" cannot be "object" +g('foo', b'bar') g(1) g(1, 'foo') -g(1, 'foo', b'bar') # E: Value of type variable "AnyStr" of "g" cannot be "object" +g(1, 'foo', b'bar') [builtins fixtures/primitives.pyi] +[out] +tmp/foo.pyi:9: error: "int" not callable +tmp/foo.pyi:10: error: "str" not callable +tmp/foo.pyi:11: error: "str" not callable +tmp/foo.pyi:12: error: No overload variant of "f" matches argument types [builtins.float] +tmp/foo.pyi:12: note: Possible overload variants: +tmp/foo.pyi:12: note: @overload +tmp/foo.pyi:12: note: def f(x: int) -> int +tmp/foo.pyi:12: note: @overload +tmp/foo.pyi:12: note: def [AnyStr in (bytes, str)] f(x: AnyStr) -> str +tmp/foo.pyi:21: error: Value of type variable "AnyStr" of "g" cannot be "object" +tmp/foo.pyi:24: error: Value of type variable "AnyStr" of "g" cannot be "object" [case testBadOverlapWithTypeVarsWithValues] from foo import * @@ -1157,7 +1287,14 @@ from typing import overload, Callable def f(a: Callable[[], int]) -> None: pass @overload def f(a: str) -> None: pass -f(0) # E: No overload variant of "f" matches argument types [builtins.int] +f(0) +[out] +tmp/foo.pyi:6: error: No overload variant of "f" matches argument types [builtins.int] +tmp/foo.pyi:6: note: Possible overload variants: +tmp/foo.pyi:6: note: @overload +tmp/foo.pyi:6: note: def f(a: Callable[[], int]) -> None +tmp/foo.pyi:6: note: @overload +tmp/foo.pyi:6: note: def f(a: str) -> None [case testCustomRedefinitionDecorator] from typing import Any, Callable, Type @@ -1489,4 +1626,3 @@ class Child4(ParentWithDynamicImpl): def f(self, arg: Any) -> Any: ... [builtins fixtures/tuple.pyi] - diff --git a/test-data/unit/check-protocols.test b/test-data/unit/check-protocols.test index 976720422002..321a84d3eb9c 100644 --- a/test-data/unit/check-protocols.test +++ b/test-data/unit/check-protocols.test @@ -1295,16 +1295,28 @@ def f(x: P2) -> str: ... def f(x): if isinstance(x, P1): return P1.attr1 - if isinstance(x, P2): # E: Only @runtime protocols can be used with instance and class checks + if isinstance(x, P2): return P1.attr2 -reveal_type(f(C1())) # E: Revealed type is 'builtins.int' -reveal_type(f(C2())) # E: Revealed type is 'builtins.str' +reveal_type(f(C1())) +reveal_type(f(C2())) class D(C1, C2): pass # Compatible with both P1 and P2 # FIXME: the below is not right, see #1322 -reveal_type(f(D())) # E: Revealed type is 'Any' -f(C()) # E: No overload variant of "f" matches argument types [__main__.C] +reveal_type(f(D())) +f(C()) [builtins fixtures/isinstance.pyi] +[out] +main:22: error: Only @runtime protocols can be used with instance and class checks +main:25: error: Revealed type is 'builtins.int' +main:26: error: Revealed type is 'builtins.str' +main:29: error: Revealed type is 'Any' +main:30: error: No overload variant of "f" matches argument types [__main__.C] +main:30: note: Possible overload variants: +main:30: note: @overload +main:30: note: def f(x: P1) -> int +main:30: note: @overload +main:30: note: def f(x: P2) -> str + -- Unions of protocol types -- ------------------------ diff --git a/test-data/unit/check-serialize.test b/test-data/unit/check-serialize.test index 2d61830a1a96..04dc12d1c548 100644 --- a/test-data/unit/check-serialize.test +++ b/test-data/unit/check-serialize.test @@ -294,7 +294,17 @@ class A: def __init__(self, x: str) -> None: pass [out2] tmp/a.py:2: error: No overload variant of "A" matches argument types [builtins.object] +tmp/a.py:2: note: Possible overload variants: +tmp/a.py:2: note: @overload +tmp/a.py:2: note: def (x: int) -> A +tmp/a.py:2: note: @overload +tmp/a.py:2: note: def (x: str) -> A tmp/a.py:7: error: No overload variant of "__init__" of "A" matches argument types [builtins.object] +tmp/a.py:7: note: Possible overload variants: +tmp/a.py:7: note: @overload +tmp/a.py:7: note: def (x: int) -> None +tmp/a.py:7: note: @overload +tmp/a.py:7: note: def (x: str) -> None [case testSerialize__new__] import a diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index ea4fa97f74ea..37e220b003b6 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -906,15 +906,31 @@ reveal_type(d.get('x', a)) # E: Revealed type is 'Union[builtins.list[builtins.i from mypy_extensions import TypedDict D = TypedDict('D', {'x': int, 'y': str}) d: D -d.get() # E: No overload variant of "get" of "Mapping" matches argument types [] -d.get('x', 1, 2) # E: No overload variant of "get" of "Mapping" matches argument types [builtins.str, builtins.int, builtins.int] -x = d.get('z') # E: TypedDict "D" has no key 'z' -reveal_type(x) # E: Revealed type is 'Any' +d.get() +d.get('x', 1, 2) +x = d.get('z') +reveal_type(x) s = '' y = d.get(s) -reveal_type(y) # E: Revealed type is 'builtins.object*' +reveal_type(y) [builtins fixtures/dict.pyi] [typing fixtures/typing-full.pyi] +[out] +main:4: error: No overload variant of "get" of "Mapping" matches argument types [] +main:4: note: Possible overload variants: +main:4: note: @overload +main:4: note: def get(self, k: str) -> object +main:4: note: @overload +main:4: note: def [V] get(self, k: str, default: object) -> object +main:5: error: No overload variant of "get" of "Mapping" matches argument types [builtins.str, builtins.int, builtins.int] +main:5: note: Possible overload variants: +main:5: note: @overload +main:5: note: def get(self, k: str) -> object +main:5: note: @overload +main:5: note: def [V] get(self, k: str, default: Union[int, V]) -> object +main:6: error: TypedDict "D" has no key 'z' +main:7: error: Revealed type is 'Any' +main:10: error: Revealed type is 'builtins.object*' [case testTypedDictMissingMethod] from mypy_extensions import TypedDict @@ -1205,9 +1221,16 @@ def f(x: int) -> None: ... def f(x): pass a: A -f(a) # E: No overload variant of "f" matches argument types [TypedDict('__main__.A', {'x': builtins.int})] +f(a) [builtins fixtures/dict.pyi] [typing fixtures/typing-full.pyi] +[out] +main:13: error: No overload variant of "f" matches argument types [TypedDict('__main__.A', {'x': builtins.int})] +main:13: note: Possible overload variants: +main:13: note: @overload +main:13: note: def f(x: str) -> None +main:13: note: @overload +main:13: note: def f(x: int) -> None [case testTypedDictOverloading4] from typing import overload diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index f4a3e9411f6b..d1f5b28c2cab 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -6302,6 +6302,11 @@ def f(x): [out] == main:3: error: No overload variant of "f" matches argument types [builtins.str] +main:3: note: Possible overload variants: +main:3: note: @overload +main:3: note: def f(x: int) -> None +main:3: note: @overload +main:3: note: def f(x: C) -> int [case testOverloadsDeleted] import mod @@ -6411,6 +6416,11 @@ T = TypeVar('T', bound=str) [out] == a.py:2: error: No overload variant of "f" matches argument types [builtins.int] +a.py:2: note: Possible overload variants: +a.py:2: note: @overload +a.py:2: note: def f(x: C) -> None +a.py:2: note: @overload +a.py:2: note: def [c.T <: str] f(x: c.T) -> c.T [case testOverloadsGenericToNonGeneric] import a @@ -6436,6 +6446,11 @@ class T: pass [out] == a.py:2: error: No overload variant of "f" matches argument types [builtins.int] +a.py:2: note: Possible overload variants: +a.py:2: note: @overload +a.py:2: note: def f(x: C) -> None +a.py:2: note: @overload +a.py:2: note: def f(x: T) -> T [case testOverloadsToNonOverloaded] import a @@ -6591,6 +6606,11 @@ class C: [out] == a.py:2: error: No overload variant of "B" matches argument types [builtins.int] +a.py:2: note: Possible overload variants: +a.py:2: note: @overload +a.py:2: note: def __init__(self, x: str) -> B +a.py:2: note: @overload +a.py:2: note: def __init__(self, x: str, y: int) -> B [case testOverloadedToNormalMethodMetaclass] import a diff --git a/test-data/unit/python2eval.test b/test-data/unit/python2eval.test index d73f3dd33ff1..eeb157b6431b 100644 --- a/test-data/unit/python2eval.test +++ b/test-data/unit/python2eval.test @@ -320,6 +320,11 @@ def f(x): # type: (bytearray) -> int pass [out] _program.py:2: error: No overload variant of "f" matches argument types [builtins.int] +_program.py:2: note: Possible overload variants: +_program.py:2: note: @overload +_program.py:2: note: def f(x: unicode) -> int +_program.py:2: note: @overload +_program.py:2: note: def f(x: bytearray) -> int [case testByteArrayStrCompatibility_python2] def f(x): # type: (str) -> None diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index e193de93dffd..4aac358ab36a 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1041,11 +1041,16 @@ d.get() s = '' reveal_type(d.get(s)) [out] -_testTypedDictGet.py:7: error: Revealed type is 'builtins.int' -_testTypedDictGet.py:8: error: Revealed type is 'builtins.str' -_testTypedDictGet.py:9: error: TypedDict "D" has no key 'z' -_testTypedDictGet.py:10: error: No overload variant of "get" of "Mapping" matches argument types [] -_testTypedDictGet.py:12: error: Revealed type is 'builtins.object*' +_program.py:7: error: Revealed type is 'builtins.int' +_program.py:8: error: Revealed type is 'builtins.str' +_program.py:9: error: TypedDict "D" has no key 'z' +_program.py:10: error: No overload variant of "get" of "Mapping" matches argument types [] +_program.py:10: note: Possible overload variants: +_program.py:10: note: @overload +_program.py:10: note: def get(self, k: str) -> object +_program.py:10: note: @overload +_program.py:10: note: def [_T] get(self, k: str, default: object) -> object +_program.py:12: error: Revealed type is 'builtins.object*' [case testTypedDictMappingMethods] from mypy_extensions import TypedDict