@@ -134,6 +134,91 @@ def main(a: object) -> None:
134134 reveal_type(a) # N: Revealed type is "Union[builtins.int, builtins.str]"
135135[builtins fixtures/tuple.pyi]
136136
137+ [case testTypeIsUnionWithGeneric]
138+ from typing import Any, List, Sequence, Union
139+ from typing_extensions import TypeIs
140+
141+ def is_int_list(a: object) -> TypeIs[List[int]]: pass
142+ def is_int_seq(a: object) -> TypeIs[Sequence[int]]: pass
143+ def is_seq(a: object) -> TypeIs[Sequence[Any]]: pass
144+
145+ def f1(a: Union[List[int], List[str]]) -> None:
146+ if is_int_list(a):
147+ reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]"
148+ else:
149+ reveal_type(a) # N: Revealed type is "builtins.list[builtins.str]"
150+ reveal_type(a) # N: Revealed type is "Union[builtins.list[builtins.int], builtins.list[builtins.str]]"
151+
152+ def f2(a: Union[List[int], int]) -> None:
153+ if is_int_list(a):
154+ reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]"
155+ else:
156+ reveal_type(a) # N: Revealed type is "builtins.int"
157+ reveal_type(a) # N: Revealed type is "Union[builtins.list[builtins.int], builtins.int]"
158+
159+ def f3(a: Union[List[bool], List[str]]) -> None:
160+ if is_int_seq(a):
161+ reveal_type(a) # N: Revealed type is "builtins.list[builtins.bool]"
162+ else:
163+ reveal_type(a) # N: Revealed type is "builtins.list[builtins.str]"
164+ reveal_type(a) # N: Revealed type is "Union[builtins.list[builtins.bool], builtins.list[builtins.str]]"
165+
166+ def f4(a: Union[List[int], int]) -> None:
167+ if is_seq(a):
168+ reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]"
169+ else:
170+ reveal_type(a) # N: Revealed type is "builtins.int"
171+ reveal_type(a) # N: Revealed type is "Union[builtins.list[builtins.int], builtins.int]"
172+ [builtins fixtures/tuple.pyi]
173+
174+ [case testTypeIsTupleGeneric]
175+ # flags: --warn-unreachable
176+ from __future__ import annotations
177+ from typing_extensions import TypeIs, Unpack
178+
179+ class A: ...
180+ class B: ...
181+
182+ def is_tuple_of_B(v: tuple[A | B, ...]) -> TypeIs[tuple[B, ...]]: ...
183+
184+ def test1(t: tuple[A]) -> None:
185+ if is_tuple_of_B(t):
186+ reveal_type(t) # E: Statement is unreachable
187+ else:
188+ reveal_type(t) # N: Revealed type is "tuple[__main__.A]"
189+
190+ def test2(t: tuple[B, A]) -> None:
191+ if is_tuple_of_B(t):
192+ reveal_type(t) # E: Statement is unreachable
193+ else:
194+ reveal_type(t) # N: Revealed type is "tuple[__main__.B, __main__.A]"
195+
196+ def test3(t: tuple[A | B]) -> None:
197+ if is_tuple_of_B(t):
198+ reveal_type(t) # N: Revealed type is "tuple[__main__.B]"
199+ else:
200+ reveal_type(t) # N: Revealed type is "tuple[Union[__main__.A, __main__.B]]"
201+
202+ def test4(t: tuple[A | B, A | B]) -> None:
203+ if is_tuple_of_B(t):
204+ reveal_type(t) # N: Revealed type is "tuple[__main__.B, __main__.B]"
205+ else:
206+ reveal_type(t) # N: Revealed type is "tuple[Union[__main__.A, __main__.B], Union[__main__.A, __main__.B]]"
207+
208+ def test5(t: tuple[A | B, ...]) -> None:
209+ if is_tuple_of_B(t):
210+ reveal_type(t) # N: Revealed type is "builtins.tuple[__main__.B, ...]"
211+ else:
212+ reveal_type(t) # N: Revealed type is "builtins.tuple[Union[__main__.A, __main__.B], ...]"
213+
214+ def test6(t: tuple[B, Unpack[tuple[A | B, ...]], B]) -> None:
215+ if is_tuple_of_B(t):
216+ # Should this be tuple[B, *tuple[B, ...], B]
217+ reveal_type(t) # N: Revealed type is "tuple[__main__.B, Never, __main__.B]"
218+ else:
219+ reveal_type(t) # N: Revealed type is "tuple[__main__.B, Unpack[builtins.tuple[Union[__main__.A, __main__.B], ...]], __main__.B]"
220+ [builtins fixtures/tuple.pyi]
221+
137222[case testTypeIsNonzeroFloat]
138223from typing_extensions import TypeIs
139224def is_nonzero(a: object) -> TypeIs[float]: pass
@@ -834,3 +919,17 @@ def handle(model: Model) -> None:
834919 if is_model_a(model):
835920 reveal_type(model) # N: Revealed type is "Literal[__main__.Model.A]"
836921[builtins fixtures/tuple.pyi]
922+
923+ [case testTypeIsAwaitableAny]
924+ from __future__ import annotations
925+ from typing import Any, Awaitable, Callable
926+ from typing_extensions import TypeIs
927+
928+ def is_async_callable(obj: Any) -> TypeIs[Callable[..., Awaitable[Any]]]: ...
929+
930+ def main(f: Callable[[], int | Awaitable[int]]) -> None:
931+ if is_async_callable(f):
932+ reveal_type(f) # N: Revealed type is "def (*Any, **Any) -> typing.Awaitable[Any]"
933+ else:
934+ reveal_type(f) # N: Revealed type is "def () -> Union[builtins.int, typing.Awaitable[builtins.int]]"
935+ [builtins fixtures/tuple.pyi]
0 commit comments