diff --git a/py/objtype.c b/py/objtype.c index db99d407acfcd..b1fc347579b48 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -472,7 +472,22 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des dest[0] = elem->value; return; } - +#if MICROPY_CPYTHON_COMPAT + if (attr == MP_QSTR___dict__) { + // Create a new dict with a copy of the instance's map items. + // This creates, unlike CPython, a 'read-only' __dict__: modifying + // it will not result in modifications to the actual instance members. + mp_map_t *map = &(self->members); + mp_obj_t attr_dict = mp_obj_new_dict(0); + for (mp_uint_t i = 0; i < map->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(map, i)) { + mp_obj_dict_store(attr_dict, map->table[i].key, map->table[i].value); + } + } + dest[0] = attr_dict; + return; + } +#endif struct class_lookup_data lookup = { .obj = self, .attr = attr, diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 483c7537747c6..5efa9aa3bace3 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -46,6 +46,7 @@ Q(__locals__) Q(__main__) Q(__module__) Q(__name__) +Q(__dict__) Q(__hash__) Q(__next__) Q(__qualname__) diff --git a/tests/basics/builtin_dict.py b/tests/basics/builtin_dict.py new file mode 100644 index 0000000000000..f51ec21d007ae --- /dev/null +++ b/tests/basics/builtin_dict.py @@ -0,0 +1,11 @@ +class A: + def __init__(self): + self.a=1 + self.b=2 + +try: + d=A().__dict__ + print(d['a']) + print(d['b']) +except AttributeError: + print("SKIP")
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: