mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[ty] Remove use of ClassBase::try_from_type
from super()
machinery (#19902)
This commit is contained in:
parent
ce938fe205
commit
82350a398e
2 changed files with 41 additions and 16 deletions
|
@ -331,6 +331,9 @@ instance or a subclass of the first. If either condition is violated, a `TypeErr
|
||||||
runtime.
|
runtime.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
import typing
|
||||||
|
import collections
|
||||||
|
|
||||||
def f(x: int):
|
def f(x: int):
|
||||||
# error: [invalid-super-argument] "`int` is not a valid class"
|
# error: [invalid-super-argument] "`int` is not a valid class"
|
||||||
super(x, x)
|
super(x, x)
|
||||||
|
@ -367,6 +370,19 @@ reveal_type(super(B, A))
|
||||||
reveal_type(super(B, object))
|
reveal_type(super(B, object))
|
||||||
|
|
||||||
super(object, object()).__class__
|
super(object, object()).__class__
|
||||||
|
|
||||||
|
# Not all objects valid in a class's bases list are valid as the first argument to `super()`.
|
||||||
|
# For example, it's valid to inherit from `typing.ChainMap`, but it's not valid as the first argument to `super()`.
|
||||||
|
#
|
||||||
|
# error: [invalid-super-argument] "`typing.ChainMap` is not a valid class"
|
||||||
|
reveal_type(super(typing.ChainMap, collections.ChainMap())) # revealed: Unknown
|
||||||
|
|
||||||
|
# Meanwhile, it's not valid to inherit from unsubscripted `typing.Generic`,
|
||||||
|
# but it *is* valid as the first argument to `super()`.
|
||||||
|
reveal_type(super(typing.Generic, typing.SupportsInt)) # revealed: <super: typing.Generic, <class 'SupportsInt'>>
|
||||||
|
|
||||||
|
def _(x: type[typing.Any], y: typing.Any):
|
||||||
|
reveal_type(super(x, y)) # revealed: <super: Any, Any>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Instance Member Access via `super`
|
### Instance Member Access via `super`
|
||||||
|
|
|
@ -9526,23 +9526,32 @@ impl<'db> BoundSuperType<'db> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: having to get a class-literal just to pass it in here is silly.
|
// We don't use `Classbase::try_from_type` here because:
|
||||||
// `BoundSuperType` should probably not be using `ClassBase::try_from_type` here;
|
// - There are objects that may validly be present in a class's bases list
|
||||||
// this also leads to false negatives in some cases. See discussion in
|
// but are not valid as pivot classes, e.g. `typing.ChainMap`
|
||||||
// <https://github.com/astral-sh/ruff/pull/19560#discussion_r2271570071>.
|
// - There are objects that are not valid in a class's bases list
|
||||||
let pivot_class = ClassBase::try_from_type(
|
// but are valid as pivot classes, e.g. unsubscripted `typing.Generic`
|
||||||
db,
|
let pivot_class = match pivot_class_type {
|
||||||
pivot_class_type,
|
Type::ClassLiteral(class) => ClassBase::Class(ClassType::NonGeneric(class)),
|
||||||
KnownClass::Object
|
Type::GenericAlias(class) => ClassBase::Class(ClassType::Generic(class)),
|
||||||
.to_class_literal(db)
|
Type::SubclassOf(subclass_of) if subclass_of.subclass_of().is_dynamic() => {
|
||||||
.into_class_literal()
|
ClassBase::Dynamic(
|
||||||
.expect("`object` should always exist in typeshed"),
|
subclass_of
|
||||||
|
.subclass_of()
|
||||||
|
.into_dynamic()
|
||||||
|
.expect("Checked in branch arm"),
|
||||||
)
|
)
|
||||||
.ok_or({
|
|
||||||
BoundSuperError::InvalidPivotClassType {
|
|
||||||
pivot_class: pivot_class_type,
|
|
||||||
}
|
}
|
||||||
})?;
|
Type::SpecialForm(SpecialFormType::Protocol) => ClassBase::Protocol,
|
||||||
|
Type::SpecialForm(SpecialFormType::Generic) => ClassBase::Generic,
|
||||||
|
Type::SpecialForm(SpecialFormType::TypedDict) => ClassBase::TypedDict,
|
||||||
|
Type::Dynamic(dynamic) => ClassBase::Dynamic(dynamic),
|
||||||
|
_ => {
|
||||||
|
return Err(BoundSuperError::InvalidPivotClassType {
|
||||||
|
pivot_class: pivot_class_type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let owner = SuperOwnerKind::try_from_type(db, owner_type)
|
let owner = SuperOwnerKind::try_from_type(db, owner_type)
|
||||||
.and_then(|owner| {
|
.and_then(|owner| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue