Implement delattr for type object

Fixed: #1404
This commit is contained in:
MinJeong Kim committed 2019-10-10 04:24:55 +00:00
1 parent dccc22dbb9
commit 37a3b2c8f0
2 files changed
+27 -1

No files matched your search

+9
View File
@@ -4,12 +4,21 @@ from testutils import assert_raises
class A:
pass
class B:
x = 50
a = A()
a.b = 10
assert hasattr(a, 'b')
assert a.b == 10
assert B.x == 50
# test delete class attribute with del keyword
del B.x
with assert_raises(AttributeError):
_ = B.x
# test override attribute
setattr(a, 'b', 12)
assert a.b == 12
+18 -1
View File
@@ -200,6 +200,23 @@ impl PyClassRef {
Ok(())
}
fn del_attr(self, attr_name: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
if let Some(attr) = class_get_attr(&self.class(), attr_name.as_str()) {
if let Some(ref descriptor) = class_get_attr(&attr.class(), "__delete__") {
return vm
.invoke(descriptor, vec![attr, self.into_object()])
.map(|_| ());
}
}
if class_get_attr(&self, attr_name.as_str()).is_some() {
self.attributes.borrow_mut().remove(attr_name.as_str());
Ok(())
} else {
Err(vm.new_attribute_error(attr_name.as_str().to_string()))
}
}
// This is used for class initialisation where the vm is not yet available.
pub fn set_str_attr<V: Into<PyObjectRef>>(&self, attr_name: &str, value: V) {
self.attributes
@@ -256,8 +273,8 @@ pub fn init(ctx: &PyContext) {
"__prepare__" => ctx.new_rustfunc(PyClassRef::prepare),
"__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
"__setattr__" => ctx.new_rustfunc(PyClassRef::set_attr),
"__delattr__" => ctx.new_rustfunc(PyClassRef::del_attr),
"__subclasses__" => ctx.new_rustfunc(PyClassRef::subclasses),
"__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
"__instancecheck__" => ctx.new_rustfunc(PyClassRef::instance_check),
"__subclasscheck__" => ctx.new_rustfunc(PyClassRef::subclass_check),
"__doc__" => ctx.new_str(type_doc.to_string()),