@@ -714,13 +714,18 @@ void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const
714714 }
715715 }
716716 } else {
717- // generic mapping
718- // TODO is calling 'items' on the mapping the correct thing to do here?
719- mp_obj_t dest [2 ];
720- mp_load_method (kw_dict , MP_QSTR_items , dest );
717+ // generic mapping:
718+ // - call keys() to get an iterable of all keys in the mapping
719+ // - call __getitem__ for each key to get the corresponding value
720+
721+ // get the keys iterable
722+ mp_obj_t dest [3 ];
723+ mp_load_method (kw_dict , MP_QSTR_keys , dest );
721724 mp_obj_t iterable = mp_getiter (mp_call_method_n_kw (0 , 0 , dest ));
722- mp_obj_t item ;
723- while ((item = mp_iternext (iterable )) != MP_OBJ_STOP_ITERATION ) {
725+
726+ mp_obj_t key ;
727+ while ((key = mp_iternext (iterable )) != MP_OBJ_STOP_ITERATION ) {
728+ // expand size of args array if needed
724729 if (args2_len + 1 >= args2_alloc ) {
725730 uint new_alloc = args2_alloc * 2 ;
726731 if (new_alloc < 4 ) {
@@ -729,15 +734,20 @@ void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const
729734 args2 = m_renew (mp_obj_t , args2 , args2_alloc , new_alloc );
730735 args2_alloc = new_alloc ;
731736 }
732- mp_obj_t * items ;
733- mp_obj_get_array_fixed_n (item , 2 , & items );
737+
734738 // the key must be a qstr, so intern it if it's a string
735- mp_obj_t key = items [0 ];
736739 if (MP_OBJ_IS_TYPE (key , & mp_type_str )) {
737740 key = mp_obj_str_intern (key );
738741 }
742+
743+ // get the value corresponding to the key
744+ mp_load_method (kw_dict , MP_QSTR___getitem__ , dest );
745+ dest [2 ] = key ;
746+ mp_obj_t value = mp_call_method_n_kw (1 , 0 , dest );
747+
748+ // store the key/value pair in the argument array
739749 args2 [args2_len ++ ] = key ;
740- args2 [args2_len ++ ] = items [ 1 ] ;
750+ args2 [args2_len ++ ] = value ;
741751 }
742752 }
743753
0 commit comments