[ty] Fix more generics-related TODOs (#18062)

This commit is contained in:
Alex Waygood 2025-05-14 12:26:52 -04:00 committed by GitHub
parent 8104b1e83b
commit 0590b38214
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 21 deletions

View file

@ -896,8 +896,8 @@ impl<'db> ClassLiteral<'db> {
} else {
let name = Type::string_literal(db, self.name(db));
let bases = TupleType::from_elements(db, self.explicit_bases(db));
// TODO: Should be `dict[str, Any]`
let namespace = KnownClass::Dict.to_instance(db);
let namespace = KnownClass::Dict
.to_specialized_instance(db, [KnownClass::Str.to_instance(db), Type::any()]);
// TODO: Other keyword arguments?
let arguments = CallArgumentTypes::positional([name, bases, namespace]);
@ -1913,7 +1913,9 @@ pub enum KnownClass {
Slice,
Property,
BaseException,
Exception,
BaseExceptionGroup,
ExceptionGroup,
Classmethod,
Super,
// enum
@ -2004,6 +2006,8 @@ impl<'db> KnownClass {
Self::Any
| Self::BaseException
| Self::Exception
| Self::ExceptionGroup
| Self::Object
| Self::OrderedDict
| Self::BaseExceptionGroup
@ -2079,6 +2083,8 @@ impl<'db> KnownClass {
| Self::Property
| Self::BaseException
| Self::BaseExceptionGroup
| Self::Exception
| Self::ExceptionGroup
| Self::Classmethod
| Self::GenericAlias
| Self::GeneratorType
@ -2137,6 +2143,8 @@ impl<'db> KnownClass {
Self::Property => "property",
Self::BaseException => "BaseException",
Self::BaseExceptionGroup => "BaseExceptionGroup",
Self::Exception => "Exception",
Self::ExceptionGroup => "ExceptionGroup",
Self::Classmethod => "classmethod",
Self::GenericAlias => "GenericAlias",
Self::ModuleType => "ModuleType",
@ -2234,7 +2242,9 @@ impl<'db> KnownClass {
db: &'db dyn Db,
specialization: impl IntoIterator<Item = Type<'db>>,
) -> Type<'db> {
let class_literal = self.to_class_literal(db).expect_class_literal();
let Type::ClassLiteral(class_literal) = self.to_class_literal(db) else {
return Type::unknown();
};
let Some(generic_context) = class_literal.generic_context(db) else {
return Type::unknown();
};
@ -2354,6 +2364,8 @@ impl<'db> KnownClass {
| Self::Dict
| Self::BaseException
| Self::BaseExceptionGroup
| Self::Exception
| Self::ExceptionGroup
| Self::Classmethod
| Self::Slice
| Self::Super
@ -2444,6 +2456,8 @@ impl<'db> KnownClass {
| Self::Property
| Self::BaseException
| Self::BaseExceptionGroup
| Self::Exception
| Self::ExceptionGroup
| Self::Classmethod
| Self::GenericAlias
| Self::ModuleType
@ -2522,6 +2536,8 @@ impl<'db> KnownClass {
| Self::SupportsIndex
| Self::BaseException
| Self::BaseExceptionGroup
| Self::Exception
| Self::ExceptionGroup
| Self::Classmethod
| Self::TypeVar
| Self::ParamSpec
@ -2565,6 +2581,8 @@ impl<'db> KnownClass {
"property" => Self::Property,
"BaseException" => Self::BaseException,
"BaseExceptionGroup" => Self::BaseExceptionGroup,
"Exception" => Self::Exception,
"ExceptionGroup" => Self::ExceptionGroup,
"classmethod" => Self::Classmethod,
"GenericAlias" => Self::GenericAlias,
"NoneType" => Self::NoneType,
@ -2643,6 +2661,8 @@ impl<'db> KnownClass {
| Self::ModuleType
| Self::VersionInfo
| Self::BaseException
| Self::Exception
| Self::ExceptionGroup
| Self::EllipsisType
| Self::BaseExceptionGroup
| Self::Classmethod
@ -2856,7 +2876,7 @@ mod tests {
for class in KnownClass::iter() {
let version_added = match class {
KnownClass::UnionType => PythonVersion::PY310,
KnownClass::BaseExceptionGroup => PythonVersion::PY311,
KnownClass::BaseExceptionGroup | KnownClass::ExceptionGroup => PythonVersion::PY311,
KnownClass::GenericAlias => PythonVersion::PY39,
_ => PythonVersion::PY37,
};

View file

@ -1843,9 +1843,7 @@ impl<'db> TypeInferenceBuilder<'db> {
}
let use_def = self.index.use_def_map(scope_id);
if use_def.can_implicit_return(self.db())
&& !KnownClass::NoneType
.to_instance(self.db())
.is_assignable_to(self.db(), declared_ty)
&& !Type::none(self.db()).is_assignable_to(self.db(), declared_ty)
{
report_implicit_return_type(&self.context, returns.range(), declared_ty);
}
@ -2623,9 +2621,14 @@ impl<'db> TypeInferenceBuilder<'db> {
};
let symbol_ty = if except_handler_definition.is_star() {
// TODO: we should infer `ExceptionGroup` if `node_ty` is a subtype of `tuple[type[Exception], ...]`
// TODO: should be generic with `symbol_ty` as the generic parameter
KnownClass::BaseExceptionGroup.to_instance(self.db())
let class = if symbol_ty
.is_subtype_of(self.db(), KnownClass::Exception.to_instance(self.db()))
{
KnownClass::ExceptionGroup
} else {
KnownClass::BaseExceptionGroup
};
class.to_specialized_instance(self.db(), [symbol_ty])
} else {
symbol_ty
};
@ -4104,7 +4107,7 @@ impl<'db> TypeInferenceBuilder<'db> {
.map_or(ret.range(), |value| value.range());
self.record_return_type(ty, range);
} else {
self.record_return_type(KnownClass::NoneType.to_instance(self.db()), ret.range());
self.record_return_type(Type::none(self.db()), ret.range());
}
}