[ty] Make TypeIs invariant in its type argument (#20428)

## Summary

What it says on the tin. See the [typing
spec](https://docs.python.org/3/library/typing.html#typing.TypeIs) for
justification.

## Test Plan

Add more tests to PEP 695 `variance.md` suite.
This commit is contained in:
Eric Mark Martin 2025-09-18 10:53:13 -04:00 committed by GitHub
parent 144373fb3c
commit 2502ff7638
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 1 deletions

View file

@ -752,6 +752,36 @@ b_container = ClassContainer[B](B)
a_instance: A = use_a_class_container(b_container) # This should work
```
## TypeIs
```toml
[environment]
python-version = "3.13"
```
`TypeIs[T]` is invariant in `T`. See the [typing spec][typeis-spec] for a justification.
```py
from typing import TypeIs
from ty_extensions import is_assignable_to, is_subtype_of, static_assert
class A:
pass
class B(A):
pass
class C[T]:
def check(x: object) -> TypeIs[T]:
# this is a bad check, but we only care about it type-checking
return False
static_assert(not is_subtype_of(C[B], C[A]))
static_assert(not is_subtype_of(C[A], C[B]))
static_assert(not is_assignable_to(C[B], C[A]))
static_assert(not is_assignable_to(C[A], C[B]))
```
## Inheriting from generic classes with inferred variance
When inheriting from a generic class with our type variable substituted in, we count its occurrences
@ -837,3 +867,4 @@ static_assert(is_subtype_of(DerivedContravariant[A], DerivedContravariant[B]))
[linear-time-variance-talk]: https://www.youtube.com/watch?v=7uixlNTOY4s&t=9705s
[spec]: https://typing.python.org/en/latest/spec/generics.html#variance
[typeis-spec]: https://typing.python.org/en/latest/spec/narrowing.html#typeis