8000 py/objtype: Add __dict__ attribute for class objects. · micropython/micropython@03ae3ec · GitHub
[go: up one dir, main page]

Skip to content

Commit 03ae3ec

Browse files
committed
py/objtype: Add __dict__ attribute for class objects.
1 parent f0e6ce0 commit 03ae3ec

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

py/objtype.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -587,17 +587,16 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
587587
}
588588
#if MICROPY_CPYTHON_COMPAT
589589
if (attr == MP_QSTR___dict__) {
590-
// Create a new dict with a copy of the instance's map items.
590+
// Returns a read-only dict of the instance members.
591+
// If the internal locals is not fixed, a copy will be created.
591592
// This creates, unlike CPython, a 'read-only' __dict__: modifying
592593
// it will not result in modifications to the actual instance members.
593-
mp_map_t *map = &self->members;
594-
mp_obj_t attr_dict = mp_obj_new_dict(map->used);
595-
for (size_t i = 0; i < map->alloc; ++i) {
596-
if (mp_map_slot_is_filled(map, i)) {
597-
mp_obj_dict_store(attr_dict, map->table[i].key, map->table[i].value);
598-
}
599-
}
600-
dest[0] = attr_dict;
594+
mp_obj_dict_t dict;
595+
dict.map = self->members;
596+
dict.base.type = &mp_type_dict;
597+
dest[0] = mp_obj_dict_copy(MP_OBJ_FROM_PTR(dict));
598+
dict = MP_OBJ_TO_PTR(dest[0]);
599+
dict->map.is_fixed = 1;
601600
return;
602601
}
603602
#endif
@@ -1015,7 +1014,16 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
10151014
}
10161015
#if MICROPY_CPYTHON_COMPAT
10171016
if (attr == MP_QSTR___dict__) {
1018-
dest[0] = mp_obj_dict_copy(MP_OBJ_FROM_PTR(self->locals_dict));
1017+
// Returns a read-only dict of the class attributes.
1018+
// If the internal locals is not fixed, a copy will be created.
1019+
mp_obj_dict_t *dict = MP_OBJ_FROM_PTR(self->locals_dict);
1020+
if (dict->map.is_fixed) {
1021+
dest[0] = dict;
1022+
} else {
1023+
dest[0] = mp_obj_dict_copy(dict);
1024+
dict = MP_OBJ_TO_PTR(dest[0]);
1025+
dict->map.is_fixed = 1;
1026+
}
10191027
return;
10201028
}
10211029
#endif

tests/basics/class_dict.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
class Foo:
3+
self.a = 1
4+
self.b = "bar"
5+
6+
if not hasattr(Foo, "__dict__"):
7+
print("SKIP")
8+
raise SystemExit
9+
10+
print(Foo.__dict__ == {'a': 1, 'b': 'bar'})

0 commit comments

Comments
 (0)
0