// this is a classmethod static mp_obj_t dict_fromkeys(uint n_args, const mp_obj_t *args) { assert(2 <= n_args && n_args <= 3); mp_obj_t iter = rt_getiter(args[1]); mp_obj_t len = mp_obj_len_maybe(iter); mp_obj_t value = mp_const_none; mp_obj_t next = NULL; mp_obj_dict_t *self = NULL; if (n_args > 2) { value = args[2]; } if (len == MP_OBJ_NULL) { /* object's type doesn't have a __len__ slot */ self = mp_obj_new_dict(0); } else { self = mp_obj_new_dict(MP_OBJ_SMALL_INT_VALUE(len)); } while ((next = rt_iternext(iter)) != mp_const_stop_iteration) { mp_map_lookup(&self->map, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } return self; }
static mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t paramtypes_in) { const char *rettype = mp_obj_str_get_str(rettype_in); int nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(paramtypes_in)); mp_obj_fficallback_t *o = m_new_obj_var(mp_obj_fficallback_t, ffi_type*, nparams); o->base.type = &fficallback_type; o->clo = ffi_closure_alloc(sizeof(ffi_closure), &o->func); o->rettype = *rettype; mp_obj_t iterable = rt_getiter(paramtypes_in); mp_obj_t item; int i = 0; while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { o->params[i++] = get_ffi_type(item); } int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params); if (res != FFI_OK) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error in ffi_prep_cif")); } res = ffi_prep_closure_loc(o->clo, &o->cif, call_py_func, func_in, o->func); if (res != FFI_OK) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "ffi_prep_closure_loc")); } return o; }
STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 switch (n_args) { case 0: // return a new, empty list return mp_obj_new_list(0, NULL); case 1: { // make list from iterable mp_obj_t iterable = rt_getiter(args[0]); mp_obj_t list = mp_obj_new_list(0, NULL); mp_obj_t item; while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { mp_obj_list_append(list, item); } return list; } default: nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "list takes at most 1 argument, %d given", n_args)); } return NULL; }
static mp_obj_t ffimod_func(uint n_args, const mp_obj_t *args) { mp_obj_ffimod_t *self = args[0]; const char *rettype = mp_obj_str_get_str(args[1]); const char *symname = mp_obj_str_get_str(args[2]); void *sym = dlsym(self->handle, symname); if (sym == NULL) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno)); } int nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(args[3])); mp_obj_ffifunc_t *o = m_new_obj_var(mp_obj_ffifunc_t, ffi_type*, nparams); o->base.type = &ffifunc_type; o->func = sym; o->rettype = *rettype; mp_obj_t iterable = rt_getiter(args[3]); mp_obj_t item; int i = 0; while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { o->params[i++] = get_ffi_type(item); } int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params); if (res != FFI_OK) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error in ffi_prep_cif")); } return o; }
STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { uint len; // Try to create array of exact len if initializer len is known mp_obj_t len_in = mp_obj_len_maybe(initializer); if (len_in == MP_OBJ_NULL) { len = 0; } else { len = MP_OBJ_SMALL_INT_VALUE(len_in); } mp_obj_array_t *array = array_new(typecode, len); mp_obj_t iterable = rt_getiter(initializer); mp_obj_t item; int i = 0; while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { if (len == 0) { array_append(array, item); } else { mp_binary_set_val(typecode, array->items, i++, item); } } return array; }
STATIC void set_update_int(mp_obj_set_t *self, mp_obj_t other_in) { mp_obj_t iter = rt_getiter(other_in); mp_obj_t next; while ((next = rt_iternext(iter)) != mp_const_stop_iteration) { mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); } }
STATIC mp_obj_t set_intersect_int(mp_obj_t self_in, mp_obj_t other, bool update) { assert(MP_OBJ_IS_TYPE(self_in, &set_type)); if (self_in == other) { return update ? mp_const_none : set_copy(self_in); } mp_obj_set_t *self = self_in; mp_obj_set_t *out = mp_obj_new_set(0, NULL); mp_obj_t iter = rt_getiter(other); mp_obj_t next; while ((next = rt_iternext(iter)) != mp_const_stop_iteration) { if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) { set_add(out, next); } } if (update) { m_del(mp_obj_t, self->set.table, self->set.alloc); self->set.alloc = out->set.alloc; self->set.used = out->set.used; self->set.table = out->set.table; } return update ? mp_const_none : out; }
STATIC mp_obj_t set_diff_int(int n_args, const mp_obj_t *args, bool update) { assert(n_args > 0); assert(MP_OBJ_IS_TYPE(args[0], &set_type)); mp_obj_set_t *self; if (update) { self = args[0]; } else { self = set_copy(args[0]); } for (int i = 1; i < n_args; i++) { mp_obj_t other = args[i]; if (self == other) { set_clear(self); } else { mp_obj_t iter = rt_getiter(other); mp_obj_t next; while ((next = rt_iternext(iter)) != mp_const_stop_iteration) { set_discard(self, next); } } } return self; }
STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other_in) { assert(MP_OBJ_IS_TYPE(self_in, &set_type)); mp_obj_set_t *self = self_in; mp_obj_t iter = rt_getiter(other_in); mp_obj_t next; while ((next = rt_iternext(iter)) != mp_const_stop_iteration) { mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_REMOVE_IF_FOUND | MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); } return mp_const_none; }
STATIC mp_obj_t filter_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { if (n_args != 2 || n_kw != 0) { nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "filter expected 2 arguments")); } assert(n_args == 2); mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t); o->base.type = &filter_type; o->fun = args[0]; o->iter = rt_getiter(args[1]); return o; }
STATIC mp_obj_t set_isdisjoint(mp_obj_t self_in, mp_obj_t other) { assert(MP_OBJ_IS_TYPE(self_in, &set_type)); mp_obj_set_t *self = self_in; mp_obj_t iter = rt_getiter(other); mp_obj_t next; while ((next = rt_iternext(iter)) != mp_const_stop_iteration) { if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) { return mp_const_false; } } return mp_const_true; }
STATIC mp_obj_t map_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { if (n_args < 2 || n_kw != 0) { nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "map must have at least 2 arguments and no keyword arguments")); } assert(n_args >= 2); mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1); o->base.type = &map_type; o->n_iters = n_args - 1; o->fun = args[0]; for (int i = 0; i < n_args - 1; i++) { o->iters[i] = rt_getiter(args[i + 1]); } return o; }
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(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } } return mp_const_none; }
STATIC mp_obj_t tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 switch (n_args) { case 0: // return a empty tuple return mp_const_empty_tuple; case 1: { // 1 argument, an iterable from which we make a new tuple if (MP_OBJ_IS_TYPE(args[0], &tuple_type)) { return args[0]; } // TODO optimise for cases where we know the length of the iterator uint alloc = 4; uint len = 0; mp_obj_t *items = m_new(mp_obj_t, alloc); mp_obj_t iterable = rt_getiter(args[0]); mp_obj_t item; while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { if (len >= alloc) { items = m_renew(mp_obj_t, items, alloc, alloc * 2); alloc *= 2; } items[len++] = item; } mp_obj_t tuple = mp_obj_new_tuple(len, items); m_free(items, alloc); return tuple; } default: nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "tuple takes at most 1 argument, %d given", n_args)); } }
STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 switch (n_args) { case 0: // return a new, empty set return mp_obj_new_set(0, NULL); case 1: { // 1 argument, an iterable from which we make a new set mp_obj_t set = mp_obj_new_set(0, NULL); mp_obj_t iterable = rt_getiter(args[0]); mp_obj_t item; while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { mp_obj_set_store(set, item); } return set; } default: nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "set takes at most 1 argument, %d given", n_args)); } }