diff --git a/mypy/applytype.py b/mypy/applytype.py index 6d2f3a9a1de0..75831116562e 100644 --- a/mypy/applytype.py +++ b/mypy/applytype.py @@ -38,12 +38,11 @@ def apply_generic_arguments(callable: CallableType, types: List[Type], types[i] = value break else: - msg.incompatible_typevar_value(callable, i + 1, type, context) - + msg.incompatible_typevar_value(callable, type, callable.variables[i].name, context) upper_bound = callable.variables[i].upper_bound if (type and not isinstance(type, PartialType) and not mypy.subtypes.is_subtype(type, upper_bound)): - msg.incompatible_typevar_value(callable, i + 1, type, context) + msg.incompatible_typevar_value(callable, type, callable.variables[i].name, context) # Create a map from type variable id to target type. id_to_type = {} # type: Dict[TypeVarId, Type] diff --git a/mypy/messages.py b/mypy/messages.py index 44bc57548ada..8ce30efa7018 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -92,6 +92,7 @@ CANNOT_ISINSTANCE_NEWTYPE = 'Cannot use isinstance() with a NewType type' BARE_GENERIC = 'Missing type parameters for generic type' IMPLICIT_GENERIC_ANY_BUILTIN = 'Implicit generic "Any". Use \'{}\' and specify generic parameters' +INCOMPATIBLE_TYPEVAR_VALUE = 'Value of type variable "{}" of {} cannot be {}' ARG_CONSTRUCTOR_NAMES = { ARG_POS: "Arg", @@ -859,10 +860,13 @@ def read_only_property(self, name: str, type: TypeInfo, self.fail('Property "{}" defined in "{}" is read-only'.format( name, type.name()), context) - def incompatible_typevar_value(self, callee: CallableType, index: int, - type: Type, context: Context) -> None: - self.fail('Type argument {} of {} has incompatible value {}'.format( - index, callable_name(callee), self.format(type)), context) + def incompatible_typevar_value(self, + callee: CallableType, + typ: Type, + typevar_name: str, + context: Context) -> None: + self.fail(INCOMPATIBLE_TYPEVAR_VALUE.format(typevar_name, callable_name(callee), + self.format(typ)), context) def overloaded_signatures_overlap(self, index1: int, index2: int, context: Context) -> None: diff --git a/mypy/typeanal.py b/mypy/typeanal.py index da3461795192..582599b22d98 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -625,8 +625,7 @@ def visit_instance(self, t: Instance) -> None: continue else: arg_values = [arg] - self.check_type_var_values(info, arg_values, - tvar.values, i + 1, t) + self.check_type_var_values(info, arg_values, tvar.name, tvar.values, i + 1, t) if not is_subtype(arg, tvar.upper_bound): self.fail('Type argument "{}" of "{}" must be ' 'a subtype of "{}"'.format( @@ -637,7 +636,7 @@ def visit_instance(self, t: Instance) -> None: for base in info.bases: base.accept(self) - def check_type_var_values(self, type: TypeInfo, actuals: List[Type], + def check_type_var_values(self, type: TypeInfo, actuals: List[Type], arg_name: str, valids: List[Type], arg_number: int, context: Context) -> None: for actual in actuals: if (not isinstance(actual, AnyType) and @@ -646,8 +645,10 @@ def check_type_var_values(self, type: TypeInfo, actuals: List[Type], self.fail('Invalid type argument value for "{}"'.format( type.name()), context) else: - self.fail('Type argument {} of "{}" has incompatible value "{}"'.format( - arg_number, type.name(), actual.type.name()), context) + class_name = '"{}"'.format(type.name()) + actual_type_name = '"{}"'.format(actual.type.name()) + self.fail(messages.INCOMPATIBLE_TYPEVAR_VALUE.format( + arg_name, class_name, actual_type_name), context) def visit_callable_type(self, t: CallableType) -> None: t.ret_type.accept(self) diff --git a/test-data/unit/check-bound.test b/test-data/unit/check-bound.test index 4d6ede29ebc6..043148f6423d 100644 --- a/test-data/unit/check-bound.test +++ b/test-data/unit/check-bound.test @@ -24,8 +24,8 @@ b = B() b = f(b) b = f(C()) # Fail [out] -main:12: error: Type argument 1 of "f" has incompatible value "U" -main:16: error: Type argument 1 of "f" has incompatible value "D" +main:12: error: Value of type variable "T" of "f" cannot be "U" +main:16: error: Value of type variable "T" of "f" cannot be "D" main:20: error: Incompatible types in assignment (expression has type "C", variable has type "B") @@ -42,7 +42,7 @@ class G(Generic[T]): v = None # type: G[A] w = None # type: G[B] x = None # type: G[str] # E: Type argument "builtins.str" of "G" must be a subtype of "__main__.A" -y = G('a') # E: Type argument 1 of "G" has incompatible value "str" +y = G('a') # E: Value of type variable "T" of "G" cannot be "str" z = G(A()) z = G(B()) @@ -125,7 +125,7 @@ def j(x: TA) -> A: def k(x: TA) -> B: return x # Fail [out] -main:16: error: Type argument 1 of "h" has incompatible value "TA" +main:16: error: Value of type variable "TB" of "h" cannot be "TA" main:21: error: Incompatible return value type (got "TA", expected "B") @@ -199,5 +199,5 @@ def foo(x: int) -> int: a = 1 b = foo(a) b = 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "int") -twice(a) # E: Type argument 1 of "twice" has incompatible value "int" +twice(a) # E: Value of type variable "T" of "twice" cannot be "int" [builtins fixtures/args.pyi] diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 97ace5ad2d41..7d7f0fa2ddd6 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -2118,7 +2118,7 @@ def error(u_c: Type[U]) -> P: [out] main:11: error: Revealed type is '__main__.WizUser*' main:13: error: Incompatible return value type (got "U", expected "P") -main:13: error: Type argument 1 of "new_pro" has incompatible value "U" +main:13: error: Value of type variable "P" of "new_pro" cannot be "U" [case testTypeUsingTypeCCovariance] from typing import Type, TypeVar diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index 15babb988782..0d962533eabd 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -852,7 +852,7 @@ fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected List[Tup fun1([(1, 'x')]) # E: Cannot infer type argument 1 of "fun1" reveal_type(fun2([(1, 1)], 1)) # E: Revealed type is 'builtins.list[Tuple[builtins.int*, builtins.int*]]' -fun2([('x', 'x')], 'x') # E: Type argument 1 of "fun2" has incompatible value "str" +fun2([('x', 'x')], 'x') # E: Value of type variable "T" of "fun2" cannot be "str" [builtins fixtures/list.pyi] @@ -1068,9 +1068,9 @@ y = None # type: SameA[str] # Two errors here, for both args of A [builtins fixtures/list.pyi] [out] -main:9:7: error: Type argument 1 of "A" has incompatible value "str" -main:13: error: Type argument 1 of "A" has incompatible value "str" -main:13: error: Type argument 2 of "A" has incompatible value "str" +main:9:7: error: Value of type variable "T" of "A" cannot be "str" +main:13: error: Value of type variable "T" of "A" cannot be "str" +main:13: error: Value of type variable "S" of "A" cannot be "str" [case testGenericTypeAliasesIgnoredPotentialAlias] class A: ... diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 42cd312c0531..cbb17b250cc1 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -750,10 +750,10 @@ AnyStr = TypeVar('AnyStr', bytes, str) def f(x: Union[AnyStr, int], *a: AnyStr) -> None: pass f('foo') f('foo', 'bar') -f('foo', b'bar') # E: Type argument 1 of "f" has incompatible value "object" +f('foo', b'bar') # E: Value of type variable "AnyStr" of "f" cannot be "object" f(1) f(1, 'foo') -f(1, 'foo', b'bar') # E: Type argument 1 of "f" has incompatible value "object" +f(1, 'foo', b'bar') # E: Value of type variable "AnyStr" of "f" cannot be "object" [builtins fixtures/primitives.pyi] diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 82458fd30fc4..0f5060fe3a12 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -957,8 +957,8 @@ 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: Type argument 1 of "f" has incompatible value "V" - f([x, y]) # E: Type argument 1 of "f" has incompatible value "object" + 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" [builtins fixtures/list.pyi] [out] @@ -998,10 +998,10 @@ def g(x: int, *a: AnyStr) -> None: pass g('foo') g('foo', 'bar') -g('foo', b'bar') # E: Type argument 1 of "g" has incompatible value "object" +g('foo', b'bar') # E: Value of type variable "AnyStr" of "g" cannot be "object" g(1) g(1, 'foo') -g(1, 'foo', b'bar') # E: Type argument 1 of "g" has incompatible value "object" +g(1, 'foo', b'bar') # E: Value of type variable "AnyStr" of "g" cannot be "object" [builtins fixtures/primitives.pyi] [case testBadOverlapWithTypeVarsWithValues] diff --git a/test-data/unit/check-typevar-values.test b/test-data/unit/check-typevar-values.test index 7604ae358a4f..dd73dbb18a90 100644 --- a/test-data/unit/check-typevar-values.test +++ b/test-data/unit/check-typevar-values.test @@ -7,7 +7,7 @@ T = TypeVar('T', int, str) def f(x: T) -> None: pass f(1) f('x') -f(object()) # E: Type argument 1 of "f" has incompatible value "object" +f(object()) # E: Value of type variable "T" of "f" cannot be "object" [case testCallGenericFunctionWithTypeVarValueRestrictionUsingContext] from typing import TypeVar, List @@ -18,7 +18,7 @@ s = ['x'] o = [object()] i = f(1) s = f('') -o = f(1) # E: Type argument 1 of "f" has incompatible value "object" +o = f(1) # E: Value of type variable "T" of "f" cannot be "object" [builtins fixtures/list.pyi] [case testCallGenericFunctionWithTypeVarValueRestrictionAndAnyArgs] @@ -228,7 +228,7 @@ X = TypeVar('X', int, str) class A(Generic[X]): pass a = None # type: A[int] b = None # type: A[str] -d = None # type: A[object] # E: Type argument 1 of "A" has incompatible value "object" +d = None # type: A[object] # E: Value of type variable "X" of "A" cannot be "object" c = None # type: A[Any] [case testConstructGenericTypeWithTypevarValuesAndTypeInference] @@ -239,7 +239,7 @@ class A(Generic[X]): A(1) A('x') A(cast(Any, object())) -A(object()) # E: Type argument 1 of "A" has incompatible value "object" +A(object()) # E: Value of type variable "X" of "A" cannot be "object" [case testGenericTypeWithTypevarValuesAndTypevarArgument] from typing import TypeVar, Generic @@ -390,8 +390,8 @@ Y = TypeVar('Y', int, str) class C(Generic[X, Y]): pass a = None # type: C[A, int] b = None # type: C[B, str] -c = None # type: C[int, int] # E: Type argument 1 of "C" has incompatible value "int" -d = None # type: C[A, A] # E: Type argument 2 of "C" has incompatible value "A" +c = None # type: C[int, int] # E: Value of type variable "X" of "C" cannot be "int" +d = None # type: C[A, A] # E: Value of type variable "Y" of "C" cannot be "A" [case testCallGenericFunctionUsingMultipleTypevarsWithValues] from typing import TypeVar @@ -402,8 +402,8 @@ Y = TypeVar('Y', int, str) def f(x: X, y: Y) -> None: pass f(A(), '') f(B(), 1) -f(A(), A()) # E: Type argument 2 of "f" has incompatible value "A" -f(1, 1) # E: Type argument 1 of "f" has incompatible value "int" +f(A(), A()) # E: Value of type variable "Y" of "f" cannot be "A" +f(1, 1) # E: Value of type variable "X" of "f" cannot be "int" [case testGenericFunctionWithNormalAndRestrictedTypevar] from typing import TypeVar, Generic @@ -418,7 +418,7 @@ def f(x: X, y: Y, z: int) -> None: z = y # Error y.foo # Error [out] -main:8: error: Type argument 1 of "C" has incompatible value "X" +main:8: error: Value of type variable "Y" of "C" cannot be "X" main:9: error: Incompatible types in assignment (expression has type "X", variable has type "int") main:10: error: Incompatible types in assignment (expression has type "str", variable has type "int") main:11: error: "int" has no attribute "foo" diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 9ec9997f0169..68af402e4601 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1277,7 +1277,7 @@ re.subn(bpat, b'', b'')[0] + b'' re.subn(bre, lambda m: b'', b'')[0] + b'' re.subn(bpat, lambda m: b'', b'')[0] + b'' [out] -_program.py:7: error: Type argument 1 of "search" has incompatible value "object" +_program.py:7: error: Value of type variable "AnyStr" of "search" cannot be "object" _program.py:9: error: Cannot infer type argument 1 of "search" [case testReModuleString] @@ -1301,7 +1301,7 @@ re.subn(spat, '', '')[0] + '' re.subn(sre, lambda m: '', '')[0] + '' re.subn(spat, lambda m: '', '')[0] + '' [out] -_program.py:7: error: Type argument 1 of "search" has incompatible value "object" +_program.py:7: error: Value of type variable "AnyStr" of "search" cannot be "object" _program.py:9: error: Cannot infer type argument 1 of "search" [case testListSetitemTuple]