@@ -49,6 +49,22 @@ const mp_obj_dict_t mp_const_empty_dict_obj = {
49
49
}
50
50
};
51
51
52
+ // CIRCUITPY-CHANGE: Native methods are passed the subclass instance so they can
53
+ // refer to subclass members. Dict only cares about the native struct so this
54
+ // function gets it.
55
+ STATIC mp_obj_dict_t * native_dict (mp_obj_t self_in ) {
56
+ // Check for OrderedDict first because it is marked as a subclass of dict. However, it doesn't
57
+ // store its state in subobj like python types to native types do.
58
+ mp_obj_t native_instance = MP_OBJ_NULL ;
59
+ #if MICROPY_PY_COLLECTIONS_ORDEREDDICT
60
+ native_instance = mp_obj_cast_to_native_base (self_in , MP_OBJ_FROM_PTR (& mp_type_ordereddict ));
61
+ #endif
62
+ if (native_instance == MP_OBJ_NULL ) {
63
+ native_instance = mp_obj_cast_to_native_base (self_in , MP_OBJ_FROM_PTR (& mp_type_dict ));
64
+ }
65
+ return MP_OBJ_TO_PTR (native_instance );
66
+ }
67
+
52
68
STATIC mp_obj_t dict_update (size_t n_args , const mp_obj_t * args , mp_map_t * kwargs );
53
69
54
70
// This is a helper function to iterate through a dictionary. The state of
@@ -71,7 +87,7 @@ STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, size_t *cur) {
71
87
}
72
88
73
89
STATIC void dict_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
74
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
90
+ mp_obj_dict_t * self = native_dict (self_in );
75
91
bool first = true;
76
92
const char * item_separator = ", " ;
77
93
const char * key_separator = ": " ;
@@ -144,7 +160,7 @@ mp_obj_t mp_obj_dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
144
160
}
145
161
146
162
STATIC mp_obj_t dict_unary_op (mp_unary_op_t op , mp_obj_t self_in ) {
147
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
163
+ mp_obj_dict_t * self = native_dict (self_in );
148
164
switch (op ) {
149
165
case MP_UNARY_OP_BOOL :
150
166
return mp_obj_new_bool (self -> map .used != 0 );
@@ -162,7 +178,7 @@ STATIC mp_obj_t dict_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
162
178
}
163
179
164
180
STATIC mp_obj_t dict_binary_op (mp_binary_op_t op , mp_obj_t lhs_in , mp_obj_t rhs_in ) {
165
- mp_obj_dict_t * o = MP_OBJ_TO_PTR (lhs_in );
181
+ mp_obj_dict_t * o = native_dict (lhs_in );
166
182
switch (op ) {
167
183
case MP_BINARY_OP_CONTAINS : {
168
184
mp_map_elem_t * elem = mp_map_lookup (& o -> map , rhs_in , MP_MAP_LOOKUP );
@@ -223,7 +239,7 @@ STATIC mp_obj_t dict_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_
223
239
224
240
// Note: Make sure this is inlined in load part of dict_subscr() below.
225
241
mp_obj_t mp_obj_dict_get (mp_obj_t self_in , mp_obj_t index ) {
226
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
242
+ mp_obj_dict_t * self = native_dict (self_in );
227
243
mp_map_elem_t * elem = mp_map_lookup (& self -> map , index , MP_MAP_LOOKUP );
228
244
if (elem == NULL ) {
229
245
mp_raise_type_arg (& mp_type_KeyError , index );
@@ -239,7 +255,7 @@ STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
239
255
return mp_const_none ;
240
256
} else if (value == MP_OBJ_SENTINEL ) {
241
257
// load
242
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
258
+ mp_obj_dict_t * self = native_dict (self_in );
243
259
mp_map_elem_t * elem = mp_map_lookup (& self -> map , index , MP_MAP_LOOKUP );
244
260
if (elem == NULL ) {
245
261
mp_raise_type_arg (& mp_type_KeyError , index );
@@ -264,7 +280,7 @@ STATIC void PLACE_IN_ITCM(mp_ensure_not_fixed)(const mp_obj_dict_t * dict) {
264
280
265
281
STATIC mp_obj_t dict_clear (mp_obj_t self_in ) {
266
282
mp_check_self (mp_obj_is_dict_or_ordereddict (self_in ));
267
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
283
+ mp_obj_dict_t * self = native_dict (self_in );
268
284
mp_ensure_not_fixed (self );
269
285
270
286
mp_map_clear (& self -> map );
@@ -275,9 +291,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_clear_obj, dict_clear);
275
291
276
292
mp_obj_t mp_obj_dict_copy (mp_obj_t self_in ) {
277
293
mp_check_self (mp_obj_is_dict_or_ordereddict (self_in ));
278
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
294
+ mp_obj_dict_t * self = native_dict (self_in );
279
295
mp_obj_t other_out = mp_obj_new_dict (self -> map .alloc );
280
- mp_obj_dict_t * other = MP_OBJ_TO_PTR (other_out );
296
+ mp_obj_dict_t * other = native_dict (other_out );
281
297
other -> base .type = self -> base .type ;
282
298
other -> map .used = self -> map .used ;
283
299
other -> map .all_keys_are_qstrs = self -> map .all_keys_are_qstrs ;
@@ -324,7 +340,7 @@ STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(dict_fromkeys_obj, MP_ROM_PTR(&dict_fromk
324
340
325
341
STATIC mp_obj_t dict_get_helper (size_t n_args , const mp_obj_t * args , mp_map_lookup_kind_t lookup_kind ) {
326
342
mp_check_self (mp_obj_is_dict_or_ordereddict (args [0 ]));
327
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (args [0 ]);
343
+ mp_obj_dict_t * self = native_dict (args [0 ]);
328
344
if (lookup_kind != MP_MAP_LOOKUP ) {
329
345
mp_ensure_not_fixed (self );
330
346
}
@@ -369,7 +385,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_setdefault_obj, 2, 3, dict_setde
369
385
370
386
STATIC mp_obj_t dict_popitem (mp_obj_t self_in ) {
371
387
mp_check_self (mp_obj_is_dict_or_ordereddict (self_in ));
372
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
388
+ mp_obj_dict_t * self = native_dict (self_in );
373
389
mp_ensure_not_fixed (self );
374
390
if (self -> map .used == 0 ) {
375
391
mp_raise_msg_varg (& mp_type_KeyError , MP_ERROR_TEXT ("pop from empty %q" ), MP_QSTR_dict );
@@ -394,7 +410,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_popitem_obj, dict_popitem);
394
410
395
411
STATIC mp_obj_t dict_update (size_t n_args , const mp_obj_t * args , mp_map_t * kwargs ) {
396
412
mp_check_self (mp_obj_is_dict_or_ordereddict (args [0 ]));
397
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (args [0 ]);
413
+ mp_obj_dict_t * self = native_dict (args [0 ]);
398
414
mp_ensure_not_fixed (self );
399
415
400
416
mp_arg_check_num (n_args , kwargs -> used , 1 , 2 , true);
@@ -726,7 +742,7 @@ size_t mp_obj_dict_len(mp_obj_t self_in) {
726
742
727
743
mp_obj_t mp_obj_dict_store (mp_obj_t self_in , mp_obj_t key , mp_obj_t value ) {
728
744
mp_check_self (mp_obj_is_dict_or_ordereddict (self_in ));
729
- mp_obj_dict_t * self = MP_OBJ_TO_PTR (self_in );
745
+ mp_obj_dict_t * self = native_dict (self_in );
730
746
mp_ensure_not_fixed (self );
731
747
mp_map_lookup (& self -> map , key , MP_MAP_LOOKUP_ADD_IF_NOT_FOUND )-> value = value ;
732
748
return self_in ;
0 commit comments