From 42e45bd69491e56d4baa681eb34f13ca1c4bd1ba Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Tue, 10 Dec 2019 12:05:22 +0200 Subject: [PATCH] py/objobject: Add object.__delattr__ function. Similar to object.__setattr__. --- py/objobject.c | 18 ++++++++++++++++++ tests/basics/class_delattr_setattr.py | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/py/objobject.c b/py/objobject.c index ae8436bc88..fcf0390597 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -77,6 +77,23 @@ STATIC mp_obj_t object___setattr__(mp_obj_t self_in, mp_obj_t attr, mp_obj_t val return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_3(object___setattr___obj, object___setattr__); + +STATIC mp_obj_t object___delattr__(mp_obj_t self_in, mp_obj_t attr) { + if (!mp_obj_is_instance_type(mp_obj_get_type(MP_OBJ_TO_PTR(self_in)))) { + mp_raise_TypeError("arg must be user-type"); + } + + if (!mp_obj_is_str(attr)) { + mp_raise_TypeError(NULL); + } + + mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in); + if (mp_map_lookup(&self->members, attr, MP_MAP_LOOKUP_REMOVE_IF_FOUND) == NULL) { + mp_raise_msg(&mp_type_AttributeError, "no such attribute"); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(object___delattr___obj, object___delattr__); #endif STATIC const mp_rom_map_elem_t object_locals_dict_table[] = { @@ -88,6 +105,7 @@ STATIC const mp_rom_map_elem_t object_locals_dict_table[] = { #endif #if MICROPY_PY_DELATTR_SETATTR { MP_ROM_QSTR(MP_QSTR___setattr__), MP_ROM_PTR(&object___setattr___obj) }, + { MP_ROM_QSTR(MP_QSTR___delattr__), MP_ROM_PTR(&object___delattr___obj) }, #endif }; diff --git a/tests/basics/class_delattr_setattr.py b/tests/basics/class_delattr_setattr.py index 8fe1bb6fc1..3389c091ab 100644 --- a/tests/basics/class_delattr_setattr.py +++ b/tests/basics/class_delattr_setattr.py @@ -69,6 +69,9 @@ class C: def __setattr__(self, attr, value): print(attr, "=", value) + def __delattr__(self, attr): + print("del", attr) + c = C() c.a = 5 try: @@ -86,3 +89,25 @@ try: object.__setattr__(c, 5, 5) except TypeError: print("TypeError") + + +# test object.__delattr__ +del c.a +print(c.a) + +object.__delattr__(c, "a") +try: + print(c.a) +except AttributeError: + print("AttributeError") + +super(C, c).__delattr__("b") +try: + print(c.b) +except AttributeError: + print("AttributeError") + +try: + object.__delattr__(c, "c") +except AttributeError: + print("AttributeError")