32
32
#include "py/runtime0.h"
33
33
#include "py/runtime.h"
34
34
#include "py/builtin.h"
35
+ #include "py/objtype.h"
36
+
37
+ #define MP_OBJ_IS_DICT_TYPE (o ) (MP_OBJ_IS_OBJ(o) && ((mp_obj_base_t*)o)->type->make_new == dict_make_new)
35
38
36
39
STATIC mp_obj_t dict_update (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kwargs );
37
40
@@ -58,6 +61,9 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
58
61
if (!(MICROPY_PY_UJSON && kind == PRINT_JSON )) {
59
62
kind = PRINT_REPR ;
60
63
}
64
+ if (MICROPY_PY_COLLECTIONS_ORDEREDDICT && self -> base .type != & mp_type_dict ) {
65
+ print (env , "%s(" , qstr_str (self -> base .type -> name ));
66
+ }
61
67
print (env , "{" );
62
68
mp_uint_t cur = 0 ;
63
69
mp_map_elem_t * next = NULL ;
@@ -71,11 +77,19 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
71
77
mp_obj_print_helper (print , env , next -> value , kind );
72
78
}
73
79
print (env , "}" );
80
+ if (MICROPY_PY_COLLECTIONS_ORDEREDDICT && self -> base .type != & mp_type_dict ) {
81
+ print (env , ")" );
82
+ }
74
83
}
75
84
76
85
STATIC mp_obj_t dict_make_new (mp_obj_t type_in , mp_uint_t n_args , mp_uint_t n_kw , const mp_obj_t * args ) {
77
- (void )type_in ;
78
- mp_obj_t dict = mp_obj_new_dict (0 );
86
+ mp_obj_dict_t * dict = mp_obj_new_dict (0 );
87
+ dict -> base .type = type_in ;
88
+ #if MICROPY_PY_COLLECTIONS_ORDEREDDICT
89
+ if (type_in == & mp_type_ordereddict ) {
90
+ dict -> map .is_ordered = 1 ;
91
+ }
92
+ #endif
79
93
if (n_args > 0 || n_kw > 0 ) {
80
94
mp_obj_t args2 [2 ] = {dict , args [0 ]}; // args[0] is always valid, even if it's not a positional arg
81
95
mp_map_t kwargs ;
@@ -102,6 +116,12 @@ STATIC mp_obj_t dict_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
102
116
return MP_BOOL (elem != NULL );
103
117
}
104
118
case MP_BINARY_OP_EQUAL : {
119
+ #if MICROPY_PY_COLLECTIONS_ORDEREDDICT
120
+ if (MP_UNLIKELY (MP_OBJ_IS_TYPE (lhs_in , & mp_type_ordereddict ) && MP_OBJ_IS_TYPE (rhs_in , & mp_type_ordereddict ))) {
121
+ //TODO: implement
122
+ return MP_OBJ_NULL ;
123
+ } else
124
+ #endif
105
125
if (MP_OBJ_IS_TYPE (rhs_in , & mp_type_dict )) {
106
126
mp_obj_dict_t * rhs = rhs_in ;
107
127
if (o -> map .used != rhs -> map .used ) {
@@ -199,7 +219,7 @@ STATIC mp_obj_t dict_getiter(mp_obj_t o_in) {
199
219
/* dict methods */
200
220
201
221
STATIC mp_obj_t dict_clear (mp_obj_t self_in ) {
202
- assert (MP_OBJ_IS_TYPE (self_in , & mp_type_dict ));
222
+ assert (MP_OBJ_IS_DICT_TYPE (self_in ));
203
223
mp_obj_dict_t * self = self_in ;
204
224
205
225
mp_map_clear (& self -> map );
@@ -209,12 +229,14 @@ STATIC mp_obj_t dict_clear(mp_obj_t self_in) {
209
229
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (dict_clear_obj , dict_clear );
210
230
211
231
STATIC mp_obj_t dict_copy (mp_obj_t self_in ) {
212
- assert (MP_OBJ_IS_TYPE (self_in , & mp_type_dict ));
232
+ assert (MP_OBJ_IS_DICT_TYPE (self_in ));
213
233
mp_obj_dict_t * self = self_in ;
214
234
mp_obj_dict_t * other = mp_obj_new_dict (self -> map .alloc );
235
+ other -> base .type = self -> base .type ;
215
236
other -> map .used = self -> map .used ;
216
237
other -> map .all_keys_are_qstrs = self -> map .all_keys_are_qstrs ;
217
- other -> map .table_is_fixed_array = 0 ;
238
+ other -> map .is_fixed = 0 ;
239
+ other -> map .is_ordered = self -> map .is_ordered ;
218
240
memcpy (other -> map .table , self -> map .table , self -> map .alloc * sizeof (mp_map_elem_t ));
219
241
return other ;
220
242
}
@@ -276,7 +298,7 @@ STATIC mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp
276
298
277
299
STATIC mp_obj_t dict_get (mp_uint_t n_args , const mp_obj_t * args ) {
278
300
assert (2 <= n_args && n_args <= 3 );
279
- assert (MP_OBJ_IS_TYPE (args [0 ], & mp_type_dict ));
301
+ assert (MP_OBJ_IS_DICT_TYPE (args [0 ]));
280
302
281
303
return dict_get_helper (& ((mp_obj_dict_t * )args [0 ])-> map ,
282
304
args [1 ],
@@ -287,7 +309,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_get_obj, 2, 3, dict_get);
287
309
288
310
STATIC mp_obj_t dict_pop (mp_uint_t n_args , const mp_obj_t * args ) {
289
311
assert (2 <= n_args && n_args <= 3 );
290
- assert (MP_OBJ_IS_TYPE (args [0 ], & mp_type_dict ));
312
+ assert (MP_OBJ_IS_DICT_TYPE (args [0 ]));
291
313
292
314
return dict_get_helper (& ((mp_obj_dict_t * )args [0 ])-> map ,
293
315
args [1 ],
@@ -299,7 +321,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_pop_obj, 2, 3, dict_pop);
299
321
300
322
STATIC mp_obj_t dict_setdefault (mp_uint_t n_args , const mp_obj_t * args ) {
301
323
assert (2 <= n_args && n_args <= 3 );
302
- assert (MP_OBJ_IS_TYPE (args [0 ], & mp_type_dict ));
324
+ assert (MP_OBJ_IS_DICT_TYPE (args [0 ]));
303
325
304
326
return dict_get_helper (& ((mp_obj_dict_t * )args [0 ])-> map ,
305
327
args [1 ],
@@ -310,7 +332,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_setdefault_obj, 2, 3, dict_setde
310
332
311
333
312
334
STATIC mp_obj_t dict_popitem (mp_obj_t self_in ) {
313
- assert (MP_OBJ_IS_TYPE (self_in , & mp_type_dict ));
335
+ assert (MP_OBJ_IS_DICT_TYPE (self_in ));
314
336
mp_obj_dict_t * self = self_in ;
315
337
mp_uint_t cur = 0 ;
316
338
mp_map_elem_t * next = dict_iter_next (self , & cur );
@@ -328,15 +350,15 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) {
328
350
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (dict_popitem_obj , dict_popitem );
329
351
330
352
STATIC mp_obj_t dict_update (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kwargs ) {
331
- assert (MP_OBJ_IS_TYPE (args [0 ], & mp_type_dict ));
353
+ assert (MP_OBJ_IS_DICT_TYPE (args [0 ]));
332
354
mp_obj_dict_t * self = args [0 ];
333
355
334
356
mp_arg_check_num (n_args , kwargs -> used , 1 , 2 , true);
335
357
336
358
if (n_args == 2 ) {
337
359
// given a positional argument
338
360
339
- if (MP_OBJ_IS_TYPE (args [1 ], & mp_type_dict )) {
361
+ if (MP_OBJ_IS_DICT_TYPE (args [1 ])) {
340
362
// update from other dictionary (make sure other is not self)
341
363
if (args [1 ] != self ) {
342
364
mp_uint_t cur = 0 ;
@@ -494,7 +516,7 @@ STATIC mp_obj_t mp_obj_new_dict_view(mp_obj_dict_t *dict, mp_dict_view_kind_t ki
494
516
}
495
517
496
518
STATIC mp_obj_t dict_view (mp_obj_t self_in , mp_dict_view_kind_t kind ) {
497
- assert (MP_OBJ_IS_TYPE (self_in , & mp_type_dict ));
519
+ assert (MP_OBJ_IS_DICT_TYPE (self_in ));
498
520
mp_obj_dict_t * self = self_in ;
499
521
return mp_obj_new_dict_view (self , kind );
500
522
}
@@ -548,6 +570,23 @@ const mp_obj_type_t mp_type_dict = {
548
570
.locals_dict = (mp_obj_t )& dict_locals_dict ,
549
571
};
550
572
573
+ #if MICROPY_PY_COLLECTIONS_ORDEREDDICT
574
+ STATIC const mp_obj_tuple_t ordereddict_base_tuple = {{& mp_type_tuple }, 1 , {(mp_obj_t )& mp_type_dict }};
575
+
576
+ const mp_obj_type_t mp_type_ordereddict = {
577
+ { & mp_type_type },
578
+ .name = MP_QSTR_OrderedDict ,
579
+ .print = dict_print ,
580
+ .make_new = dict_make_new ,
581
+ .unary_op = dict_unary_op ,
582
+ .binary_op = dict_binary_op ,
583
+ .subscr = dict_subscr ,
584
+ .getiter = dict_getiter ,
585
+ .bases_tuple = (mp_obj_t )& ordereddict_base_tuple ,
586
+ .locals_dict = (mp_obj_t )& dict_locals_dict ,
587
+ };
588
+ #endif
589
+
551
590
void mp_obj_dict_init (mp_obj_dict_t * dict , mp_uint_t n_args ) {
552
591
dict -> base .type = & mp_type_dict ;
553
592
mp_map_init (& dict -> map , n_args );
@@ -564,21 +603,21 @@ mp_uint_t mp_obj_dict_len(mp_obj_t self_in) {
564
603
}
565
604
566
605
mp_obj_t mp_obj_dict_store (mp_obj_t self_in , mp_obj_t key , mp_obj_t value ) {
567
- assert (MP_OBJ_IS_TYPE (self_in , & mp_type_dict ));
606
+ assert (MP_OBJ_IS_DICT_TYPE (self_in ));
568
607
mp_obj_dict_t * self = self_in ;
569
608
mp_map_lookup (& self -> map , key , MP_MAP_LOOKUP_ADD_IF_NOT_FOUND )-> value = value ;
570
609
return self_in ;
571
610
}
572
611
573
612
mp_obj_t mp_obj_dict_delete (mp_obj_t self_in , mp_obj_t key ) {
574
- assert (MP_OBJ_IS_TYPE (self_in , & mp_type_dict ));
613
+ assert (MP_OBJ_IS_DICT_TYPE (self_in ));
575
614
mp_obj_dict_t * self = self_in ;
576
615
dict_get_helper (& self -> map , key , MP_OBJ_NULL , MP_MAP_LOOKUP_REMOVE_IF_FOUND );
577
616
return self_in ;
578
617
}
579
618
580
619
mp_map_t * mp_obj_dict_get_map (mp_obj_t self_in ) {
581
- assert (MP_OBJ_IS_TYPE (self_in , & mp_type_dict ));
620
+ assert (MP_OBJ_IS_DICT_TYPE (self_in ));
582
621
mp_obj_dict_t * self = self_in ;
583
622
return & self -> map ;
584
623
}
0 commit comments