mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[ty] Homogeneous and mixed tuples (#18600)
Some checks are pending
CI / cargo fuzz build (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
Some checks are pending
CI / cargo fuzz build (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
We already had support for homogeneous tuples (`tuple[int, ...]`). This PR extends this to also support mixed tuples (`tuple[str, str, *tuple[int, ...], str str]`). A mixed tuple consists of a fixed-length (possibly empty) prefix and suffix, and a variable-length portion in the middle. Every element of the variable-length portion must be of the same type. A homogeneous tuple is then just a mixed tuple with an empty prefix and suffix. The new data representation uses different Rust types for a fixed-length (aka heterogeneous) tuple. Another option would have been to use the `VariableLengthTuple` representation for all tuples, and to wrap the "variable + suffix" portion in an `Option`. I don't think that would simplify the method implementations much, though, since we would still have a 2×2 case analysis for most of them. One wrinkle is that the definition of the `tuple` class in the typeshed has a single typevar, and canonically represents a homogeneous tuple. When getting the class of a tuple instance, that means that we have to summarize our detailed mixed tuple type information into its "homogeneous supertype". (We were already doing this for heterogeneous types.) A similar thing happens when concatenating two mixed tuples: the variable-length portion and suffix of the LHS, and the prefix and variable-length portion of the RHS, all get unioned into the variable-length portion of the result. The LHS prefix and RHS suffix carry through unchanged. --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
d9266284df
commit
ea812d0813
32 changed files with 2432 additions and 758 deletions
|
@ -17,6 +17,32 @@ def _(x: tuple[int, str], y: tuple[None, tuple[int]]):
|
|||
|
||||
```py
|
||||
def _(x: tuple[int, ...], y: tuple[str, ...]):
|
||||
reveal_type(x + x) # revealed: tuple[int, ...]
|
||||
reveal_type(x + y) # revealed: tuple[int | str, ...]
|
||||
reveal_type(x + (1, 2)) # revealed: tuple[int, ...]
|
||||
reveal_type((1, 2) + x) # revealed: tuple[Literal[1], Literal[2], *tuple[int, ...]]
|
||||
reveal_type(x + (3, 4)) # revealed: tuple[*tuple[int, ...], Literal[3], Literal[4]]
|
||||
reveal_type((1, 2) + x + (3, 4)) # revealed: tuple[Literal[1], Literal[2], *tuple[int, ...], Literal[3], Literal[4]]
|
||||
reveal_type((1, 2) + y + (3, 4) + x) # revealed: tuple[Literal[1], Literal[2], *tuple[int | str, ...]]
|
||||
```
|
||||
|
||||
We get the same results even when we use a legacy type alias, even though this involves first
|
||||
inferring the `tuple[...]` expression as a value form. (Doing so gives a generic alias of the
|
||||
`tuple` type, but as a special case, we include the full detailed tuple element specification in
|
||||
specializations of `tuple`.)
|
||||
|
||||
```py
|
||||
from typing import Literal
|
||||
|
||||
OneTwo = tuple[Literal[1], Literal[2]]
|
||||
ThreeFour = tuple[Literal[3], Literal[4]]
|
||||
IntTuple = tuple[int, ...]
|
||||
StrTuple = tuple[str, ...]
|
||||
|
||||
def _(one_two: OneTwo, x: IntTuple, y: StrTuple, three_four: ThreeFour):
|
||||
reveal_type(x + x) # revealed: tuple[int, ...]
|
||||
reveal_type(x + y) # revealed: tuple[int | str, ...]
|
||||
reveal_type(one_two + x) # revealed: tuple[Literal[1], Literal[2], *tuple[int, ...]]
|
||||
reveal_type(x + three_four) # revealed: tuple[*tuple[int, ...], Literal[3], Literal[4]]
|
||||
reveal_type(one_two + x + three_four) # revealed: tuple[Literal[1], Literal[2], *tuple[int, ...], Literal[3], Literal[4]]
|
||||
reveal_type(one_two + y + three_four + x) # revealed: tuple[Literal[1], Literal[2], *tuple[int | str, ...]]
|
||||
```
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue