Skip to content

Treat provably empty slices of variadic tuples as empty - #22211

Open
hsusul wants to merge 1 commit into
python:masterfrom
hsusul:fix-variadic-tuple-empty-slice
Open

hsusul wants to merge 1 commit into
python:masterfrom
hsusul:fix-variadic-tuple-empty-slice

Conversation

@hsusul

@hsusul hsusul commented Oct 15, 2026

Copy link
Copy Markdown

Slicing a variadic tuple where start and stop count from the same end and start >= stop gives an empty tuple at runtime, whatever the tuple's length. mypy reports an error instead:

from typing import TypeVarTuple

Ts = TypeVarTuple("Ts")

def f(x: tuple[int, *Ts, str], y: tuple[int, *tuple[str, ...]]) -> None:
    reveal_type(x[2:1])  # error: Ambiguous slice of a variadic tuple; Revealed type is "Any"
    reveal_type(y[5:2])  # same
    reveal_type(x[-1:-2])  # same

TupleType.slice only covers a few prefix/suffix layouts for variadic tuples. When begin is past the unpack, it falls through to the return None branch, and the caller reports the ambiguous-slice error. Fixed tuples don't have this problem because they just use Python's own slicing.

If begin and end are both non-negative or both negative, then begin >= end (step positive or omitted) or begin <= end (step negative) means the slice is empty for every possible length, because Python clamps both bounds the same way. The fix handles that case first and returns tuple[()]. All other cases behave as before; the test checks that y[1:5] and y[-2:-5:-1] still report the ambiguous-slice error.

Test: testVariadicTupleEmptySlice in check-typevar-tuple.test. It fails on master.

Slicing a variadic tuple with literal start and stop on the same side
(both non-negative or both negative) where start >= stop (or start <= stop
with a negative step) always gives an empty tuple, whatever the tuple's
length. TupleType.slice didn't handle this when the start fell after the
unpack, so mypy reported "Ambiguous slice of a variadic tuple" and
inferred Any. Return tuple[()] in that case instead.
@github-actions

Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

scipy-stubs (https://github.com/scipy/scipy-stubs)
+ tests/misc/test_submodules_empty.pyi:3: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant