added a first pass of dict.update

This commit is contained in:
John R. Lenton 2014-01-06 22:58:17 +00:00
parent e3096172c9
commit 88f3043e0a
2 changed files with 30 additions and 3 deletions

View File

@ -157,7 +157,7 @@ static mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, bo
value = elem->value;
if (pop) {
/* catch the leak (from mp_map_lookup_helper) */
m_free(elem, 2 * sizeof(mp_obj_t));
m_free(elem, sizeof(mp_map_elem_t));
}
}
if (set) {
@ -220,6 +220,32 @@ static mp_obj_t dict_popitem(mp_obj_t self_in) {
}
static MP_DEFINE_CONST_FUN_OBJ_1(dict_popitem_obj, dict_popitem);
static mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) {
assert(MP_OBJ_IS_TYPE(self_in, &dict_type));
mp_obj_dict_t *self = self_in;
/* TODO: check for the "keys" method */
mp_obj_t iter = rt_getiter(iterable);
mp_obj_t next = NULL;
while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
mp_obj_t inneriter = rt_getiter(next);
mp_obj_t key = rt_iternext(inneriter);
mp_obj_t value = rt_iternext(inneriter);
mp_obj_t stop = rt_iternext(inneriter);
if (key == mp_const_stop_iteration
|| value == mp_const_stop_iteration
|| stop != mp_const_stop_iteration) {
nlr_jump(mp_obj_new_exception_msg(
MP_QSTR_ValueError,
"dictionary update sequence has the wrong length"));
} else {
mp_map_lookup_helper(&self->map, key, true, false)->value = value;
}
}
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_2(dict_update_obj, dict_update);
/******************************************************************************/
/* dict constructors & etc */
@ -238,6 +264,7 @@ const mp_obj_type_t dict_type = {
{ "pop", &dict_pop_obj },
{ "popitem", &dict_popitem_obj },
{ "setdefault", &dict_setdefault_obj },
{ "update", &dict_update_obj },
{ NULL, NULL }, // end-of-list sentinel
},
};

View File

@ -859,13 +859,13 @@ mp_obj_t rt_getiter(mp_obj_t o_in) {
mp_obj_t rt_iternext(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) {
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "? 'int' object is not iterable"));
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "'int' object is not an iterator"));
} else {
mp_obj_base_t *o = o_in;
if (o->type->iternext != NULL) {
return o->type->iternext(o_in);
} else {
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "? '%s' object is not iterable", o->type->name));
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "'%s' object is not an iterator", o->type->name));
}
}
}