Skip to content

Commit 21a7369

Browse files
yonmilkyouknowone
authored andcommitted
Add weakproxy mapping
1 parent e4bef69 commit 21a7369

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

Lib/test/test_array.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,8 +1028,6 @@ def test_buffer(self):
10281028
self.assertRaises(BufferError, operator.delitem, a, slice(0, 1))
10291029
self.assertEqual(m.tobytes(), expected)
10301030

1031-
# TODO: RUSTPYTHON
1032-
@unittest.expectedFailure
10331031
def test_weakref(self):
10341032
s = array.array(self.typecode, self.example)
10351033
p = weakref.proxy(s)

Lib/test/test_weakref.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,6 @@ def check_proxy(self, o, proxy):
394394
self.assertFalse(hasattr(o, 'foo'),
395395
"object does not reflect attribute removal via proxy")
396396

397-
# TODO: RUSTPYTHON
398-
@unittest.expectedFailure
399397
def test_proxy_deletion(self):
400398
# Test clearing of SF bug #762891
401399
class Foo:

vm/src/builtins/weakproxy.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use super::{PyStrRef, PyType, PyTypeRef, PyWeak};
22
use crate::{
33
class::PyClassImpl,
44
function::OptionalArg,
5-
protocol::{PySequence, PySequenceMethods},
6-
types::{AsSequence, Constructor, GetAttr, SetAttr},
5+
protocol::{PyMappingMethods, PySequence, PySequenceMethods},
6+
types::{AsMapping, AsSequence, Constructor, GetAttr, SetAttr},
77
Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
88
};
99

@@ -58,7 +58,7 @@ crate::common::static_cell! {
5858
static WEAK_SUBCLASS: PyTypeRef;
5959
}
6060

61-
#[pyimpl(with(GetAttr, SetAttr, Constructor, AsSequence))]
61+
#[pyimpl(with(GetAttr, SetAttr, Constructor, AsSequence, AsMapping))]
6262
impl PyWeakProxy {
6363
#[pymethod(magic)]
6464
fn str(&self, vm: &VirtualMachine) -> PyResult<PyStrRef> {
@@ -81,6 +81,32 @@ impl PyWeakProxy {
8181
None => Err(new_reference_error(vm)),
8282
}
8383
}
84+
85+
fn getitem(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
86+
match self.weak.upgrade() {
87+
Some(obj) => obj.get_item(&*needle, vm),
88+
None => Err(new_reference_error(vm)),
89+
}
90+
}
91+
92+
fn setitem(
93+
&self,
94+
needle: PyObjectRef,
95+
value: PyObjectRef,
96+
vm: &VirtualMachine,
97+
) -> PyResult<()> {
98+
match self.weak.upgrade() {
99+
Some(obj) => obj.set_item(&*needle, value, vm),
100+
None => Err(new_reference_error(vm)),
101+
}
102+
}
103+
104+
fn delitem(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
105+
match self.weak.upgrade() {
106+
Some(obj) => obj.del_item(&*needle, vm),
107+
None => Err(new_reference_error(vm)),
108+
}
109+
}
84110
}
85111

86112
fn new_reference_error(vm: &VirtualMachine) -> PyRef<super::PyBaseException> {
@@ -125,6 +151,23 @@ impl AsSequence for PyWeakProxy {
125151
};
126152
}
127153

154+
impl AsMapping for PyWeakProxy {
155+
const AS_MAPPING: PyMappingMethods = PyMappingMethods {
156+
length: Some(|mapping, vm| Self::mapping_downcast(mapping).len(vm)),
157+
subscript: Some(|mapping, needle, vm| {
158+
Self::mapping_downcast(mapping).getitem(needle.to_owned(), vm)
159+
}),
160+
ass_subscript: Some(|mapping, needle, value, vm| {
161+
let zelf = Self::mapping_downcast(mapping);
162+
if let Some(value) = value {
163+
zelf.setitem(needle.to_owned(), value, vm)
164+
} else {
165+
zelf.delitem(needle.to_owned(), vm)
166+
}
167+
}),
168+
};
169+
}
170+
128171
pub fn init(context: &Context) {
129172
PyWeakProxy::extend_class(context, context.types.weakproxy_type);
130173
}

0 commit comments

Comments
 (0)