Skip to content

Commit 2e5d7ee

Browse files
authored
Use normalized tuples for fallback calculation (#19111)
Fixes #19105. I haven't checked this with namedtuples magic, nor am I certain that this is the best way.
1 parent d528707 commit 2e5d7ee

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

mypy/semanal_shared.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
TypeVarLikeType,
4747
TypeVarTupleType,
4848
UnpackType,
49+
flatten_nested_tuples,
4950
get_proper_type,
5051
)
5152

@@ -290,7 +291,7 @@ def calculate_tuple_fallback(typ: TupleType) -> None:
290291
fallback = typ.partial_fallback
291292
assert fallback.type.fullname == "builtins.tuple"
292293
items = []
293-
for item in typ.items:
294+
for item in flatten_nested_tuples(typ.items):
294295
# TODO: this duplicates some logic in typeops.tuple_fallback().
295296
if isinstance(item, UnpackType):
296297
unpacked_type = get_proper_type(item.type)

mypy/semanal_typeargs.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ def visit_type_alias_type(self, t: TypeAliasType) -> None:
102102
# If there was already an error for the alias itself, there is no point in checking
103103
# the expansion, most likely it will result in the same kind of error.
104104
get_proper_type(t).accept(self)
105+
if t.alias is not None:
106+
t.alias.accept(self)
105107

106108
def visit_tuple_type(self, t: TupleType) -> None:
107109
t.items = flatten_nested_tuples(t.items)
@@ -254,6 +256,10 @@ def visit_unpack_type(self, typ: UnpackType) -> None:
254256
def check_type_var_values(
255257
self, name: str, actuals: list[Type], arg_name: str, valids: list[Type], context: Context
256258
) -> bool:
259+
if self.in_type_alias_expr:
260+
# See testValidTypeAliasValues - we do not enforce typevar compatibility
261+
# at the definition site. We check instantiation validity later.
262+
return False
257263
is_error = False
258264
for actual in get_proper_types(actuals):
259265
# We skip UnboundType here, since they may appear in defn.bases,

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,3 +2666,30 @@ def identity(smth: _FT) -> _FT:
26662666
class S(tuple[Unpack[Ts]], Generic[T, Unpack[Ts]]):
26672667
def f(self, x: T, /) -> T: ...
26682668
[builtins fixtures/tuple.pyi]
2669+
2670+
[case testNoCrashSubclassingTupleWithTrivialUnpack]
2671+
# https://github.com/python/mypy/issues/19105
2672+
from typing import Unpack
2673+
2674+
class A(tuple[Unpack[tuple[int]]]): ...
2675+
class B(tuple[Unpack[tuple[()]]]): ...
2676+
2677+
a: A
2678+
reveal_type(tuple(a)) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
2679+
(x,) = a
2680+
2681+
b: B
2682+
(_,) = b # E: Need more than 0 values to unpack (1 expected)
2683+
[builtins fixtures/tuple.pyi]
2684+
2685+
[case testNoCrashSubclassingTupleWithVariadicUnpack]
2686+
# https://github.com/python/mypy/issues/19105
2687+
from typing import Unpack
2688+
2689+
class A(tuple[Unpack[tuple[int, ...]]]): ...
2690+
2691+
a: A
2692+
tuple(a)
2693+
(x,) = a
2694+
(_,) = a
2695+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)