Skip to content

Commit ad032c5

Browse files
committed
add a test
1 parent 688bf32 commit ad032c5

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

crates/ty_python_semantic/resources/mdtest/narrow/type_guards.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ def _(d: Any):
173173

174174
## Narrowing
175175

176+
```toml
177+
[environment]
178+
python-version = "3.12"
179+
```
180+
176181
```py
177182
from typing import Any
178183
from typing_extensions import TypeGuard, TypeIs
@@ -295,6 +300,38 @@ def _(a: Foo):
295300
reveal_type(a) # revealed: Foo & Bar
296301
```
297302

303+
For generics, we transform the argument passed into `TypeIs[]` from `X` to `Top[X]`. This helps
304+
especially when using various functions from typeshed that are annotated as returning
305+
`TypeIs[SomeCovariantGeneric[Any]]` to avoid false positives in other type checkers. For ty's
306+
purposes, it would usually lead to more intuitive results if `object` was used as the specialization
307+
for a covariant generic inside the `TypeIs` special form, but this is mitigated by our implicit
308+
transformation from `TypeIs[SomeCovariantGeneric[Any]]` to `TypeIs[Top[SomeCovariantGeneric[Any]]]`
309+
(which just simplifies to `TypeIs[SomeCovariantGeneric[object]]`).
310+
311+
```py
312+
class Unrelated: ...
313+
314+
class Covariant[T]:
315+
def get(self) -> T:
316+
raise NotImplementedError
317+
318+
def is_instance_of_covariant(arg: object) -> TypeIs[Covariant[Any]]:
319+
return isinstance(arg, Covariant)
320+
321+
def needs_instance_of_unrelated(arg: Unrelated):
322+
pass
323+
324+
def _(x: Unrelated | Covariant[int]):
325+
if is_instance_of_covariant(x):
326+
raise RuntimeError("oh no")
327+
328+
reveal_type(x) # revealed: Unrelated & ~Covariant[object]
329+
330+
# We would emit a false-positive diagnostic here if we didn't implicitly transform
331+
# `TypeIs[Covariant[Any]]` to `TypeIs[Covariant[object]]`
332+
needs_instance_of_unrelated(x)
333+
```
334+
298335
## `TypeGuard` special cases
299336

300337
```py

0 commit comments

Comments
 (0)