mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 05:45:24 +00:00
[red-knot] Treat classes as instances of their respective metaclasses in boolean tests (#15105)
## Summary Follow-up to #15089. ## Test Plan Markdown tests. --------- Co-authored-by: Carl Meyer <carl@astral.sh>
This commit is contained in:
parent
3b27d5dbad
commit
f764f59971
2 changed files with 68 additions and 24 deletions
|
@ -1206,14 +1206,6 @@ impl<'db> Type<'db> {
|
|||
Type::SubclassOf(_),
|
||||
) => true,
|
||||
|
||||
(Type::SubclassOf(_), _) | (_, Type::SubclassOf(_)) => {
|
||||
// TODO: Once we have support for final classes, we can determine disjointness in some cases
|
||||
// here. However, note that it might be better to turn `Type::SubclassOf('FinalClass')` into
|
||||
// `Type::ClassLiteral('FinalClass')` during construction, instead of adding special cases for
|
||||
// final classes inside `Type::SubclassOf` everywhere.
|
||||
false
|
||||
}
|
||||
|
||||
(Type::AlwaysTruthy, ty) | (ty, Type::AlwaysTruthy) => {
|
||||
// `Truthiness::Ambiguous` may include `AlwaysTrue` as a subset, so it's not guaranteed to be disjoint.
|
||||
// Thus, they are only disjoint if `ty.bool() == AlwaysFalse`.
|
||||
|
@ -1224,6 +1216,14 @@ impl<'db> Type<'db> {
|
|||
matches!(ty.bool(db), Truthiness::AlwaysTrue)
|
||||
}
|
||||
|
||||
(Type::SubclassOf(_), _) | (_, Type::SubclassOf(_)) => {
|
||||
// TODO: Once we have support for final classes, we can determine disjointness in some cases
|
||||
// here. However, note that it might be better to turn `Type::SubclassOf('FinalClass')` into
|
||||
// `Type::ClassLiteral('FinalClass')` during construction, instead of adding special cases for
|
||||
// final classes inside `Type::SubclassOf` everywhere.
|
||||
false
|
||||
}
|
||||
|
||||
(Type::KnownInstance(left), right) => {
|
||||
left.instance_fallback(db).is_disjoint_from(db, right)
|
||||
}
|
||||
|
@ -1678,15 +1678,13 @@ impl<'db> Type<'db> {
|
|||
Type::Any | Type::Todo(_) | Type::Never | Type::Unknown => Truthiness::Ambiguous,
|
||||
Type::FunctionLiteral(_) => Truthiness::AlwaysTrue,
|
||||
Type::ModuleLiteral(_) => Truthiness::AlwaysTrue,
|
||||
Type::ClassLiteral(_) => {
|
||||
// TODO: lookup `__bool__` and `__len__` methods on the class's metaclass
|
||||
// More info in https://docs.python.org/3/library/stdtypes.html#truth-value-testing
|
||||
Truthiness::Ambiguous
|
||||
}
|
||||
Type::SubclassOf(_) => {
|
||||
// TODO: see above
|
||||
Truthiness::Ambiguous
|
||||
Type::ClassLiteral(ClassLiteralType { class }) => {
|
||||
class.metaclass(db).to_instance(db).bool(db)
|
||||
}
|
||||
Type::SubclassOf(SubclassOfType { base }) => base
|
||||
.into_class()
|
||||
.map(|class| Type::class_literal(class).bool(db))
|
||||
.unwrap_or(Truthiness::Ambiguous),
|
||||
Type::AlwaysTruthy => Truthiness::AlwaysTrue,
|
||||
Type::AlwaysFalsy => Truthiness::AlwaysFalse,
|
||||
instance_ty @ Type::Instance(InstanceType { class }) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue