Skip to content

Commit 55df927

Browse files
authored
[ty] Understand homogeneous tuple annotations (#17998)
1 parent f301931 commit 55df927

File tree

17 files changed

+196
-104
lines changed

17 files changed

+196
-104
lines changed

crates/ty_python_semantic/resources/mdtest/annotations/starred.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ from typing_extensions import TypeVarTuple
1313
Ts = TypeVarTuple("Ts")
1414

1515
def append_int(*args: *Ts) -> tuple[*Ts, int]:
16-
# TODO: tuple[*Ts]
17-
reveal_type(args) # revealed: tuple[Unknown, ...]
16+
reveal_type(args) # revealed: @Todo(PEP 646)
1817

1918
return (*args, 1)
2019

2120
# TODO should be tuple[Literal[True], Literal["a"], int]
22-
reveal_type(append_int(True, "a")) # revealed: @Todo(full tuple[...] support)
21+
reveal_type(append_int(True, "a")) # revealed: @Todo(PEP 646)
2322
```

crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_forms.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,13 @@ R_co = TypeVar("R_co", covariant=True)
1515
Alias: TypeAlias = int
1616

1717
def f(*args: Unpack[Ts]) -> tuple[Unpack[Ts]]:
18-
# TODO: should understand the annotation
19-
reveal_type(args) # revealed: tuple[Unknown, ...]
20-
18+
reveal_type(args) # revealed: tuple[@Todo(`Unpack[]` special form), ...]
2119
reveal_type(Alias) # revealed: @Todo(Support for `typing.TypeAlias`)
2220

2321
def g() -> TypeGuard[int]: ...
2422
def h() -> TypeIs[int]: ...
2523
def i(callback: Callable[Concatenate[int, P], R_co], *args: P.args, **kwargs: P.kwargs) -> R_co:
26-
# TODO: should understand the annotation
27-
reveal_type(args) # revealed: tuple[Unknown, ...]
24+
reveal_type(args) # revealed: tuple[@Todo(Support for `typing.ParamSpec`), ...]
2825
reveal_type(kwargs) # revealed: dict[str, @Todo(Support for `typing.ParamSpec`)]
2926
return callback(42, *args, **kwargs)
3027

crates/ty_python_semantic/resources/mdtest/assignment/annotations.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,12 @@ reveal_type(a) # revealed: tuple[()]
5656
reveal_type(b) # revealed: tuple[int]
5757
reveal_type(c) # revealed: tuple[str, int]
5858
reveal_type(d) # revealed: tuple[tuple[str, str], tuple[int, int]]
59+
reveal_type(e) # revealed: tuple[str, ...]
5960

60-
# TODO: homogeneous tuples, PEP-646 tuples, generics
61-
reveal_type(e) # revealed: @Todo(full tuple[...] support)
62-
reveal_type(f) # revealed: @Todo(full tuple[...] support)
63-
reveal_type(g) # revealed: @Todo(full tuple[...] support)
64-
reveal_type(h) # revealed: tuple[list[int], list[int]]
61+
reveal_type(f) # revealed: @Todo(PEP 646)
62+
reveal_type(g) # revealed: @Todo(PEP 646)
6563

64+
reveal_type(h) # revealed: tuple[list[int], list[int]]
6665
reveal_type(i) # revealed: tuple[str | int, str | int]
6766
reveal_type(j) # revealed: tuple[str | int]
6867
```

crates/ty_python_semantic/resources/mdtest/attributes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ functions are instances of that class:
16761676
```py
16771677
def f(): ...
16781678

1679-
reveal_type(f.__defaults__) # revealed: @Todo(full tuple[...] support) | None
1679+
reveal_type(f.__defaults__) # revealed: tuple[Any, ...] | None
16801680
reveal_type(f.__kwdefaults__) # revealed: dict[str, Any] | None
16811681
```
16821682

@@ -1730,7 +1730,7 @@ All attribute access on literal `bytes` types is currently delegated to `builtin
17301730
```py
17311731
# revealed: bound method Literal[b"foo"].join(iterable_of_bytes: Iterable[@Todo(Support for `typing.TypeAlias`)], /) -> bytes
17321732
reveal_type(b"foo".join)
1733-
# revealed: bound method Literal[b"foo"].endswith(suffix: @Todo(Support for `typing.TypeAlias`), start: SupportsIndex | None = ellipsis, end: SupportsIndex | None = ellipsis, /) -> bool
1733+
# revealed: bound method Literal[b"foo"].endswith(suffix: @Todo(Support for `typing.TypeAlias`) | tuple[@Todo(Support for `typing.TypeAlias`), ...], start: SupportsIndex | None = ellipsis, end: SupportsIndex | None = ellipsis, /) -> bool
17341734
reveal_type(b"foo".endswith)
17351735
```
17361736

crates/ty_python_semantic/resources/mdtest/binary/instances.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,7 @@ reveal_type(A() + b"foo") # revealed: A
317317
reveal_type(b"foo" + A()) # revealed: bytes
318318

319319
reveal_type(A() + ()) # revealed: A
320-
# TODO this should be `A`, since `tuple.__add__` doesn't support `A` instances
321-
reveal_type(() + A()) # revealed: @Todo(full tuple[...] support)
320+
reveal_type(() + A()) # revealed: A
322321

323322
literal_string_instance = "foo" * 1_000_000_000
324323
# the test is not testing what it's meant to be testing if this isn't a `LiteralString`:

crates/ty_python_semantic/resources/mdtest/binary/tuples.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def _(x: tuple[int, str], y: tuple[None, tuple[int]]):
1717

1818
```py
1919
def _(x: tuple[int, ...], y: tuple[str, ...]):
20-
reveal_type(x + y) # revealed: @Todo(full tuple[...] support)
21-
reveal_type(x + (1, 2)) # revealed: @Todo(full tuple[...] support)
20+
# TODO: should be `tuple[int | str, ...]`
21+
reveal_type(x + y) # revealed: tuple[int | Unknown, ...]
22+
reveal_type(x + (1, 2)) # revealed: tuple[int, ...]
2223
```

crates/ty_python_semantic/resources/mdtest/call/builtins.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type(b"Foo", (), {})
5454
# error: [no-matching-overload] "No overload of class `type` matches arguments"
5555
type("Foo", Base, {})
5656

57-
# TODO: this should be an error
57+
# error: [no-matching-overload] "No overload of class `type` matches arguments"
5858
type("Foo", (1, 2), {})
5959

6060
# TODO: this should be an error

crates/ty_python_semantic/resources/mdtest/exception/basic.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ def foo(
4545
x: type[AttributeError],
4646
y: tuple[type[OSError], type[RuntimeError]],
4747
z: tuple[type[BaseException], ...],
48+
zz: tuple[type[TypeError | RuntimeError], ...],
49+
zzz: type[BaseException] | tuple[type[BaseException], ...],
4850
):
4951
try:
5052
help()
@@ -53,8 +55,11 @@ def foo(
5355
except y as f:
5456
reveal_type(f) # revealed: OSError | RuntimeError
5557
except z as g:
56-
# TODO: should be `BaseException`
57-
reveal_type(g) # revealed: @Todo(full tuple[...] support)
58+
reveal_type(g) # revealed: BaseException
59+
except zz as h:
60+
reveal_type(h) # revealed: TypeError | RuntimeError
61+
except zzz as i:
62+
reveal_type(i) # revealed: BaseException
5863
```
5964

6065
## Invalid exception handlers
@@ -86,9 +91,9 @@ def foo(
8691
# error: [invalid-exception-caught]
8792
except y as f:
8893
reveal_type(f) # revealed: OSError | RuntimeError | Unknown
94+
# error: [invalid-exception-caught]
8995
except z as g:
90-
# TODO: should emit a diagnostic here:
91-
reveal_type(g) # revealed: @Todo(full tuple[...] support)
96+
reveal_type(g) # revealed: Unknown
9297
```
9398

9499
## Object raised is not an exception

crates/ty_python_semantic/resources/mdtest/function/parameters.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ def f(a, b: int, c=1, d: int = 2, /, e=3, f: Literal[4] = 4, *args: object, g=5,
2525
reveal_type(f) # revealed: Literal[4]
2626
reveal_type(g) # revealed: Unknown | Literal[5]
2727
reveal_type(h) # revealed: Literal[6]
28-
# TODO: should be `tuple[object, ...]`
29-
reveal_type(args) # revealed: tuple[Unknown, ...]
28+
reveal_type(args) # revealed: tuple[object, ...]
3029
reveal_type(kwargs) # revealed: dict[str, str]
3130
```
3231

crates/ty_python_semantic/resources/mdtest/pep695_type_aliases.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,7 @@ y: MyIntOrStr = None
6868

6969
```py
7070
type ListOrSet[T] = list[T] | set[T]
71-
72-
# TODO: Should be `tuple[typing.TypeVar | typing.ParamSpec | typing.TypeVarTuple, ...]`,
73-
# as specified in the `typeshed` stubs.
74-
reveal_type(ListOrSet.__type_params__) # revealed: @Todo(full tuple[...] support)
71+
reveal_type(ListOrSet.__type_params__) # revealed: tuple[TypeVar | ParamSpec | TypeVarTuple, ...]
7572
```
7673

7774
## `TypeAliasType` properties

0 commit comments

Comments
 (0)