Skip to content
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
28 changes: 17 additions & 11 deletions mypy/expandtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,18 +307,24 @@ def interpolate_args_for_unpack(self, t: CallableType, var_arg: UnpackType) -> l
suffix = self.expand_types(t.arg_types[star_index + 1 :])

var_arg_type = get_proper_type(var_arg.type)
# We have something like Unpack[Tuple[Unpack[Ts], X1, X2]]
if isinstance(var_arg_type, TupleType):
expanded_tuple = var_arg_type.accept(self)
assert isinstance(expanded_tuple, ProperType) and isinstance(expanded_tuple, TupleType)
expanded_items = expanded_tuple.items
fallback = var_arg_type.partial_fallback
if isinstance(var_arg_type, Instance):
# we have something like Unpack[Tuple[Any, ...]]
new_unpack = var_arg
else:
# We have plain Unpack[Ts]
assert isinstance(var_arg_type, TypeVarTupleType)
fallback = var_arg_type.tuple_fallback
expanded_items = self.expand_unpack(var_arg)
new_unpack = UnpackType(TupleType(expanded_items, fallback))
if isinstance(var_arg_type, TupleType):
# We have something like Unpack[Tuple[Unpack[Ts], X1, X2]]
expanded_tuple = var_arg_type.accept(self)
assert isinstance(expanded_tuple, ProperType) and isinstance(
expanded_tuple, TupleType
)
expanded_items = expanded_tuple.items
fallback = var_arg_type.partial_fallback
else:
# We have plain Unpack[Ts]
assert isinstance(var_arg_type, TypeVarTupleType), type(var_arg_type)
fallback = var_arg_type.tuple_fallback
expanded_items = self.expand_unpack(var_arg)
new_unpack = UnpackType(TupleType(expanded_items, fallback))
return prefix + [new_unpack] + suffix

def visit_callable_type(self, t: CallableType) -> CallableType:
Expand Down
42 changes: 42 additions & 0 deletions test-data/unit/check-typevar-tuple.test
Original file line number Diff line number Diff line change
Expand Up @@ -2235,3 +2235,45 @@ z: Tuple[int, Unpack[Tuple[int, ...]]] = (1,)
w: Tuple[int, Unpack[Tuple[int, ...]]] = (1, *[2, 3, 4])
t: Tuple[int, Unpack[Tuple[int, ...]]] = (1, *(2, 3, 4))
[builtins fixtures/tuple.pyi]

[case testAliasToCallableWithUnpack]
from typing import Any, Callable, Tuple, Unpack

_CallableValue = Callable[[Unpack[Tuple[Any, ...]]], Any]
def higher_order(f: _CallableValue) -> None: ...

def good1(*args: int) -> None: ...
def good2(*args: str) -> int: ...

def bad1(a: str, b: int, /) -> None: ...
def bad2(c: bytes, *args: int) -> str: ...
def bad3(*, d: str) -> int: ...
def bad4(**kwargs: None) -> None: ...

higher_order(good1)
higher_order(good2)

higher_order(bad1) # E: Argument 1 to "higher_order" has incompatible type "Callable[[str, int], None]"; expected "Callable[[VarArg(Any)], Any]"
higher_order(bad2) # E: Argument 1 to "higher_order" has incompatible type "Callable[[bytes, VarArg(int)], str]"; expected "Callable[[VarArg(Any)], Any]"
higher_order(bad3) # E: Argument 1 to "higher_order" has incompatible type "Callable[[NamedArg(str, 'd')], int]"; expected "Callable[[VarArg(Any)], Any]"
higher_order(bad4) # E: Argument 1 to "higher_order" has incompatible type "Callable[[KwArg(None)], None]"; expected "Callable[[VarArg(Any)], Any]"
[builtins fixtures/tuple.pyi]

[case testAliasToCallableWithUnpack2]
from typing import Any, Callable, Tuple, Unpack

_CallableValue = Callable[[int, str, Unpack[Tuple[Any, ...]], int], Any]
def higher_order(f: _CallableValue) -> None: ...

def good(a: int, b: str, *args: Unpack[Tuple[Unpack[Tuple[Any, ...]], int]]) -> int: ...
def bad1(a: str, b: int, /) -> None: ...
def bad2(c: bytes, *args: int) -> str: ...
def bad3(*, d: str) -> int: ...
def bad4(**kwargs: None) -> None: ...

higher_order(good)
higher_order(bad1) # E: Argument 1 to "higher_order" has incompatible type "Callable[[str, int], None]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]"
higher_order(bad2) # E: Argument 1 to "higher_order" has incompatible type "Callable[[bytes, VarArg(int)], str]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]"
higher_order(bad3) # E: Argument 1 to "higher_order" has incompatible type "Callable[[NamedArg(str, 'd')], int]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]"
higher_order(bad4) # E: Argument 1 to "higher_order" has incompatible type "Callable[[KwArg(None)], None]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]"
[builtins fixtures/tuple.pyi]