Skip to content

Show name of type variable in "Cannot infer type argument" message #19290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2338,10 +2338,10 @@ def apply_inferred_arguments(
# Report error if some of the variables could not be solved. In that
# case assume that all variables have type Any to avoid extra
# bogus error messages.
for i, inferred_type in enumerate(inferred_args):
for inferred_type, tv in zip(inferred_args, callee_type.variables):
if not inferred_type or has_erased_component(inferred_type):
# Could not infer a non-trivial type for a type variable.
self.msg.could_not_infer_type_arguments(callee_type, i + 1, context)
self.msg.could_not_infer_type_arguments(callee_type, tv, context)
inferred_args = [AnyType(TypeOfAny.from_error)] * len(inferred_args)
# Apply the inferred types to the function type. In this case the
# return type must be CallableType, since we give the right number of type
Expand Down
9 changes: 6 additions & 3 deletions mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -1370,11 +1370,14 @@ def incompatible_type_application(
self.fail(f"Type application has too few types ({s})", context)

def could_not_infer_type_arguments(
self, callee_type: CallableType, n: int, context: Context
self, callee_type: CallableType, tv: TypeVarLikeType, context: Context
) -> None:
callee_name = callable_name(callee_type)
if callee_name is not None and n > 0:
self.fail(f"Cannot infer type argument {n} of {callee_name}", context)
if callee_name is not None:
self.fail(
f"Cannot infer value of type parameter {format_type(tv, self.options)} of {callee_name}",
context,
)
if callee_name == "<dict>":
# Invariance in key type causes more of these errors than we would want.
self.note(
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-dataclasses.test
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ class A(Generic[T]):
return self.z # E: Incompatible return value type (got "list[T]", expected "T")

reveal_type(A) # N: Revealed type is "def [T] (x: T`1, y: T`1, z: builtins.list[T`1]) -> __main__.A[T`1]"
A(1, 2, ["a", "b"]) # E: Cannot infer type argument 1 of "A"
A(1, 2, ["a", "b"]) # E: Cannot infer value of type parameter "T" of "A"
a = A(1, 2, [1, 2])
reveal_type(a) # N: Revealed type is "__main__.A[builtins.int]"
reveal_type(a.x) # N: Revealed type is "builtins.int"
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-expressions.test
Original file line number Diff line number Diff line change
Expand Up @@ -1878,7 +1878,7 @@ a = {'a': 1}
b = {'z': 26, **a}
c = {**b}
d = {**a, **b, 'c': 3}
e = {1: 'a', **a} # E: Cannot infer type argument 1 of <dict> \
e = {1: 'a', **a} # E: Cannot infer value of type parameter "KT" of <dict> \
# N: Try assigning the literal to a variable annotated as dict[<key>, <val>]
f = {**b} # type: Dict[int, int] # E: Unpacked dict entry 0 has incompatible type "dict[str, int]"; expected "SupportsKeysAndGetItem[int, int]"
g = {**Thing()}
Expand All @@ -1893,7 +1893,7 @@ i = {**Thing()} # type: Dict[int, int] # E: Unpacked dict entry 0 has incompat
# N: def keys(self) -> Iterable[int] \
# N: Got: \
# N: def keys(self) -> Iterable[str]
j = {1: 'a', **Thing()} # E: Cannot infer type argument 1 of <dict> \
j = {1: 'a', **Thing()} # E: Cannot infer value of type parameter "KT" of <dict> \
# N: Try assigning the literal to a variable annotated as dict[<key>, <val>]
[builtins fixtures/dict.pyi]
[typing fixtures/typing-medium.pyi]
Expand Down
6 changes: 3 additions & 3 deletions test-data/unit/check-generics.test
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ def func2(x: SameNode[T]) -> SameNode[T]:
return x
reveal_type(func2) # N: Revealed type is "def [T] (x: __main__.Node[T`-1, T`-1]) -> __main__.Node[T`-1, T`-1]"

func2(Node(1, 'x')) # E: Cannot infer type argument 1 of "func2"
func2(Node(1, 'x')) # E: Cannot infer value of type parameter "T" of "func2"
y = func2(Node('x', 'x'))
reveal_type(y) # N: Revealed type is "__main__.Node[builtins.str, builtins.str]"

Expand Down Expand Up @@ -888,7 +888,7 @@ def fun2(v: Vec[T], scale: T) -> Vec[T]:

reveal_type(fun1([(1, 1)])) # N: Revealed type is "builtins.int"
fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected "list[tuple[bool, bool]]"
fun1([(1, 'x')]) # E: Cannot infer type argument 1 of "fun1"
fun1([(1, 'x')]) # E: Cannot infer value of type parameter "T" of "fun1"

reveal_type(fun2([(1, 1)], 1)) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.int]]"
fun2([('x', 'x')], 'x') # E: Value of type variable "T" of "fun2" cannot be "str"
Expand All @@ -909,7 +909,7 @@ def f(x: Node[T, T]) -> TupledNode[T]:
return Node(x.x, (x.x, x.x))

f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "Node[Never, Never]"
f(Node(1, 'x')) # E: Cannot infer type argument 1 of "f"
f(Node(1, 'x')) # E: Cannot infer value of type parameter "T" of "f"
reveal_type(Node('x', 'x')) # N: Revealed type is "a.Node[builtins.str, builtins.str]"

[file a.py]
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-inference-context.test
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,7 @@ class D(C): ...

def f(x: List[T], y: List[T]) -> List[T]: ...

f([C()], [D()]) # E: Cannot infer type argument 1 of "f"
f([C()], [D()]) # E: Cannot infer value of type parameter "T" of "f"
[builtins fixtures/list.pyi]

[case testInferTypeVariableFromTwoGenericTypes3]
Expand Down
24 changes: 20 additions & 4 deletions test-data/unit/check-inference.test
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ class A(Generic[T]): pass
class B: pass


f(ao, ab) # E: Cannot infer type argument 1 of "f"
f(ab, ao) # E: Cannot infer type argument 1 of "f"
f(ao, ab) # E: Cannot infer value of type parameter "T" of "f"
f(ab, ao) # E: Cannot infer value of type parameter "T" of "f"
f(ao, ao)
f(ab, ab)

Expand Down Expand Up @@ -3774,8 +3774,8 @@ reveal_type(f(x, [])) # N: Revealed type is "builtins.str"
reveal_type(f(["yes"], [])) # N: Revealed type is "builtins.str"

empty: List[NoReturn]
f(x, empty) # E: Cannot infer type argument 1 of "f"
f(["no"], empty) # E: Cannot infer type argument 1 of "f"
f(x, empty) # E: Cannot infer value of type parameter "T" of "f"
f(["no"], empty) # E: Cannot infer value of type parameter "T" of "f"
[builtins fixtures/list.pyi]

[case testInferenceWorksWithEmptyCollectionsUnion]
Expand Down Expand Up @@ -4149,3 +4149,19 @@ class Foo:
else:
self.qux = {} # E: Need type annotation for "qux" (hint: "qux: dict[<type>, <type>] = ...")
[builtins fixtures/dict.pyi]

[case testConstraintSolvingFailureShowsCorrectArgument]
from typing import Callable, TypeVar

T1 = TypeVar('T1')
T2 = TypeVar('T2')
def foo(
a: T1,
b: T2,
c: Callable[[T2], T2],
) -> tuple[T1, T2]: ...

def bar(y: float) -> float: ...

foo(1, None, bar) # E: Cannot infer value of type parameter "T2" of "foo"
[builtins fixtures/tuple.pyi]
4 changes: 2 additions & 2 deletions test-data/unit/check-literal.test
Original file line number Diff line number Diff line change
Expand Up @@ -2989,9 +2989,9 @@ def g(a: T, t: A[T]) -> T: ...

def check(obj: A[Literal[1]]) -> None:
reveal_type(f(obj, 1)) # N: Revealed type is "Literal[1]"
reveal_type(f(obj, '')) # E: Cannot infer type argument 1 of "f" \
reveal_type(f(obj, '')) # E: Cannot infer value of type parameter "T" of "f" \
# N: Revealed type is "Any"
reveal_type(g(1, obj)) # N: Revealed type is "Literal[1]"
reveal_type(g('', obj)) # E: Cannot infer type argument 1 of "g" \
reveal_type(g('', obj)) # E: Cannot infer value of type parameter "T" of "g" \
# N: Revealed type is "Any"
[builtins fixtures/tuple.pyi]
6 changes: 3 additions & 3 deletions test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -3370,10 +3370,10 @@ def wrapper() -> None:
obj2: Union[W1[A], W2[B]]

reveal_type(foo(obj2)) # N: Revealed type is "Union[__main__.A, __main__.B]"
bar(obj2) # E: Cannot infer type argument 1 of "bar"
bar(obj2) # E: Cannot infer value of type parameter "T" of "bar"

b1_overload: A = foo(obj2) # E: Incompatible types in assignment (expression has type "Union[A, B]", variable has type "A")
b1_union: A = bar(obj2) # E: Cannot infer type argument 1 of "bar"
b1_union: A = bar(obj2) # E: Cannot infer value of type parameter "T" of "bar"

[case testOverloadingInferUnionReturnWithObjectTypevarReturn]
from typing import overload, Union, TypeVar, Generic
Expand Down Expand Up @@ -3496,7 +3496,7 @@ def t_is_same_bound(arg1: T1, arg2: S) -> Tuple[T1, S]:
# The arguments in the tuple are swapped
x3: Union[List[S], List[Tuple[S, T1]]]
y3: S
Dummy[T1]().foo(x3, y3) # E: Cannot infer type argument 1 of "foo" of "Dummy" \
Dummy[T1]().foo(x3, y3) # E: Cannot infer value of type parameter "S" of "foo" of "Dummy" \
# E: Argument 1 to "foo" of "Dummy" has incompatible type "Union[list[S], list[tuple[S, T1]]]"; expected "list[tuple[T1, Any]]"

x4: Union[List[int], List[Tuple[C, int]]]
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-parameter-specification.test
Original file line number Diff line number Diff line change
Expand Up @@ -2135,7 +2135,7 @@ def d(f: Callable[P, None], fn: Callable[Concatenate[Callable[P, None], P], None

reveal_type(d(a, f1)) # N: Revealed type is "def (i: builtins.int)"
reveal_type(d(a, f2)) # N: Revealed type is "def (i: builtins.int)"
reveal_type(d(b, f1)) # E: Cannot infer type argument 1 of "d" \
reveal_type(d(b, f1)) # E: Cannot infer value of type parameter "P" of "d" \
# N: Revealed type is "def (*Any, **Any)"
reveal_type(d(b, f2)) # N: Revealed type is "def (builtins.int)"
[builtins fixtures/paramspec.pyi]
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-plugin-attrs.test
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,8 @@ reveal_type(a) # N: Revealed type is "__main__.A[builtins.int]"
reveal_type(a.x) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(a.y) # N: Revealed type is "builtins.int"

A(['str'], 7) # E: Cannot infer type argument 1 of "A"
A([1], '2') # E: Cannot infer type argument 1 of "A"
A(['str'], 7) # E: Cannot infer value of type parameter "T" of "A"
A([1], '2') # E: Cannot infer value of type parameter "T" of "A"

[builtins fixtures/list.pyi]

Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-protocols.test
Original file line number Diff line number Diff line change
Expand Up @@ -4217,10 +4217,10 @@ def g2(a: Input[bytes], b: Output[bytes]) -> None:
f(a, b)

def g3(a: Input[str], b: Output[bytes]) -> None:
f(a, b) # E: Cannot infer type argument 1 of "f"
f(a, b) # E: Cannot infer value of type parameter "AnyStr" of "f"

def g4(a: Input[bytes], b: Output[str]) -> None:
f(a, b) # E: Cannot infer type argument 1 of "f"
f(a, b) # E: Cannot infer value of type parameter "AnyStr" of "f"

[builtins fixtures/tuple.pyi]

Expand Down
8 changes: 4 additions & 4 deletions test-data/unit/check-typevar-tuple.test
Original file line number Diff line number Diff line change
Expand Up @@ -2372,19 +2372,19 @@ def pointwise_multiply(x: Array[Unpack[Ts]], y: Array[Unpack[Ts]]) -> Array[Unpa

def a1(x: Array[int], y: Array[str], z: Array[int, str]) -> None:
reveal_type(pointwise_multiply(x, x)) # N: Revealed type is "__main__.Array[builtins.int]"
reveal_type(pointwise_multiply(x, y)) # E: Cannot infer type argument 1 of "pointwise_multiply" \
reveal_type(pointwise_multiply(x, y)) # E: Cannot infer value of type parameter "Ts" of "pointwise_multiply" \
# N: Revealed type is "__main__.Array[Unpack[builtins.tuple[Any, ...]]]"
reveal_type(pointwise_multiply(x, z)) # E: Cannot infer type argument 1 of "pointwise_multiply" \
reveal_type(pointwise_multiply(x, z)) # E: Cannot infer value of type parameter "Ts" of "pointwise_multiply" \
# N: Revealed type is "__main__.Array[Unpack[builtins.tuple[Any, ...]]]"

def func(x: Array[Unpack[Ts]], *args: Unpack[Ts]) -> Tuple[Unpack[Ts]]:
...

def a2(x: Array[int, str]) -> None:
reveal_type(func(x, 2, "Hello")) # N: Revealed type is "tuple[builtins.int, builtins.str]"
reveal_type(func(x, 2)) # E: Cannot infer type argument 1 of "func" \
reveal_type(func(x, 2)) # E: Cannot infer value of type parameter "Ts" of "func" \
# N: Revealed type is "builtins.tuple[Any, ...]"
reveal_type(func(x, 2, "Hello", True)) # E: Cannot infer type argument 1 of "func" \
reveal_type(func(x, 2, "Hello", True)) # E: Cannot infer value of type parameter "Ts" of "func" \
# N: Revealed type is "builtins.tuple[Any, ...]"
[builtins fixtures/tuple.pyi]

Expand Down