forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweakref.rs
More file actions
55 lines (49 loc) · 1.8 KB
/
weakref.rs
File metadata and controls
55 lines (49 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//! Implementation in line with the python `weakref` module.
//!
//! See also:
//! - [python weakref module](https://docs.python.org/3/library/weakref.html)
//! - [rust weak struct](https://doc.rust-lang.org/std/rc/struct.Weak.html)
//!
use super::super::obj::objtype;
use super::super::pyobject::{
PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyObjectWeakRef, PyResult,
TypeProtocol,
};
use super::super::VirtualMachine;
use std::rc::Rc;
pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
let py_mod = ctx.new_module(&"_weakref".to_string(), ctx.new_scope(None));
let py_ref_class = ctx.new_class("ref", ctx.object());
ctx.set_attr(&py_ref_class, "__new__", ctx.new_rustfunc(ref_new));
ctx.set_attr(&py_ref_class, "__call__", ctx.new_rustfunc(ref_call));
ctx.set_attr(&py_mod, "ref", py_ref_class);
py_mod
}
fn ref_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
// TODO: check first argument for subclass of `ref`.
arg_check!(vm, args, required = [(cls, None), (referent, None)]);
let referent = Rc::downgrade(referent);
Ok(PyObject::new(
PyObjectKind::WeakRef { referent: referent },
cls.clone(),
))
}
/// Dereference the weakref, and check if we still refer something.
fn ref_call(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
// TODO: check first argument for subclass of `ref`.
arg_check!(vm, args, required = [(cls, None)]);
let referent = get_value(cls);
let py_obj = if let Some(obj) = referent.upgrade() {
obj
} else {
vm.get_none()
};
Ok(py_obj)
}
fn get_value(obj: &PyObjectRef) -> PyObjectWeakRef {
if let PyObjectKind::WeakRef { referent } = &obj.borrow().kind {
referent.clone()
} else {
panic!("Inner error getting weak ref {:?}", obj);
}
}