@@ -173,6 +173,11 @@ def _(d: Any):
173173
174174## Narrowing
175175
176+ ``` toml
177+ [environment ]
178+ python-version = " 3.12"
179+ ```
180+
176181``` py
177182from typing import Any
178183from 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