Skip to content

Commit f44c61e

Browse files
authored
Merge pull request RustPython#3293 from DimitrisJim/recursive_inst_subcls
Fix recursions in isinstance and issubclass.
2 parents b3220f9 + 4fad83e commit f44c61e

File tree

2 files changed

+8
-9
lines changed

2 files changed

+8
-9
lines changed

Lib/test/test_isinstance.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,15 +241,11 @@ def test_subclass_tuple(self):
241241
self.assertEqual(True, issubclass(int, (int, (float, int))))
242242
self.assertEqual(True, issubclass(str, (str, (Child, str))))
243243

244-
# TODO: RUSTPYTHON requires issue 2680 for stack depth detection in Rust
245-
@unittest.expectedFailure
246244
def test_subclass_recursion_limit(self):
247245
# make sure that issubclass raises RecursionError before the C stack is
248246
# blown
249247
self.assertRaises(RecursionError, blowstack, issubclass, str, str)
250248

251-
# TODO: RUSTPYTHON requires issue 2680 for stack depth detection in Rust
252-
@unittest.expectedFailure
253249
def test_isinstance_recursion_limit(self):
254250
# make sure that issubclass raises RecursionError before the C stack is
255251
# blown

vm/src/vm.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ impl VirtualMachine {
902902
}
903903

904904
pub fn to_repr(&self, obj: &PyObjectRef) -> PyResult<PyStrRef> {
905-
self.with_recursion(" while getting the repr of an object", || {
905+
self.with_recursion("while getting the repr of an object", || {
906906
let repr = self.call_special_method(obj.clone(), "__repr__", ())?;
907907
repr.try_into_value(self)
908908
})
@@ -1057,15 +1057,16 @@ impl VirtualMachine {
10571057

10581058
if let Ok(tuple) = PyTupleRef::try_from_object(self, cls.clone()) {
10591059
for typ in tuple.as_slice().iter() {
1060-
if self.isinstance(obj, typ)? {
1060+
if self.with_recursion("in __instancecheck__", || self.isinstance(obj, typ))? {
10611061
return Ok(true);
10621062
}
10631063
}
10641064
return Ok(false);
10651065
}
10661066

10671067
if let Ok(meth) = self.get_special_method(cls.clone(), "__instancecheck__")? {
1068-
let ret = meth.invoke((obj.clone(),), self)?;
1068+
let ret =
1069+
self.with_recursion("in __instancecheck__", || meth.invoke((obj.clone(),), self))?;
10691070
return ret.try_to_bool(self);
10701071
}
10711072

@@ -1139,15 +1140,17 @@ impl VirtualMachine {
11391140

11401141
if let Ok(tuple) = PyTupleRef::try_from_object(self, cls.clone()) {
11411142
for typ in tuple.as_slice().iter() {
1142-
if self.issubclass(subclass, typ)? {
1143+
if self.with_recursion("in __subclasscheck__", || self.issubclass(subclass, typ))? {
11431144
return Ok(true);
11441145
}
11451146
}
11461147
return Ok(false);
11471148
}
11481149

11491150
if let Ok(meth) = self.get_special_method(cls.clone(), "__subclasscheck__")? {
1150-
let ret = meth.invoke((subclass.clone(),), self)?;
1151+
let ret = self.with_recursion("in __subclasscheck__", || {
1152+
meth.invoke((subclass.clone(),), self)
1153+
})?;
11511154
return ret.try_to_bool(self);
11521155
}
11531156

0 commit comments

Comments
 (0)