From 4fad83e3cc23456c952356a321394d377c353f69 Mon Sep 17 00:00:00 2001 From: jfh Date: Wed, 13 Oct 2021 19:32:31 +0300 Subject: [PATCH] Fix recursions in isinstance and issubclass. --- Lib/test/test_isinstance.py | 4 ---- vm/src/vm.rs | 13 ++++++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index f8e025c9f1..104f519f56 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -241,15 +241,11 @@ class TestIsInstanceIsSubclass(unittest.TestCase): self.assertEqual(True, issubclass(int, (int, (float, int)))) self.assertEqual(True, issubclass(str, (str, (Child, str)))) - # TODO: RUSTPYTHON requires issue 2680 for stack depth detection in Rust - @unittest.expectedFailure def test_subclass_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is # blown self.assertRaises(RecursionError, blowstack, issubclass, str, str) - # TODO: RUSTPYTHON requires issue 2680 for stack depth detection in Rust - @unittest.expectedFailure def test_isinstance_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is # blown diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 3997d9f3c1..1032dff343 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -902,7 +902,7 @@ impl VirtualMachine { } pub fn to_repr(&self, obj: &PyObjectRef) -> PyResult { - self.with_recursion(" while getting the repr of an object", || { + self.with_recursion("while getting the repr of an object", || { let repr = self.call_special_method(obj.clone(), "__repr__", ())?; repr.try_into_value(self) }) @@ -1057,7 +1057,7 @@ impl VirtualMachine { if let Ok(tuple) = PyTupleRef::try_from_object(self, cls.clone()) { for typ in tuple.as_slice().iter() { - if self.isinstance(obj, typ)? { + if self.with_recursion("in __instancecheck__", || self.isinstance(obj, typ))? { return Ok(true); } } @@ -1065,7 +1065,8 @@ impl VirtualMachine { } if let Ok(meth) = self.get_special_method(cls.clone(), "__instancecheck__")? { - let ret = meth.invoke((obj.clone(),), self)?; + let ret = + self.with_recursion("in __instancecheck__", || meth.invoke((obj.clone(),), self))?; return ret.try_to_bool(self); } @@ -1139,7 +1140,7 @@ impl VirtualMachine { if let Ok(tuple) = PyTupleRef::try_from_object(self, cls.clone()) { for typ in tuple.as_slice().iter() { - if self.issubclass(subclass, typ)? { + if self.with_recursion("in __subclasscheck__", || self.issubclass(subclass, typ))? { return Ok(true); } } @@ -1147,7 +1148,9 @@ impl VirtualMachine { } if let Ok(meth) = self.get_special_method(cls.clone(), "__subclasscheck__")? { - let ret = meth.invoke((subclass.clone(),), self)?; + let ret = self.with_recursion("in __subclasscheck__", || { + meth.invoke((subclass.clone(),), self) + })?; return ret.try_to_bool(self); }