3232#include "py/runtime0.h"
3333#include "py/runtime.h"
3434#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)
3538
3639STATIC mp_obj_t dict_update (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kwargs );
3740
@@ -58,6 +61,9 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
5861 if (!(MICROPY_PY_UJSON && kind == PRINT_JSON )) {
5962 kind = PRINT_REPR ;
6063 }
64+ if (MICROPY_PY_COLLECTIONS_ORDEREDDICT && self -> base .type != & mp_type_dict ) {
65+ print (env , "%s(" , qstr_str (self -> base .type -> name ));
66+ }
6167 print (env , "{" );
6268 mp_uint_t cur = 0 ;
6369 mp_map_elem_t * next = NULL ;
@@ -71,11 +77,19 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
7177 mp_obj_print_helper (print , env , next -> value , kind );
7278 }
7379 print (env , "}" );
80+ if (MICROPY_PY_COLLECTIONS_ORDEREDDICT && self -> base .type != & mp_type_dict ) {
81+ print (env , ")" );
82+ }
7483}
7584
7685STATIC 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
7993 if (n_args > 0 || n_kw > 0 ) {
8094 mp_obj_t args2 [2 ] = {dict , args [0 ]}; // args[0] is always valid, even if it's not a positional arg
8195 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) {
102116 return MP_BOOL (elem != NULL );
103117 }
104118 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
105125 if (MP_OBJ_IS_TYPE (rhs_in , & mp_type_dict )) {
106126 mp_obj_dict_t * rhs = rhs_in ;
107127 if (o -> map .used != rhs -> map .used ) {
@@ -199,7 +219,7 @@ STATIC mp_obj_t dict_getiter(mp_obj_t o_in) {
199219/* dict methods */
200220
201221STATIC 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 ));
203223 mp_obj_dict_t * self = self_in ;
204224
205225 mp_map_clear (& self -> map );
@@ -209,12 +229,14 @@ STATIC mp_obj_t dict_clear(mp_obj_t self_in) {
209229STATIC MP_DEFINE_CONST_FUN_OBJ_1 (dict_clear_obj , dict_clear );
210230
211231STATIC 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 ));
213233 mp_obj_dict_t * self = self_in ;
214234 mp_obj_dict_t * other = mp_obj_new_dict (self -> map .alloc );
235+ other -> base .type = self -> base .type ;
215236 other -> map .used = self -> map .used ;
216237 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 ;
218240 memcpy (other -> map .table , self -> map .table , self -> map .alloc * sizeof (mp_map_elem_t ));
219241 return other ;
220242}
@@ -276,7 +298,7 @@ STATIC mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp
276298
277299STATIC mp_obj_t dict_get (mp_uint_t n_args , const mp_obj_t * args ) {
278300 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 ]));
280302
281303 return dict_get_helper (& ((mp_obj_dict_t * )args [0 ])-> map ,
282304 args [1 ],
@@ -287,7 +309,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_get_obj, 2, 3, dict_get);
287309
288310STATIC mp_obj_t dict_pop (mp_uint_t n_args , const mp_obj_t * args ) {
289311 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 ]));
291313
292314 return dict_get_helper (& ((mp_obj_dict_t * )args [0 ])-> map ,
293315 args [1 ],
@@ -299,7 +321,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_pop_obj, 2, 3, dict_pop);
299321
300322STATIC mp_obj_t dict_setdefault (mp_uint_t n_args , const mp_obj_t * args ) {
301323 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 ]));
303325
304326 return dict_get_helper (& ((mp_obj_dict_t * )args [0 ])-> map ,
305327 args [1 ],
@@ -310,7 +332,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_setdefault_obj, 2, 3, dict_setde
310332
311333
312334STATIC 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 ));
314336 mp_obj_dict_t * self = self_in ;
315337 mp_uint_t cur = 0 ;
316338 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) {
328350STATIC MP_DEFINE_CONST_FUN_OBJ_1 (dict_popitem_obj , dict_popitem );
329351
330352STATIC 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 ]));
332354 mp_obj_dict_t * self = args [0 ];
333355
334356 mp_arg_check_num (n_args , kwargs -> used , 1 , 2 , true);
335357
336358 if (n_args == 2 ) {
337359 // given a positional argument
338360
339- if (MP_OBJ_IS_TYPE (args [1 ], & mp_type_dict )) {
361+ if (MP_OBJ_IS_DICT_TYPE (args [1 ])) {
340362 // update from other dictionary (make sure other is not self)
341363 if (args [1 ] != self ) {
342364 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
494516}
495517
496518STATIC 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 ));
498520 mp_obj_dict_t * self = self_in ;
499521 return mp_obj_new_dict_view (self , kind );
500522}
@@ -548,6 +570,23 @@ const mp_obj_type_t mp_type_dict = {
548570 .locals_dict = (mp_obj_t )& dict_locals_dict ,
549571};
550572
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+
551590void mp_obj_dict_init (mp_obj_dict_t * dict , mp_uint_t n_args ) {
552591 dict -> base .type = & mp_type_dict ;
553592 mp_map_init (& dict -> map , n_args );
@@ -564,21 +603,21 @@ mp_uint_t mp_obj_dict_len(mp_obj_t self_in) {
564603}
565604
566605mp_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 ));
568607 mp_obj_dict_t * self = self_in ;
569608 mp_map_lookup (& self -> map , key , MP_MAP_LOOKUP_ADD_IF_NOT_FOUND )-> value = value ;
570609 return self_in ;
571610}
572611
573612mp_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 ));
575614 mp_obj_dict_t * self = self_in ;
576615 dict_get_helper (& self -> map , key , MP_OBJ_NULL , MP_MAP_LOOKUP_REMOVE_IF_FOUND );
577616 return self_in ;
578617}
579618
580619mp_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 ));
582621 mp_obj_dict_t * self = self_in ;
583622 return & self -> map ;
584623}
0 commit comments