mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Fix type.__subclasscheck__ (#5864)
This commit is contained in:
2
Lib/test/test_typing.py
vendored
2
Lib/test/test_typing.py
vendored
@@ -3296,8 +3296,6 @@ class ProtocolTests(BaseTestCase):
|
||||
|
||||
self.assertNotIsInstance([], collections.abc.Mapping)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_issubclass_and_isinstance_on_Protocol_itself(self):
|
||||
class C:
|
||||
def x(self): pass
|
||||
|
||||
@@ -442,7 +442,7 @@ impl Py<PyType> {
|
||||
/// Determines if `subclass` is actually a subclass of `cls`, this doesn't call __subclasscheck__,
|
||||
/// so only use this if `cls` is known to have not overridden the base __subclasscheck__ magic
|
||||
/// method.
|
||||
pub fn fast_issubclass(&self, cls: &impl Borrow<crate::PyObject>) -> bool {
|
||||
pub fn fast_issubclass(&self, cls: &impl Borrow<PyObject>) -> bool {
|
||||
self.as_object().is(cls.borrow()) || self.mro.read().iter().any(|c| c.is(cls.borrow()))
|
||||
}
|
||||
|
||||
@@ -1216,8 +1216,10 @@ impl Py<PyType> {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __subclasscheck__(&self, subclass: PyTypeRef) -> bool {
|
||||
subclass.fast_issubclass(self)
|
||||
fn __subclasscheck__(&self, subclass: PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
// Use real_is_subclass to avoid going through __subclasscheck__ recursion
|
||||
// This matches CPython's type___subclasscheck___impl which calls _PyObject_RealIsSubclass
|
||||
subclass.real_is_subclass(self.as_object(), vm)
|
||||
}
|
||||
|
||||
#[pyclassmethod]
|
||||
|
||||
@@ -447,6 +447,12 @@ impl PyObject {
|
||||
}
|
||||
}
|
||||
|
||||
/// Real issubclass check without going through __subclasscheck__
|
||||
/// This is equivalent to CPython's _PyObject_RealIsSubclass which just calls recursive_issubclass
|
||||
pub fn real_is_subclass(&self, cls: &PyObject, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
self.recursive_issubclass(cls, vm)
|
||||
}
|
||||
|
||||
/// Determines if `self` is a subclass of `cls`, either directly, indirectly or virtually
|
||||
/// via the __subclasscheck__ magic method.
|
||||
/// PyObject_IsSubclass/object_issubclass
|
||||
|
||||
Reference in New Issue
Block a user