@@ -533,6 +533,15 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
533533
534534 // try __getattr__
535535 if (attr != MP_QSTR___getattr__ ) {
536+ #if MICROPY_PY_DELATTR_SETATTR
537+ // If the requested attr is __setattr__/__delattr__ then don't delegate the lookup
538+ // to __getattr__. If we followed CPython's behaviour then __setattr__/__delattr__
539+ // would have already been found in the "object" base class.
540+ if (attr == MP_QSTR___setattr__ || attr == MP_QSTR___delattr__ ) {
541+ return ;
542+ }
543+ #endif
544+
536545 mp_obj_t dest2 [3 ];
537546 mp_load_method_maybe (self_in , MP_QSTR___getattr__ , dest2 );
538547 if (dest2 [0 ] != MP_OBJ_NULL ) {
@@ -626,10 +635,35 @@ STATIC bool mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t val
626635
627636 if (value == MP_OBJ_NULL ) {
628637 // delete attribute
638+ #if MICROPY_PY_DELATTR_SETATTR
639+ // try __delattr__ first
640+ mp_obj_t attr_delattr_method [3 ];
641+ mp_load_method_maybe (self_in , MP_QSTR___delattr__ , attr_delattr_method );
642+ if (attr_delattr_method [0 ] != MP_OBJ_NULL ) {
643+ // __delattr__ exists, so call it
644+ attr_delattr_method [2 ] = MP_OBJ_NEW_QSTR (attr );
645+ mp_call_method_n_kw (1 , 0 , attr_delattr_method );
646+ return true;
647+ }
648+ #endif
649+
629650 mp_map_elem_t * elem = mp_map_lookup (& self -> members , MP_OBJ_NEW_QSTR (attr ), MP_MAP_LOOKUP_REMOVE_IF_FOUND );
630651 return elem != NULL ;
631652 } else {
632653 // store attribute
654+ #if MICROPY_PY_DELATTR_SETATTR
655+ // try __setattr__ first
656+ mp_obj_t attr_setattr_method [4 ];
657+ mp_load_method_maybe (self_in , MP_QSTR___setattr__ , attr_setattr_method );
658+ if (attr_setattr_method [0 ] != MP_OBJ_NULL ) {
659+ // __setattr__ exists, so call it
660+ attr_setattr_method [2 ] = MP_OBJ_NEW_QSTR (attr );
661+ attr_setattr_method [3 ] = value ;
662+ mp_call_method_n_kw (2 , 0 , attr_setattr_method );
663+ return true;
664+ }
665+ #endif
666+
633667 mp_map_lookup (& self -> members , MP_OBJ_NEW_QSTR (attr ), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND )-> value = value ;
634668 return true;
635669 }
0 commit comments