Skip to content

Commit aa07162

Browse files
committed
Implement delattr for type object
Fixed: #1404
1 parent dccc22d commit aa07162

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

tests/snippets/attr.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ class A:
1010
assert hasattr(a, 'b')
1111
assert a.b == 10
1212

13+
a.c = 50
14+
assert hasattr(a, 'c')
15+
assert a.c == 50
16+
17+
# test delete attribute with del keyword
18+
del a.c
19+
with assert_raises(AttributeError):
20+
_ = a.c
21+
1322
# test override attribute
1423
setattr(a, 'b', 12)
1524
assert a.b == 12

vm/src/obj/objtype.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,23 @@ impl PyClassRef {
200200
Ok(())
201201
}
202202

203+
fn del_attr(self, attr_name: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
204+
if let Some(attr) = class_get_attr(&self.class(), attr_name.as_str()) {
205+
if let Some(ref descriptor) = class_get_attr(&attr.class(), "__delete__") {
206+
return vm
207+
.invoke(descriptor, vec![attr, self.into_object()])
208+
.map(|_| ());
209+
}
210+
}
211+
212+
if let Some(_) = class_get_attr(&self, attr_name.as_str()) {
213+
self.attributes.borrow_mut().remove(attr_name.as_str());
214+
Ok(())
215+
} else {
216+
Err(vm.new_attribute_error(attr_name.as_str().to_string()))
217+
}
218+
}
219+
203220
// This is used for class initialisation where the vm is not yet available.
204221
pub fn set_str_attr<V: Into<PyObjectRef>>(&self, attr_name: &str, value: V) {
205222
self.attributes
@@ -256,8 +273,8 @@ pub fn init(ctx: &PyContext) {
256273
"__prepare__" => ctx.new_rustfunc(PyClassRef::prepare),
257274
"__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
258275
"__setattr__" => ctx.new_rustfunc(PyClassRef::set_attr),
276+
"__delattr__" => ctx.new_rustfunc(PyClassRef::del_attr),
259277
"__subclasses__" => ctx.new_rustfunc(PyClassRef::subclasses),
260-
"__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
261278
"__instancecheck__" => ctx.new_rustfunc(PyClassRef::instance_check),
262279
"__subclasscheck__" => ctx.new_rustfunc(PyClassRef::subclass_check),
263280
"__doc__" => ctx.new_str(type_doc.to_string()),

0 commit comments

Comments
 (0)