diff --git a/vm/src/obj/objweakproxy.rs b/vm/src/obj/objweakproxy.rs index 735670f4e..5d4f68d9d 100644 --- a/vm/src/obj/objweakproxy.rs +++ b/vm/src/obj/objweakproxy.rs @@ -1,9 +1,10 @@ use super::objweakref::PyWeak; use crate::function::OptionalArg; use crate::obj::objtype::PyClassRef; -use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue}; +use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue}; use crate::vm::VirtualMachine; +#[pyclass] #[derive(Debug)] pub struct PyWeakProxy { weak: PyWeak, @@ -17,21 +18,27 @@ impl PyValue for PyWeakProxy { pub type PyWeakProxyRef = PyRef; -impl PyWeakProxyRef { - // TODO callbacks +#[pyimpl] +impl PyWeakProxy { + // TODO: callbacks + #[pymethod(name = "__new__")] fn create( cls: PyClassRef, referent: PyObjectRef, - _callback: OptionalArg, + callback: OptionalArg, vm: &VirtualMachine, - ) -> PyResult { + ) -> PyResult { + if callback.is_present() { + panic!("Passed a callback to weakproxy, but weakproxy does not yet support proxies."); + } PyWeakProxy { weak: PyWeak::downgrade(&referent), } .into_ref_with_type(vm, cls) } - fn getattr(self, attr_name: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__getattr__")] + fn getattr(&self, attr_name: PyObjectRef, vm: &VirtualMachine) -> PyResult { match self.weak.upgrade() { Some(obj) => vm.get_attribute(obj, attr_name), None => Err(vm.new_exception( @@ -40,11 +47,19 @@ impl PyWeakProxyRef { )), } } + + #[pymethod(name = "__setattr__")] + fn setattr(&self, attr_name: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult { + match self.weak.upgrade() { + Some(obj) => vm.set_attr(&obj, attr_name, value), + None => Err(vm.new_exception( + vm.ctx.exceptions.reference_error.clone(), + "weakly-referenced object no longer exists".to_string(), + )), + } + } } pub fn init(context: &PyContext) { - extend_class!(context, &context.weakproxy_type, { - "__new__" => context.new_rustfunc(PyWeakProxyRef::create), - "__getattr__" => context.new_rustfunc(PyWeakProxyRef::getattr), - }); + PyWeakProxy::extend_class(&context, &context.weakproxy_type); }