static mp_obj_t dict_view_getiter(mp_obj_t view_in) { assert(MP_OBJ_IS_TYPE(view_in, &dict_view_type)); mp_obj_dict_view_t *view = view_in; mp_obj_dict_view_it_t *o = m_new_obj(mp_obj_dict_view_it_t); o->base.type = &dict_view_it_type; o->kind = view->kind; o->iter = mp_obj_new_dict_iterator(view->dict, 0); return o; }
STATIC mp_obj_t dict_update(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { assert(MP_OBJ_IS_TYPE(args[0], &mp_type_dict)); mp_obj_dict_t *self = args[0]; mp_arg_check_num(n_args, kwargs->used, 1, 2, true); if (n_args == 2) { // given a positional argument if (MP_OBJ_IS_TYPE(args[1], &mp_type_dict)) { // update from other dictionary (make sure other is not self) if (args[1] != self) { // TODO don't allocate heap object for this iterator mp_obj_t *dict_iter = mp_obj_new_dict_iterator(args[1], 0); mp_map_elem_t *elem = NULL; while ((elem = dict_it_iternext_elem(dict_iter)) != MP_OBJ_STOP_ITERATION) { mp_map_lookup(&self->map, elem->key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = elem->value; } } } else { // update from a generic iterable of pairs mp_obj_t iter = mp_getiter(args[1]); mp_obj_t next = NULL; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { mp_obj_t inneriter = mp_getiter(next); mp_obj_t key = mp_iternext(inneriter); mp_obj_t value = mp_iternext(inneriter); mp_obj_t stop = mp_iternext(inneriter); if (key == MP_OBJ_STOP_ITERATION || value == MP_OBJ_STOP_ITERATION || stop != MP_OBJ_STOP_ITERATION) { nlr_raise(mp_obj_new_exception_msg( &mp_type_ValueError, "dictionary update sequence has the wrong length")); } else { mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } } } } // update the dict with any keyword args for (mp_uint_t i = 0; i < kwargs->alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { mp_map_lookup(&self->map, kwargs->table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = kwargs->table[i].value; } } return mp_const_none; }
static mp_obj_t dict_popitem(mp_obj_t self_in) { assert(MP_OBJ_IS_TYPE(self_in, &dict_type)); mp_obj_dict_t *self = self_in; if (self->map.used == 0) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "popitem(): dictionary is empty")); } mp_obj_dict_it_t *iter = mp_obj_new_dict_iterator(self, 0); mp_map_elem_t *next = dict_it_iternext_elem(iter); self->map.used--; mp_obj_t items[] = {next->key, next->value}; next->key = NULL; next->value = NULL; mp_obj_t tuple = mp_obj_new_tuple(2, items); return tuple; }
static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_dict_t *self = self_in; bool first = true; print(env, "{"); mp_obj_t *dict_iter = mp_obj_new_dict_iterator(self, 0); mp_map_elem_t *next = NULL; while ((next = dict_it_iternext_elem(dict_iter)) != NULL) { if (!first) { print(env, ", "); } first = false; mp_obj_print_helper(print, env, next->key, PRINT_REPR); print(env, ": "); mp_obj_print_helper(print, env, next->value, PRINT_REPR); } print(env, "}"); }
static mp_obj_t dict_getiter(mp_obj_t o_in) { return mp_obj_new_dict_iterator(o_in, 0); }