Skip to content

Commit cb14655

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

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

py/objtype.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -587,17 +587,20 @@ 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-
}
594+
mp_obj_t members_dict = mp_obj_new_dict(0);
595+
mp_obj_dict_t *dict = MP_OBJ_TO_PTR(members_dict);
596+
dict->map = self->members;
597+
if (dict->map.is_fixed) {
598+
dest[0] = dict;
599+
} else {
600+
dest[0] = mp_obj_dict_copy(MP_OBJ_FROM_PTR(dict));
601+
dict = MP_OBJ_TO_PTR(dest[0]);
602+
dict->map.is_fixed = 1;
599603
}
600-
dest[0] = attr_dict;
601604
return;
602605
}
603606
#endif
@@ -1015,7 +1018,16 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
10151018
}
10161019
#if MICROPY_CPYTHON_COMPAT
10171020
if (attr == MP_QSTR___dict__) {
1018-
dest[0] = mp_obj_dict_copy(MP_OBJ_FROM_PTR(self->locals_dict));
1021+
// Returns a read-only dict of the class attributes.
1022+
// If the internal locals is not fixed, a copy will be created.
1023+
mp_obj_dict_t *dict = MP_OBJ_FROM_PTR(self->locals_dict);
1024+
if (dict->map.is_fixed) {
1025+
dest[0] = dict;
1026+
} else {
1027+
dest[0] = mp_obj_dict_copy(dict);
1028+
dict = MP_OBJ_TO_PTR(dest[0]);
1029+
dict->map.is_fixed = 1;
1030+
}
10191031
return;
10201032
}
10211033
#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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy