Skip to content

Commit 64d3d04

Browse files
tdsmithhauntsaninja
authored andcommitted
Allow unpacking from TypeVars with iterable bounds (python#13425)
* Allow unpacking from TypeVars by resolving bounds TypeVars aren't iterable, but their bounds might be! Resolve a TypeVar to its bounds before trying to decide how to unpack one of its instances. Fixes python#13402.
1 parent e43dbb9 commit 64d3d04

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

mypy/checker.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3173,6 +3173,9 @@ def check_multi_assignment(
31733173
# TODO: maybe elsewhere; redundant.
31743174
rvalue_type = get_proper_type(rv_type or self.expr_checker.accept(rvalue))
31753175

3176+
if isinstance(rvalue_type, TypeVarType):
3177+
rvalue_type = get_proper_type(rvalue_type.upper_bound)
3178+
31763179
if isinstance(rvalue_type, UnionType):
31773180
# If this is an Optional type in non-strict Optional code, unwrap it.
31783181
relevant_items = rvalue_type.relevant_items()

test-data/unit/check-bound.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,13 @@ if int():
215215
b = 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
216216
twice(a) # E: Value of type variable "T" of "twice" cannot be "int"
217217
[builtins fixtures/args.pyi]
218+
219+
220+
[case testIterableBoundUnpacking]
221+
from typing import Tuple, TypeVar
222+
TupleT = TypeVar("TupleT", bound=Tuple[int, ...])
223+
def f(t: TupleT) -> None:
224+
a, *b = t
225+
reveal_type(a) # N: Revealed type is "builtins.int"
226+
reveal_type(b) # N: Revealed type is "builtins.list[builtins.int]"
227+
[builtins fixtures/tuple.pyi]

test-data/unit/check-typevar-unbound.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,9 @@ def h(a: List[Union[Callable[..., T]]]) -> T:
5858
def j(a: List[Union[Callable[..., Tuple[T, T]], int]]) -> T:
5959
...
6060
[builtins fixtures/tuple.pyi]
61+
62+
[case testUnboundedTypevarUnpacking]
63+
from typing import TypeVar
64+
T = TypeVar("T")
65+
def f(t: T) -> None:
66+
a, *b = t # E: "object" object is not iterable

0 commit comments

Comments
 (0)