[ty] Add narrowing for isinstance() and issubclass() checks that use PEP-604 unions (#21334)
This commit is contained in:
@@ -11,9 +11,9 @@ use crate::types::enums::{enum_member_literals, enum_metadata};
|
||||
use crate::types::function::KnownFunction;
|
||||
use crate::types::infer::infer_same_file_expression_type;
|
||||
use crate::types::{
|
||||
ClassLiteral, ClassType, IntersectionBuilder, KnownClass, SpecialFormType, SubclassOfInner,
|
||||
SubclassOfType, Truthiness, Type, TypeContext, TypeVarBoundOrConstraints, UnionBuilder,
|
||||
infer_expression_types,
|
||||
ClassLiteral, ClassType, IntersectionBuilder, KnownClass, KnownInstanceType, SpecialFormType,
|
||||
SubclassOfInner, SubclassOfType, Truthiness, Type, TypeContext, TypeVarBoundOrConstraints,
|
||||
UnionBuilder, infer_expression_types,
|
||||
};
|
||||
|
||||
use ruff_db::parsed::{ParsedModuleRef, parsed_module};
|
||||
@@ -212,6 +212,23 @@ impl ClassInfoConstraintFunction {
|
||||
)
|
||||
}),
|
||||
|
||||
Type::KnownInstance(KnownInstanceType::UnionType(elements)) => {
|
||||
UnionType::try_from_elements(
|
||||
db,
|
||||
elements.elements(db).iter().map(|element| {
|
||||
// A special case is made for `None` at runtime
|
||||
// (it's implicitly converted to `NoneType` in `int | None`)
|
||||
// which means that `isinstance(x, int | None)` works even though
|
||||
// `None` is not a class literal.
|
||||
if element.is_none(db) {
|
||||
self.generate_constraint(db, KnownClass::NoneType.to_class_literal(db))
|
||||
} else {
|
||||
self.generate_constraint(db, *element)
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
Type::AlwaysFalsy
|
||||
| Type::AlwaysTruthy
|
||||
| Type::BooleanLiteral(_)
|
||||
|
||||
Reference in New Issue
Block a user