Skip to content

Commit ba4dace

Browse files
committed
Replace vm.issubclass to obj.is_subclass
1 parent fc577e9 commit ba4dace

2 files changed

Lines changed: 31 additions & 32 deletions

File tree

vm/src/protocol/object.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,32 @@ impl PyObjectRef {
187187
}
188188
}
189189

190+
/// Determines if `self` is a subclass of `cls`, either directly, indirectly or virtually
191+
/// via the __subclasscheck__ magic method.
190192
pub fn is_subclass(&self, cls: &PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
191-
vm.issubclass(self, cls)
193+
if cls.class().is(&vm.ctx.types.type_type) {
194+
if self.is(cls) {
195+
return Ok(true);
196+
}
197+
return vm.recursive_issubclass(self, cls);
198+
}
199+
200+
if let Ok(tuple) = PyTupleRef::try_from_object(vm, cls.clone()) {
201+
for typ in tuple.as_slice().iter() {
202+
if vm.with_recursion("in __subclasscheck__", || self.is_subclass(typ, vm))? {
203+
return Ok(true);
204+
}
205+
}
206+
return Ok(false);
207+
}
208+
209+
if let Ok(meth) = vm.get_special_method(cls.clone(), "__subclasscheck__")? {
210+
let ret =
211+
vm.with_recursion("in __subclasscheck__", || meth.invoke((self.clone(),), vm))?;
212+
return ret.try_to_bool(vm);
213+
}
214+
215+
vm.recursive_issubclass(self, cls)
192216
}
193217

194218
/// Determines if `self` is an instance of `cls`, either directly, indirectly or virtually via

vm/src/vm.rs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ impl VirtualMachine {
10351035
}
10361036
}
10371037

1038-
fn abstract_issubclass(&self, subclass: PyObjectRef, cls: &PyObjectRef) -> PyResult<bool> {
1038+
pub fn abstract_issubclass(&self, subclass: PyObjectRef, cls: &PyObjectRef) -> PyResult<bool> {
10391039
let mut derived = subclass;
10401040
loop {
10411041
if derived.is(cls) {
@@ -1067,7 +1067,11 @@ impl VirtualMachine {
10671067
}
10681068
}
10691069

1070-
fn recursive_issubclass(&self, subclass: &PyObjectRef, cls: &PyObjectRef) -> PyResult<bool> {
1070+
pub fn recursive_issubclass(
1071+
&self,
1072+
subclass: &PyObjectRef,
1073+
cls: &PyObjectRef,
1074+
) -> PyResult<bool> {
10711075
if let (Ok(subclass), Ok(cls)) = (
10721076
PyTypeRef::try_from_object(self, subclass.clone()),
10731077
PyTypeRef::try_from_object(self, cls.clone()),
@@ -1090,35 +1094,6 @@ impl VirtualMachine {
10901094
}
10911095
}
10921096

1093-
/// Determines if `subclass` is a subclass of `cls`, either directly, indirectly or virtually
1094-
/// via the __subclasscheck__ magic method.
1095-
pub fn issubclass(&self, subclass: &PyObjectRef, cls: &PyObjectRef) -> PyResult<bool> {
1096-
if cls.class().is(&self.ctx.types.type_type) {
1097-
if subclass.is(cls) {
1098-
return Ok(true);
1099-
}
1100-
return self.recursive_issubclass(subclass, cls);
1101-
}
1102-
1103-
if let Ok(tuple) = PyTupleRef::try_from_object(self, cls.clone()) {
1104-
for typ in tuple.as_slice().iter() {
1105-
if self.with_recursion("in __subclasscheck__", || self.issubclass(subclass, typ))? {
1106-
return Ok(true);
1107-
}
1108-
}
1109-
return Ok(false);
1110-
}
1111-
1112-
if let Ok(meth) = self.get_special_method(cls.clone(), "__subclasscheck__")? {
1113-
let ret = self.with_recursion("in __subclasscheck__", || {
1114-
meth.invoke((subclass.clone(),), self)
1115-
})?;
1116-
return ret.try_to_bool(self);
1117-
}
1118-
1119-
self.recursive_issubclass(subclass, cls)
1120-
}
1121-
11221097
pub fn call_get_descriptor_specific(
11231098
&self,
11241099
descr: PyObjectRef,

0 commit comments

Comments
 (0)