Skip to content

Commit 99ba048

Browse files
authored
tuple slice should not propagate fallback (#16154)
Fixes #8776
1 parent 3d3e482 commit 99ba048

File tree

4 files changed

+23
-7
lines changed

4 files changed

+23
-7
lines changed

mypy/checkexpr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4271,7 +4271,7 @@ def visit_tuple_slice_helper(self, left_type: TupleType, slic: SliceExpr) -> Typ
42714271

42724272
items: list[Type] = []
42734273
for b, e, s in itertools.product(begin, end, stride):
4274-
item = left_type.slice(b, e, s)
4274+
item = left_type.slice(b, e, s, fallback=self.named_type("builtins.tuple"))
42754275
if item is None:
42764276
self.chk.fail(message_registry.AMBIGUOUS_SLICE_OF_VARIADIC_TUPLE, slic)
42774277
return AnyType(TypeOfAny.from_error)

mypy/types.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,7 +2416,12 @@ def copy_modified(
24162416
items = self.items
24172417
return TupleType(items, fallback, self.line, self.column)
24182418

2419-
def slice(self, begin: int | None, end: int | None, stride: int | None) -> TupleType | None:
2419+
def slice(
2420+
self, begin: int | None, end: int | None, stride: int | None, *, fallback: Instance | None
2421+
) -> TupleType | None:
2422+
if fallback is None:
2423+
fallback = self.partial_fallback
2424+
24202425
if any(isinstance(t, UnpackType) for t in self.items):
24212426
total = len(self.items)
24222427
unpack_index = find_unpack_in_list(self.items)
@@ -2462,7 +2467,7 @@ def slice(self, begin: int | None, end: int | None, stride: int | None) -> Tuple
24622467
return None
24632468
else:
24642469
slice_items = self.items[begin:end:stride]
2465-
return TupleType(slice_items, self.partial_fallback, self.line, self.column, self.implicit)
2470+
return TupleType(slice_items, fallback, self.line, self.column, self.implicit)
24662471

24672472

24682473
class TypedDictType(ProperType):

test-data/unit/check-literal.test

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,8 +1872,9 @@ reveal_type(tup2[idx3]) # N: Revealed type is "__main__.D"
18721872
reveal_type(tup2[idx4]) # N: Revealed type is "__main__.E"
18731873
reveal_type(tup2[idx_neg1]) # N: Revealed type is "__main__.E"
18741874
tup2[idx5] # E: Tuple index out of range
1875-
reveal_type(tup2[idx2:idx4]) # N: Revealed type is "Tuple[__main__.C, __main__.D, fallback=__main__.Tup2Class]"
1876-
reveal_type(tup2[::idx2]) # N: Revealed type is "Tuple[__main__.A, __main__.C, __main__.E, fallback=__main__.Tup2Class]"
1875+
reveal_type(tup2[idx2:idx4]) # N: Revealed type is "Tuple[__main__.C, __main__.D]"
1876+
reveal_type(tup2[::idx2]) # N: Revealed type is "Tuple[__main__.A, __main__.C, __main__.E]"
1877+
tup3: Tup2Class = tup2[:] # E: Incompatible types in assignment (expression has type "Tuple[A, B, C, D, E]", variable has type "Tup2Class")
18771878
[builtins fixtures/slice.pyi]
18781879

18791880
[case testLiteralIntelligentIndexingTypedDict]
@@ -1977,8 +1978,8 @@ reveal_type(tup1[0::idx1]) # N: Revealed type is "Union[Tuple[__main__.A, _
19771978
tup1[idx_bad] # E: Tuple index out of range
19781979

19791980
reveal_type(tup2[idx1]) # N: Revealed type is "Union[__main__.B, __main__.C]"
1980-
reveal_type(tup2[idx1:idx2]) # N: Revealed type is "Union[Tuple[__main__.B, __main__.C, fallback=__main__.Tup2Class], Tuple[__main__.B, __main__.C, __main__.D, fallback=__main__.Tup2Class], Tuple[__main__.C, fallback=__main__.Tup2Class], Tuple[__main__.C, __main__.D, fallback=__main__.Tup2Class]]"
1981-
reveal_type(tup2[0::idx1]) # N: Revealed type is "Union[Tuple[__main__.A, __main__.B, __main__.C, __main__.D, __main__.E, fallback=__main__.Tup2Class], Tuple[__main__.A, __main__.C, __main__.E, fallback=__main__.Tup2Class]]"
1981+
reveal_type(tup2[idx1:idx2]) # N: Revealed type is "Union[Tuple[__main__.B, __main__.C], Tuple[__main__.B, __main__.C, __main__.D], Tuple[__main__.C], Tuple[__main__.C, __main__.D]]"
1982+
reveal_type(tup2[0::idx1]) # N: Revealed type is "Union[Tuple[__main__.A, __main__.B, __main__.C, __main__.D, __main__.E], Tuple[__main__.A, __main__.C, __main__.E]]"
19821983
tup2[idx_bad] # E: Tuple index out of range
19831984
[builtins fixtures/slice.pyi]
19841985
[out]

test-data/unit/check-tuples.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,3 +1681,13 @@ def g(t: Tuple):
16811681
reveal_type(zip(*t)) # N: Revealed type is "typing.Iterator[builtins.tuple[Any, ...]]"
16821682
reveal_type(zip(t)) # N: Revealed type is "typing.Iterator[Tuple[Any]]"
16831683
[builtins fixtures/tuple.pyi]
1684+
1685+
[case testTupleSubclassSlice]
1686+
from typing import Tuple
1687+
1688+
class A: ...
1689+
1690+
class tuple_aa_subclass(Tuple[A, A]): ...
1691+
1692+
inst_tuple_aa_subclass: tuple_aa_subclass = tuple_aa_subclass((A(), A()))[:] # E: Incompatible types in assignment (expression has type "Tuple[A, A]", variable has type "tuple_aa_subclass")
1693+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)