Skip to main content

rustpython_vm/
recursion.rs

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