use crate::{AsObject, PyObject, VirtualMachine}; pub struct ReprGuard<'vm> { vm: &'vm VirtualMachine, id: usize, } /// A guard to protect repr methods from recursion into itself, impl<'vm> ReprGuard<'vm> { /// Returns None if the guard against 'obj' is still held otherwise returns the guard. The guard /// which is released if dropped. pub fn enter(vm: &'vm VirtualMachine, obj: &PyObject) -> Option { let mut guards = vm.repr_guards.borrow_mut(); // Should this be a flag on the obj itself? putting it in a global variable for now until it // decided the form of PyObject. https://github.com/RustPython/RustPython/issues/371 let id = obj.get_id(); if guards.contains(&id) { return None; } guards.insert(id); Some(ReprGuard { vm, id }) } } impl<'vm> Drop for ReprGuard<'vm> { fn drop(&mut self) { self.vm.repr_guards.borrow_mut().remove(&self.id); } }