Skip to content

Commit 62bcae2

Browse files
ilevkivskyiJukkaL
authored andcommitted
Fix handling of tuple type context with unpacks (#16444)
Fixes #16425 Fix is straightforward.
1 parent c22294a commit 62bcae2

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

mypy/checkexpr.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4902,7 +4902,7 @@ def tuple_context_matches(self, expr: TupleExpr, ctx: TupleType) -> bool:
49024902
return len([e for e in expr.items if not isinstance(e, StarExpr)]) <= len(ctx.items)
49034903
# For variadic context, the only easy case is when structure matches exactly.
49044904
# TODO: try using tuple type context in more cases.
4905-
if len([e for e in expr.items if not isinstance(e, StarExpr)]) != 1:
4905+
if len([e for e in expr.items if isinstance(e, StarExpr)]) != 1:
49064906
return False
49074907
expr_star_index = next(i for i, lv in enumerate(expr.items) if isinstance(lv, StarExpr))
49084908
return len(expr.items) == len(ctx.items) and ctx_unpack_index == expr_star_index
@@ -4941,6 +4941,9 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type:
49414941
if type_context_items is not None:
49424942
unpack_in_context = find_unpack_in_list(type_context_items) is not None
49434943
seen_unpack_in_items = False
4944+
allow_precise_tuples = (
4945+
unpack_in_context or PRECISE_TUPLE_TYPES in self.chk.options.enable_incomplete_feature
4946+
)
49444947

49454948
# Infer item types. Give up if there's a star expression
49464949
# that's not a Tuple.
@@ -4981,10 +4984,7 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type:
49814984
# result in an error later, just do something predictable here.
49824985
j += len(tt.items)
49834986
else:
4984-
if (
4985-
PRECISE_TUPLE_TYPES in self.chk.options.enable_incomplete_feature
4986-
and not seen_unpack_in_items
4987-
):
4987+
if allow_precise_tuples and not seen_unpack_in_items:
49884988
# Handle (x, *y, z), where y is e.g. tuple[Y, ...].
49894989
if isinstance(tt, Instance) and self.chk.type_is_iterable(tt):
49904990
item_type = self.chk.iterable_item_type(tt, e)

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,3 +2225,13 @@ bar(*keys, 1) # OK
22252225
reveal_type(baz(keys, 1)) # N: Revealed type is "builtins.object"
22262226
reveal_type(baz(*keys, 1)) # N: Revealed type is "builtins.int"
22272227
[builtins fixtures/tuple.pyi]
2228+
2229+
[case testVariadicTupleContextNoCrash]
2230+
from typing import Tuple, Unpack
2231+
2232+
x: Tuple[int, Unpack[Tuple[int, ...]]] = () # E: Incompatible types in assignment (expression has type "Tuple[()]", variable has type "Tuple[int, Unpack[Tuple[int, ...]]]")
2233+
y: Tuple[int, Unpack[Tuple[int, ...]]] = (1, 2)
2234+
z: Tuple[int, Unpack[Tuple[int, ...]]] = (1,)
2235+
w: Tuple[int, Unpack[Tuple[int, ...]]] = (1, *[2, 3, 4])
2236+
t: Tuple[int, Unpack[Tuple[int, ...]]] = (1, *(2, 3, 4))
2237+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)