[ty] don't eagerly unpack aliases in user-authored unions (#20055)
Some checks are pending
CI / mkdocs (push) Waiting to run
CI / test ruff-lsp (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 / formatter instabilities and black similarity (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (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 / 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

## Summary

Add a subtly different test case for recursive PEP 695 type aliases,
which does require that we relax our union simplification, so we don't
eagerly unpack aliases from user-provided union annotations.

## Test Plan

Added mdtest.
This commit is contained in:
Carl Meyer 2025-08-26 16:29:45 -07:00 committed by GitHub
parent a60fb3f2c8
commit 9ab276b345
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 197 additions and 57 deletions

View file

@ -204,13 +204,17 @@ def f(x: OptNestedInt) -> None:
### Invalid self-referential
```py
# TODO emit a diagnostic here
# TODO emit a diagnostic on these two lines
type IntOr = int | IntOr
type OrInt = OrInt | int
def f(x: IntOr):
def f(x: IntOr, y: OrInt):
reveal_type(x) # revealed: int
reveal_type(y) # revealed: int
if not isinstance(x, int):
reveal_type(x) # revealed: Never
if not isinstance(y, int):
reveal_type(y) # revealed: Never
```
### Mutually recursive
@ -234,3 +238,42 @@ from ty_extensions import Intersection
def h(x: Intersection[A, B]):
reveal_type(x) # revealed: tuple[B] | None
```
### Union inside generic
#### With old-style union
```py
from typing import Union
type A = list[Union["A", str]]
def f(x: A):
reveal_type(x) # revealed: list[A | str]
for item in x:
reveal_type(item) # revealed: list[A | str] | str
```
#### With new-style union
```py
type A = list["A" | str]
def f(x: A):
reveal_type(x) # revealed: list[A | str]
for item in x:
reveal_type(item) # revealed: list[A | str] | str
```
#### With Optional
```py
from typing import Optional, Union
type A = list[Optional[Union["A", str]]]
def f(x: A):
reveal_type(x) # revealed: list[A | str | None]
for item in x:
reveal_type(item) # revealed: list[A | str | None] | str | None
```