rustpython_vm/
recursion.rs

1use crate::{AsObject, PyObject, VirtualMachine};
2
3pub struct ReprGuard<'vm> {
4    vm: &'vm VirtualMachine,
5    id: usize,
6}
7
8/// A guard to protect repr methods from recursion into itself,
9impl<'vm> ReprGuard<'vm> {
10    /// Returns None if the guard against 'obj' is still held otherwise returns the guard. The guard
11    /// which is released if dropped.
12    pub fn enter(vm: &'vm VirtualMachine, obj: &PyObject) -> Option<Self> {
13        let mut guards = vm.repr_guards.borrow_mut();
14
15        // Should this be a flag on the obj itself? putting it in a global variable for now until it
16        // decided the form of PyObject. https://github.com/RustPython/RustPython/issues/371
17        let id = obj.get_id();
18        if guards.contains(&id) {
19            return None;
20        }
21        guards.insert(id);
22        Some(ReprGuard { vm, id })
23    }
24}
25
26impl<'vm> Drop for ReprGuard<'vm> {
27    fn drop(&mut self) {
28        self.vm.repr_guards.borrow_mut().remove(&self.id);
29    }
30}