added a first pass of dict.update
This commit is contained in:
parent
e3096172c9
commit
88f3043e0a
29
py/objdict.c
29
py/objdict.c
|
@ -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
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue