mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
[red-knot] Use type[Unknown]
rather than Unknown
as the fallback metaclass for invalid classes (#14961)
This commit is contained in:
parent
4b2b126b9f
commit
90a5439791
2 changed files with 8 additions and 10 deletions
|
@ -68,7 +68,7 @@ class B(metaclass=M2): ...
|
||||||
# error: [conflicting-metaclass] "The metaclass of a derived class (`C`) must be a subclass of the metaclasses of all its bases, but `M1` (metaclass of base class `A`) and `M2` (metaclass of base class `B`) have no subclass relationship"
|
# error: [conflicting-metaclass] "The metaclass of a derived class (`C`) must be a subclass of the metaclasses of all its bases, but `M1` (metaclass of base class `A`) and `M2` (metaclass of base class `B`) have no subclass relationship"
|
||||||
class C(A, B): ...
|
class C(A, B): ...
|
||||||
|
|
||||||
reveal_type(C.__class__) # revealed: Unknown
|
reveal_type(C.__class__) # revealed: type[Unknown]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Conflict (2)
|
## Conflict (2)
|
||||||
|
@ -85,7 +85,7 @@ class A(metaclass=M1): ...
|
||||||
# error: [conflicting-metaclass] "The metaclass of a derived class (`B`) must be a subclass of the metaclasses of all its bases, but `M2` (metaclass of `B`) and `M1` (metaclass of base class `A`) have no subclass relationship"
|
# error: [conflicting-metaclass] "The metaclass of a derived class (`B`) must be a subclass of the metaclasses of all its bases, but `M2` (metaclass of `B`) and `M1` (metaclass of base class `A`) have no subclass relationship"
|
||||||
class B(A, metaclass=M2): ...
|
class B(A, metaclass=M2): ...
|
||||||
|
|
||||||
reveal_type(B.__class__) # revealed: Unknown
|
reveal_type(B.__class__) # revealed: type[Unknown]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Common metaclass
|
## Common metaclass
|
||||||
|
@ -129,7 +129,7 @@ class C(metaclass=M12): ...
|
||||||
# error: [conflicting-metaclass] "The metaclass of a derived class (`D`) must be a subclass of the metaclasses of all its bases, but `M1` (metaclass of base class `A`) and `M2` (metaclass of base class `B`) have no subclass relationship"
|
# error: [conflicting-metaclass] "The metaclass of a derived class (`D`) must be a subclass of the metaclasses of all its bases, but `M1` (metaclass of base class `A`) and `M2` (metaclass of base class `B`) have no subclass relationship"
|
||||||
class D(A, B, C): ...
|
class D(A, B, C): ...
|
||||||
|
|
||||||
reveal_type(D.__class__) # revealed: Unknown
|
reveal_type(D.__class__) # revealed: type[Unknown]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Unknown
|
## Unknown
|
||||||
|
@ -183,7 +183,7 @@ class A(B): ... # error: [cyclic-class-definition]
|
||||||
class B(C): ... # error: [cyclic-class-definition]
|
class B(C): ... # error: [cyclic-class-definition]
|
||||||
class C(A): ... # error: [cyclic-class-definition]
|
class C(A): ... # error: [cyclic-class-definition]
|
||||||
|
|
||||||
reveal_type(A.__class__) # revealed: Unknown
|
reveal_type(A.__class__) # revealed: type[Unknown]
|
||||||
```
|
```
|
||||||
|
|
||||||
## PEP 695 generic
|
## PEP 695 generic
|
||||||
|
|
|
@ -2925,10 +2925,10 @@ impl<'db> Class<'db> {
|
||||||
Some(metaclass_ty)
|
Some(metaclass_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the metaclass of this class, or `Unknown` if the metaclass cannot be inferred.
|
/// Return the metaclass of this class, or `type[Unknown]` if the metaclass cannot be inferred.
|
||||||
pub(crate) fn metaclass(self, db: &'db dyn Db) -> Type<'db> {
|
pub(crate) fn metaclass(self, db: &'db dyn Db) -> Type<'db> {
|
||||||
// TODO: `type[Unknown]` would be a more precise fallback
|
self.try_metaclass(db)
|
||||||
self.try_metaclass(db).unwrap_or(Type::Unknown)
|
.unwrap_or_else(|_| Type::subclass_of_base(ClassBase::Unknown))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the metaclass of this class, or an error if the metaclass cannot be inferred.
|
/// Return the metaclass of this class, or an error if the metaclass cannot be inferred.
|
||||||
|
@ -2941,9 +2941,7 @@ impl<'db> Class<'db> {
|
||||||
// We emit diagnostics for cyclic class definitions elsewhere.
|
// We emit diagnostics for cyclic class definitions elsewhere.
|
||||||
// Avoid attempting to infer the metaclass if the class is cyclically defined:
|
// Avoid attempting to infer the metaclass if the class is cyclically defined:
|
||||||
// it would be easy to enter an infinite loop.
|
// it would be easy to enter an infinite loop.
|
||||||
//
|
return Ok(Type::subclass_of_base(ClassBase::Unknown));
|
||||||
// TODO: `type[Unknown]` might be better here?
|
|
||||||
return Ok(Type::Unknown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let explicit_metaclass = self.explicit_metaclass(db);
|
let explicit_metaclass = self.explicit_metaclass(db);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue