Skip to content

Commit 668733d

Browse files
authored
Correctly handle empty tuple index when unpacked (#21545)
Fixes #18390 Closes #18395 This is a more targeted fix than the original PR. Note we don't need to worry about other places with `flatten_nested_tuples()`, since the issue is only specific to (early) `UnboundType`.
1 parent 965dd31 commit 668733d

3 files changed

Lines changed: 70 additions & 0 deletions

File tree

‎mypy/typeanal.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,10 @@ def analyze_type_with_type_info(
884884
return AnyType(TypeOfAny.from_error)
885885

886886
# Check type argument count.
887+
old_args = instance.args
887888
instance.args = tuple(flatten_nested_tuples(instance.args))
889+
if old_args and not instance.args:
890+
empty_tuple_index = True
888891
if not (self.defining_alias and self.nesting_level == 0) and not validate_instance(
889892
instance, self.fail, empty_tuple_index
890893
):
@@ -2192,7 +2195,10 @@ def instantiate_type_alias(
21922195
# Type aliases are special, since they can be expanded during semantic analysis,
21932196
# so we need to normalize them as soon as possible.
21942197
# TODO: can this cause an infinite recursion?
2198+
old_args = args
21952199
args = flatten_nested_tuples(args)
2200+
if old_args and not args:
2201+
empty_tuple_index = True
21962202
if any(unknown_unpack(a) for a in args):
21972203
# This type is not ready to be validated, because of unknown total count.
21982204
# Note that we keep the kind of Any for consistency.

‎test-data/unit/check-python313.test‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,3 +451,32 @@ reveal_type(a) # N: Revealed type is "builtins.list[builtins.list[Any]]"
451451
type A[T = A] = int
452452
a: A
453453
reveal_type(a) # N: Revealed type is "builtins.int"
454+
455+
[case testPEP695VariadicGenericClassEmptyTupleUnpackIndex]
456+
class Blah[*Ts]:
457+
pass
458+
459+
x: Blah[()]
460+
y: Blah[*tuple[()]]
461+
462+
type Empty = tuple[()]
463+
z: Blah[*Empty]
464+
465+
reveal_type(x) # N: Revealed type is "__main__.Blah[()]"
466+
reveal_type(y) # N: Revealed type is "__main__.Blah[()]"
467+
reveal_type(z) # N: Revealed type is "__main__.Blah[()]"
468+
[builtins fixtures/tuple.pyi]
469+
470+
[case testPEP695VariadicGenericAliasEmptyTupleUnpackIndex]
471+
type Blah[*Ts] = list[tuple[*Ts]]
472+
473+
x: Blah[()]
474+
y: Blah[*tuple[()]]
475+
476+
type Empty = tuple[()]
477+
z: Blah[*Empty]
478+
479+
reveal_type(x) # N: Revealed type is "builtins.list[tuple[()]]"
480+
reveal_type(y) # N: Revealed type is "builtins.list[tuple[()]]"
481+
reveal_type(z) # N: Revealed type is "builtins.list[tuple[()]]"
482+
[builtins fixtures/tuple.pyi]

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,3 +2838,38 @@ def test(t: tuple[int, ...]) -> None: ...
28382838
test(x)
28392839
test(y)
28402840
[builtins fixtures/tuple.pyi]
2841+
2842+
[case testVariadicGenericClassEmptyTupleUnpackIndex]
2843+
from typing import Generic, TypeVarTuple, Unpack
2844+
2845+
Ts = TypeVarTuple("Ts")
2846+
class Blah(Generic[Unpack[Ts]]):
2847+
pass
2848+
2849+
x: Blah[()]
2850+
y: Blah[Unpack[tuple[()]]]
2851+
2852+
Empty = tuple[()]
2853+
z: Blah[Unpack[Empty]]
2854+
2855+
reveal_type(x) # N: Revealed type is "__main__.Blah[()]"
2856+
reveal_type(y) # N: Revealed type is "__main__.Blah[()]"
2857+
reveal_type(z) # N: Revealed type is "__main__.Blah[()]"
2858+
[builtins fixtures/tuple.pyi]
2859+
2860+
[case testVariadicGenericAliasEmptyTupleUnpackIndex]
2861+
from typing import Generic, TypeVarTuple, Unpack
2862+
2863+
Ts = TypeVarTuple("Ts")
2864+
Blah = list[tuple[Unpack[Ts]]]
2865+
2866+
x: Blah[()]
2867+
y: Blah[Unpack[tuple[()]]]
2868+
2869+
Empty = tuple[()]
2870+
z: Blah[Unpack[Empty]]
2871+
2872+
reveal_type(x) # N: Revealed type is "builtins.list[tuple[()]]"
2873+
reveal_type(y) # N: Revealed type is "builtins.list[tuple[()]]"
2874+
reveal_type(z) # N: Revealed type is "builtins.list[tuple[()]]"
2875+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)