[red-knot] Fixes to Type::to_meta_type (#14942)

This commit is contained in:
Alex Waygood 2024-12-12 19:55:11 +00:00 committed by GitHub
parent d2712c7669
commit dbc191d2d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 65 additions and 18 deletions

View file

@ -1844,23 +1844,22 @@ impl<'db> Type<'db> {
Type::ModuleLiteral(_) => KnownClass::ModuleType.to_class_literal(db),
Type::Tuple(_) => KnownClass::Tuple.to_class_literal(db),
Type::ClassLiteral(ClassLiteralType { class }) => class.metaclass(db),
Type::SubclassOf(SubclassOfType {
base: ClassBase::Class(class),
}) => Type::subclass_of(
class
.try_metaclass(db)
.ok()
.and_then(Type::into_class_literal)
.unwrap_or_else(|| KnownClass::Type.to_class_literal(db).expect_class_literal())
.class,
),
Type::SubclassOf(_) => Type::Any,
Type::SubclassOf(SubclassOfType { base }) => match base {
ClassBase::Any | ClassBase::Unknown | ClassBase::Todo(_) => *self,
ClassBase::Class(class) => Type::subclass_of_base(
ClassBase::try_from_ty(db, class.metaclass(db)).unwrap_or(ClassBase::Unknown),
),
},
Type::StringLiteral(_) | Type::LiteralString => KnownClass::Str.to_class_literal(db),
Type::Any => Type::Any,
Type::Unknown => Type::Unknown,
Type::Any => Type::subclass_of_base(ClassBase::Any),
Type::Unknown => Type::subclass_of_base(ClassBase::Unknown),
// TODO intersections
Type::Intersection(_) => todo_type!(),
todo @ Type::Todo(_) => *todo,
Type::Intersection(_) => Type::subclass_of_base(
ClassBase::try_from_ty(db, todo_type!("Intersection meta-type"))
.expect("Type::Todo should be a valid ClassBase"),
),
Type::Todo(todo) => Type::subclass_of_base(ClassBase::Todo(*todo)),
}
}

View file

@ -334,7 +334,7 @@ impl<'db> ClassBase<'db> {
/// Attempt to resolve `ty` into a `ClassBase`.
///
/// Return `None` if `ty` is not an acceptable type for a class base.
fn try_from_ty(db: &'db dyn Db, ty: Type<'db>) -> Option<Self> {
pub(super) fn try_from_ty(db: &'db dyn Db, ty: Type<'db>) -> Option<Self> {
match ty {
Type::Any => Some(Self::Any),
Type::Unknown => Some(Self::Unknown),
@ -449,6 +449,12 @@ impl<'db> From<ClassBase<'db>> for Type<'db> {
}
}
impl<'db> From<&ClassBase<'db>> for Type<'db> {
fn from(value: &ClassBase<'db>) -> Self {
Self::from(*value)
}
}
/// Implementation of the [C3-merge algorithm] for calculating a Python class's
/// [method resolution order].
///