mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:25:17 +00:00
[ty] Fix more generics-related TODOs (#18062)
This commit is contained in:
parent
8104b1e83b
commit
0590b38214
3 changed files with 39 additions and 21 deletions
|
@ -22,9 +22,7 @@ except* BaseException as e:
|
||||||
try:
|
try:
|
||||||
help()
|
help()
|
||||||
except* OSError as e:
|
except* OSError as e:
|
||||||
# TODO: more precise would be `ExceptionGroup[OSError]` --Alex
|
reveal_type(e) # revealed: ExceptionGroup[OSError]
|
||||||
# (needs homogeneous tuples + generics)
|
|
||||||
reveal_type(e) # revealed: BaseExceptionGroup[BaseException]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## `except*` with multiple exceptions
|
## `except*` with multiple exceptions
|
||||||
|
@ -33,9 +31,7 @@ except* OSError as e:
|
||||||
try:
|
try:
|
||||||
help()
|
help()
|
||||||
except* (TypeError, AttributeError) as e:
|
except* (TypeError, AttributeError) as e:
|
||||||
# TODO: more precise would be `ExceptionGroup[TypeError | AttributeError]` --Alex
|
reveal_type(e) # revealed: ExceptionGroup[TypeError | AttributeError]
|
||||||
# (needs homogeneous tuples + generics)
|
|
||||||
reveal_type(e) # revealed: BaseExceptionGroup[BaseException]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## `except*` with mix of `Exception`s and `BaseException`s
|
## `except*` with mix of `Exception`s and `BaseException`s
|
||||||
|
@ -44,8 +40,7 @@ except* (TypeError, AttributeError) as e:
|
||||||
try:
|
try:
|
||||||
help()
|
help()
|
||||||
except* (KeyboardInterrupt, AttributeError) as e:
|
except* (KeyboardInterrupt, AttributeError) as e:
|
||||||
# TODO: more precise would be `BaseExceptionGroup[KeyboardInterrupt | AttributeError]` --Alex
|
reveal_type(e) # revealed: BaseExceptionGroup[KeyboardInterrupt | AttributeError]
|
||||||
reveal_type(e) # revealed: BaseExceptionGroup[BaseException]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Invalid `except*` handlers
|
## Invalid `except*` handlers
|
||||||
|
@ -54,10 +49,10 @@ except* (KeyboardInterrupt, AttributeError) as e:
|
||||||
try:
|
try:
|
||||||
help()
|
help()
|
||||||
except* 3 as e: # error: [invalid-exception-caught]
|
except* 3 as e: # error: [invalid-exception-caught]
|
||||||
reveal_type(e) # revealed: BaseExceptionGroup[BaseException]
|
reveal_type(e) # revealed: BaseExceptionGroup[Unknown]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
help()
|
help()
|
||||||
except* (AttributeError, 42) as e: # error: [invalid-exception-caught]
|
except* (AttributeError, 42) as e: # error: [invalid-exception-caught]
|
||||||
reveal_type(e) # revealed: BaseExceptionGroup[BaseException]
|
reveal_type(e) # revealed: BaseExceptionGroup[AttributeError | Unknown]
|
||||||
```
|
```
|
||||||
|
|
|
@ -896,8 +896,8 @@ impl<'db> ClassLiteral<'db> {
|
||||||
} else {
|
} else {
|
||||||
let name = Type::string_literal(db, self.name(db));
|
let name = Type::string_literal(db, self.name(db));
|
||||||
let bases = TupleType::from_elements(db, self.explicit_bases(db));
|
let bases = TupleType::from_elements(db, self.explicit_bases(db));
|
||||||
// TODO: Should be `dict[str, Any]`
|
let namespace = KnownClass::Dict
|
||||||
let namespace = KnownClass::Dict.to_instance(db);
|
.to_specialized_instance(db, [KnownClass::Str.to_instance(db), Type::any()]);
|
||||||
|
|
||||||
// TODO: Other keyword arguments?
|
// TODO: Other keyword arguments?
|
||||||
let arguments = CallArgumentTypes::positional([name, bases, namespace]);
|
let arguments = CallArgumentTypes::positional([name, bases, namespace]);
|
||||||
|
@ -1913,7 +1913,9 @@ pub enum KnownClass {
|
||||||
Slice,
|
Slice,
|
||||||
Property,
|
Property,
|
||||||
BaseException,
|
BaseException,
|
||||||
|
Exception,
|
||||||
BaseExceptionGroup,
|
BaseExceptionGroup,
|
||||||
|
ExceptionGroup,
|
||||||
Classmethod,
|
Classmethod,
|
||||||
Super,
|
Super,
|
||||||
// enum
|
// enum
|
||||||
|
@ -2004,6 +2006,8 @@ impl<'db> KnownClass {
|
||||||
|
|
||||||
Self::Any
|
Self::Any
|
||||||
| Self::BaseException
|
| Self::BaseException
|
||||||
|
| Self::Exception
|
||||||
|
| Self::ExceptionGroup
|
||||||
| Self::Object
|
| Self::Object
|
||||||
| Self::OrderedDict
|
| Self::OrderedDict
|
||||||
| Self::BaseExceptionGroup
|
| Self::BaseExceptionGroup
|
||||||
|
@ -2079,6 +2083,8 @@ impl<'db> KnownClass {
|
||||||
| Self::Property
|
| Self::Property
|
||||||
| Self::BaseException
|
| Self::BaseException
|
||||||
| Self::BaseExceptionGroup
|
| Self::BaseExceptionGroup
|
||||||
|
| Self::Exception
|
||||||
|
| Self::ExceptionGroup
|
||||||
| Self::Classmethod
|
| Self::Classmethod
|
||||||
| Self::GenericAlias
|
| Self::GenericAlias
|
||||||
| Self::GeneratorType
|
| Self::GeneratorType
|
||||||
|
@ -2137,6 +2143,8 @@ impl<'db> KnownClass {
|
||||||
Self::Property => "property",
|
Self::Property => "property",
|
||||||
Self::BaseException => "BaseException",
|
Self::BaseException => "BaseException",
|
||||||
Self::BaseExceptionGroup => "BaseExceptionGroup",
|
Self::BaseExceptionGroup => "BaseExceptionGroup",
|
||||||
|
Self::Exception => "Exception",
|
||||||
|
Self::ExceptionGroup => "ExceptionGroup",
|
||||||
Self::Classmethod => "classmethod",
|
Self::Classmethod => "classmethod",
|
||||||
Self::GenericAlias => "GenericAlias",
|
Self::GenericAlias => "GenericAlias",
|
||||||
Self::ModuleType => "ModuleType",
|
Self::ModuleType => "ModuleType",
|
||||||
|
@ -2234,7 +2242,9 @@ impl<'db> KnownClass {
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
specialization: impl IntoIterator<Item = Type<'db>>,
|
specialization: impl IntoIterator<Item = Type<'db>>,
|
||||||
) -> 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 {
|
let Some(generic_context) = class_literal.generic_context(db) else {
|
||||||
return Type::unknown();
|
return Type::unknown();
|
||||||
};
|
};
|
||||||
|
@ -2354,6 +2364,8 @@ impl<'db> KnownClass {
|
||||||
| Self::Dict
|
| Self::Dict
|
||||||
| Self::BaseException
|
| Self::BaseException
|
||||||
| Self::BaseExceptionGroup
|
| Self::BaseExceptionGroup
|
||||||
|
| Self::Exception
|
||||||
|
| Self::ExceptionGroup
|
||||||
| Self::Classmethod
|
| Self::Classmethod
|
||||||
| Self::Slice
|
| Self::Slice
|
||||||
| Self::Super
|
| Self::Super
|
||||||
|
@ -2444,6 +2456,8 @@ impl<'db> KnownClass {
|
||||||
| Self::Property
|
| Self::Property
|
||||||
| Self::BaseException
|
| Self::BaseException
|
||||||
| Self::BaseExceptionGroup
|
| Self::BaseExceptionGroup
|
||||||
|
| Self::Exception
|
||||||
|
| Self::ExceptionGroup
|
||||||
| Self::Classmethod
|
| Self::Classmethod
|
||||||
| Self::GenericAlias
|
| Self::GenericAlias
|
||||||
| Self::ModuleType
|
| Self::ModuleType
|
||||||
|
@ -2522,6 +2536,8 @@ impl<'db> KnownClass {
|
||||||
| Self::SupportsIndex
|
| Self::SupportsIndex
|
||||||
| Self::BaseException
|
| Self::BaseException
|
||||||
| Self::BaseExceptionGroup
|
| Self::BaseExceptionGroup
|
||||||
|
| Self::Exception
|
||||||
|
| Self::ExceptionGroup
|
||||||
| Self::Classmethod
|
| Self::Classmethod
|
||||||
| Self::TypeVar
|
| Self::TypeVar
|
||||||
| Self::ParamSpec
|
| Self::ParamSpec
|
||||||
|
@ -2565,6 +2581,8 @@ impl<'db> KnownClass {
|
||||||
"property" => Self::Property,
|
"property" => Self::Property,
|
||||||
"BaseException" => Self::BaseException,
|
"BaseException" => Self::BaseException,
|
||||||
"BaseExceptionGroup" => Self::BaseExceptionGroup,
|
"BaseExceptionGroup" => Self::BaseExceptionGroup,
|
||||||
|
"Exception" => Self::Exception,
|
||||||
|
"ExceptionGroup" => Self::ExceptionGroup,
|
||||||
"classmethod" => Self::Classmethod,
|
"classmethod" => Self::Classmethod,
|
||||||
"GenericAlias" => Self::GenericAlias,
|
"GenericAlias" => Self::GenericAlias,
|
||||||
"NoneType" => Self::NoneType,
|
"NoneType" => Self::NoneType,
|
||||||
|
@ -2643,6 +2661,8 @@ impl<'db> KnownClass {
|
||||||
| Self::ModuleType
|
| Self::ModuleType
|
||||||
| Self::VersionInfo
|
| Self::VersionInfo
|
||||||
| Self::BaseException
|
| Self::BaseException
|
||||||
|
| Self::Exception
|
||||||
|
| Self::ExceptionGroup
|
||||||
| Self::EllipsisType
|
| Self::EllipsisType
|
||||||
| Self::BaseExceptionGroup
|
| Self::BaseExceptionGroup
|
||||||
| Self::Classmethod
|
| Self::Classmethod
|
||||||
|
@ -2856,7 +2876,7 @@ mod tests {
|
||||||
for class in KnownClass::iter() {
|
for class in KnownClass::iter() {
|
||||||
let version_added = match class {
|
let version_added = match class {
|
||||||
KnownClass::UnionType => PythonVersion::PY310,
|
KnownClass::UnionType => PythonVersion::PY310,
|
||||||
KnownClass::BaseExceptionGroup => PythonVersion::PY311,
|
KnownClass::BaseExceptionGroup | KnownClass::ExceptionGroup => PythonVersion::PY311,
|
||||||
KnownClass::GenericAlias => PythonVersion::PY39,
|
KnownClass::GenericAlias => PythonVersion::PY39,
|
||||||
_ => PythonVersion::PY37,
|
_ => PythonVersion::PY37,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1843,9 +1843,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||||
}
|
}
|
||||||
let use_def = self.index.use_def_map(scope_id);
|
let use_def = self.index.use_def_map(scope_id);
|
||||||
if use_def.can_implicit_return(self.db())
|
if use_def.can_implicit_return(self.db())
|
||||||
&& !KnownClass::NoneType
|
&& !Type::none(self.db()).is_assignable_to(self.db(), declared_ty)
|
||||||
.to_instance(self.db())
|
|
||||||
.is_assignable_to(self.db(), declared_ty)
|
|
||||||
{
|
{
|
||||||
report_implicit_return_type(&self.context, returns.range(), 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() {
|
let symbol_ty = if except_handler_definition.is_star() {
|
||||||
// TODO: we should infer `ExceptionGroup` if `node_ty` is a subtype of `tuple[type[Exception], ...]`
|
let class = if symbol_ty
|
||||||
// TODO: should be generic with `symbol_ty` as the generic parameter
|
.is_subtype_of(self.db(), KnownClass::Exception.to_instance(self.db()))
|
||||||
KnownClass::BaseExceptionGroup.to_instance(self.db())
|
{
|
||||||
|
KnownClass::ExceptionGroup
|
||||||
|
} else {
|
||||||
|
KnownClass::BaseExceptionGroup
|
||||||
|
};
|
||||||
|
class.to_specialized_instance(self.db(), [symbol_ty])
|
||||||
} else {
|
} else {
|
||||||
symbol_ty
|
symbol_ty
|
||||||
};
|
};
|
||||||
|
@ -4104,7 +4107,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||||
.map_or(ret.range(), |value| value.range());
|
.map_or(ret.range(), |value| value.range());
|
||||||
self.record_return_type(ty, range);
|
self.record_return_type(ty, range);
|
||||||
} else {
|
} else {
|
||||||
self.record_return_type(KnownClass::NoneType.to_instance(self.db()), ret.range());
|
self.record_return_type(Type::none(self.db()), ret.range());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue