[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

@ -6620,6 +6620,7 @@ impl<'db> VarianceInferable<'db> for Type<'db> {
.map(|ty| ty.variance_of(db, typevar))
.collect(),
Type::SubclassOf(subclass_of_type) => subclass_of_type.variance_of(db, typevar),
Type::TypeIs(type_is_type) => type_is_type.variance_of(db, typevar),
Type::Dynamic(_)
| Type::Never
| Type::WrapperDescriptor(_)
@ -6640,7 +6641,6 @@ impl<'db> VarianceInferable<'db> for Type<'db> {
| Type::BoundSuper(_)
| Type::TypeVar(_)
| Type::NonInferableTypeVar(_)
| Type::TypeIs(_)
| Type::TypedDict(_)
| Type::TypeAlias(_) => TypeVarVariance::Bivariant,
};
@ -10956,6 +10956,16 @@ impl<'db> TypeIsType<'db> {
}
}
impl<'db> VarianceInferable<'db> for TypeIsType<'db> {
// See the [typing spec] on why `TypeIs` is invariant in its type.
// [typing spec]: https://typing.python.org/en/latest/spec/narrowing.html#typeis
fn variance_of(self, db: &'db dyn Db, typevar: BoundTypeVarInstance<'db>) -> TypeVarVariance {
self.return_type(db)
.with_polarity(TypeVarVariance::Invariant)
.variance_of(db, typevar)
}
}
/// Walk the MRO of this class and return the last class just before the specified known base.
/// This can be used to determine upper bounds for `Self` type variables on methods that are
/// being added to the given class.