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 gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value) { mp_obj_t ret; switch (mp_obj_gen_resume(self_in, send_value, throw_value, &ret)) { case MP_VM_RETURN_NORMAL: // Optimize return w/o value in case generator is used in for loop if (ret == mp_const_none) { return MP_OBJ_NULL; } else { nlr_jump(mp_obj_new_exception_args(&mp_type_StopIteration, 1, &ret)); } case MP_VM_RETURN_YIELD: return ret; case MP_VM_RETURN_EXCEPTION: // TODO: Optimization of returning MP_OBJ_NULL is really part // of mp_iternext() protocol, but this function is called by other methods // too, which may not handled MP_OBJ_NULL. if (mp_obj_is_subclass_fast(mp_obj_get_type(ret), &mp_type_StopIteration)) { return MP_OBJ_NULL; } else { nlr_jump(ret); } default: assert(0); return mp_const_none; } }
mp_obj_t py_file_open(mp_obj_t path, mp_obj_t mode_str) { BYTE mode=0; FRESULT res; py_file_obj_t *o; switch (mp_obj_str_get_str(mode_str)[0]) { case 'r': /* Open file for reading, fail if the file is not existing. */ mode = FA_READ|FA_OPEN_EXISTING; break; case 'w': /* Open file for reading/writing, create the file if not existing. */ mode = FA_READ|FA_WRITE|FA_OPEN_ALWAYS; break; case 'a': /* Open file for reading/writing, fail if the file is not existing. */ mode = FA_READ|FA_WRITE|FA_OPEN_EXISTING; break; default: nlr_jump(mp_obj_new_exception_msg(qstr_from_str("File"), "invalid open mode")); } /* Create new python file obj */ o = m_new_obj(py_file_obj_t); o->base.type = &py_file_type; /* Open underlying file handle */ res = f_open(&o->fp, mp_obj_str_get_str(path), mode); if (res != FR_OK) { nlr_jump(mp_obj_new_exception_msg(qstr_from_str("File"), ffs_strerror(res))); } return o; }
mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) { pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t); o->base.type = &adc_type; o->pin_name = pin_name_obj; // work out the channel from the pin name const char *pin_name = mp_obj_str_get_str(pin_name_obj); GPIO_TypeDef *port; switch (pin_name[0]) { case 'A': case 'a': port = GPIOA; break; case 'B': case 'b': port = GPIOB; break; case 'C': case 'c': port = GPIOC; break; default: goto pin_error; } uint pin_num = 0; for (const char *s = pin_name + 1; *s; s++) { if (!('0' <= *s && *s <= '9')) { goto pin_error; } pin_num = 10 * pin_num + *s - '0'; } if (!(0 <= pin_num && pin_num <= 15)) { goto pin_error; } int i; for (i = 0; i < ADC_NUM_CHANNELS; i++) { if (adc_gpio[i].port == port && adc_gpio[i].pin == (1 << pin_num)) { o->channel = i; break; } } if (i == ADC_NUM_CHANNELS) { nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not have ADC capabilities", pin_name)); } // init ADC just for this channel adc_init_single(o->channel); o->is_enabled = true; return o; pin_error: nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not exist", pin_name)); }
void do_load(mp_obj_t module_obj, vstr_t *file) { // create the lexer mp_lexer_t *lex = mp_lexer_new_from_file(vstr_str(file)); if (lex == NULL) { // we verified the file exists using stat, but lexer could still fail nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "ImportError: No module named '%s'", vstr_str(file))); } qstr source_name = mp_lexer_source_name(lex); // save the old context mp_map_t *old_locals = mp_locals_get(); mp_map_t *old_globals = mp_globals_get(); // set the new context mp_locals_set(mp_obj_module_get_globals(module_obj)); mp_globals_set(mp_obj_module_get_globals(module_obj)); // parse the imported script mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind); mp_lexer_free(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error; clean up and raise exception mp_locals_set(old_locals); mp_globals_set(old_globals); nlr_jump(mp_parse_make_exception(parse_error_kind)); } // compile the imported script mp_obj_t module_fun = mp_compile(pn, source_name, false); mp_parse_node_free(pn); if (module_fun == mp_const_none) { // TODO handle compile error correctly mp_locals_set(old_locals); mp_globals_set(old_globals); return; } // complied successfully, execute it nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_call_function_0(module_fun); nlr_pop(); } else { // exception; restore context and re-raise same exception mp_locals_set(old_locals); mp_globals_set(old_globals); nlr_jump(nlr.ret_val); } mp_locals_set(old_locals); mp_globals_set(old_globals); }
// args are in reverse order in the array mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { mp_obj_fun_native_t *self = self_in; if (self->is_kw) { return fun_native_call_n_kw(self_in, n_args, 0, args); } if (self->n_args_min == self->n_args_max) { // function requires a fixed number of arguments // check number of arguments if (n_args != self->n_args_min) { nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args_min, (const char*)(machine_int_t)n_args)); } // dispatch function call switch (self->n_args_min) { case 0: return ((mp_fun_0_t)self->fun)(); case 1: return ((mp_fun_1_t)self->fun)(args[0]); case 2: return ((mp_fun_2_t)self->fun)(args[1], args[0]); case 3: return ((mp_fun_3_t)self->fun)(args[2], args[1], args[0]); default: assert(0); return mp_const_none; } } else { // function takes a variable number of arguments if (n_args < self->n_args_min) { nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "<fun name>() missing %d required positional arguments: <list of names of params>", (const char*)(machine_int_t)(self->n_args_min - n_args))); } else if (n_args > self->n_args_max) { nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "<fun name> expected at most %d arguments, got %d", (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args)); } // TODO really the args need to be passed in as a Python tuple, as the form f(*[1,2]) can be used to pass var args mp_obj_t *args_ordered = m_new(mp_obj_t, n_args); for (int i = 0; i < n_args; i++) { args_ordered[i] = args[n_args - i - 1]; } mp_obj_t res = ((mp_fun_var_t)self->fun)(n_args, args_ordered); m_del(mp_obj_t, args_ordered, n_args); return res; } }
mp_obj_t py_imlib_save_template(mp_obj_t image_obj, mp_obj_t rectangle_obj, mp_obj_t path_obj) { struct image t; struct image *image = NULL; struct rectangle r; mp_obj_t *array; const char *path = mp_obj_str_get_str(path_obj); array = mp_obj_get_array_fixed_n(rectangle_obj, 4); r.x = mp_obj_get_int(array[0]); r.y = mp_obj_get_int(array[1]); r.w = mp_obj_get_int(array[2]); r.h = mp_obj_get_int(array[3]); /* get C image pointer */ image = py_image_cobj(image_obj); t.w = r.w; t.h = r.h; t.data = malloc(sizeof(*t.data)*t.w*t.h); imlib_subimage(image, &t, r.x, r.y); int res = imlib_save_template(&t, path); free(t.data); if (res != FR_OK) { nlr_jump(mp_obj_new_exception_msg(qstr_from_str("Imlib"), ffs_strerror(res))); } return mp_const_true; }
static mp_obj_t mp_builtin_eval(mp_obj_t o_in) { uint str_len; const byte *str = mp_obj_str_get_data(o_in, &str_len); // create the lexer mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, (const char*)str, str_len, 0); qstr source_name = mp_lexer_source_name(lex); // parse the string qstr parse_exc_id; const char *parse_exc_msg; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_EVAL_INPUT, &parse_exc_id, &parse_exc_msg); mp_lexer_free(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error; raise exception nlr_jump(mp_obj_new_exception_msg(parse_exc_id, parse_exc_msg)); } // compile the string mp_obj_t module_fun = mp_compile(pn, source_name, false); mp_parse_node_free(pn); if (module_fun == mp_const_none) { // TODO handle compile error correctly return mp_const_none; } // complied successfully, execute it return rt_call_function_0(module_fun); }
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_1_arg(MP_QSTR_TypeError, "list takes at most 1 argument, %d given", (void*)(machine_int_t)n_args)); } return NULL; }
STATIC mp_obj_t parse_compile_execute(mp_obj_t o_in, mp_parse_input_kind_t parse_input_kind) { uint str_len; const char *str = mp_obj_str_get_data(o_in, &str_len); // create the lexer mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, str, str_len, 0); qstr source_name = mp_lexer_source_name(lex); // parse the string mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, parse_input_kind, &parse_error_kind); mp_lexer_free(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error; raise exception nlr_jump(mp_parse_make_exception(parse_error_kind)); } // compile the string mp_obj_t module_fun = mp_compile(pn, source_name, false); mp_parse_node_free(pn); if (module_fun == mp_const_none) { // TODO handle compile error correctly return mp_const_none; } // complied successfully, execute it return rt_call_function_0(module_fun); }
static mp_obj_t py_sensor_set_framerate(mp_obj_t framerate) { enum sensor_framerate fr; switch (mp_obj_get_int(framerate)) { case 2: fr = FRAMERATE_2FPS; break; case 8: fr = FRAMERATE_8FPS; break; case 15: fr = FRAMERATE_15FPS; break; case 30: fr = FRAMERATE_30FPS; break; case 60: fr = FRAMERATE_60FPS; break; default: nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid framerate")); break; } if (sensor_set_framerate(fr) != 0) { return mp_const_false; } return mp_const_true; }
// If it's possible to call a function without allocating new argument array, // this function returns true, together with pointers to 2 subarrays to be used // as arguments. Otherwise, it returns false. It is expected that this fucntion // will be accompanied by another, mp_obj_fun_prepare_full_args(), which will // instead take pointer to full-length out-array, and will fill it in. Rationale // being that a caller can try this function and if it succeeds, the function call // can be made without allocating extra memory. Otherwise, caller can allocate memory // and try "full" function. These functions are expected to be refactoring of // code in fun_bc_call() and evenrually replace it. bool mp_obj_fun_prepare_simple_args(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args, uint *out_args1_len, const mp_obj_t **out_args1, uint *out_args2_len, const mp_obj_t **out_args2) { mp_obj_fun_bc_t *self = self_in; assert(n_kw == 0); assert(self->takes_var_args == 0); assert(self->takes_kw_args == 0); mp_obj_t *extra_args = self->extra_args + self->n_def_args; uint n_extra_args = 0; if (n_args > self->n_args) { goto arg_error; } else { extra_args -= self->n_args - n_args; n_extra_args += self->n_args - n_args; } *out_args1 = args; *out_args1_len = n_args; *out_args2 = extra_args; *out_args2_len = n_extra_args; return true; arg_error: nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args)); }
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 = mp_getiter(args[0]); mp_obj_t list = mp_obj_new_list(0, NULL); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_NULL) { 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; }
mp_obj_t rt_unary_op(int op, mp_obj_t arg) { DEBUG_OP_printf("unary %d %p\n", op, arg); if (MP_OBJ_IS_SMALL_INT(arg)) { mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(arg); switch (op) { case RT_UNARY_OP_NOT: if (val != 0) { return mp_const_true;} else { return mp_const_false; } case RT_UNARY_OP_POSITIVE: break; case RT_UNARY_OP_NEGATIVE: val = -val; break; case RT_UNARY_OP_INVERT: val = ~val; break; default: assert(0); val = 0; } if (fit_small_int(val)) { return MP_OBJ_NEW_SMALL_INT(val); } else { // TODO make a bignum assert(0); return mp_const_none; } } else { // will be an object (small ints are caught in previous if) mp_obj_base_t *o = arg; if (o->type->unary_op != NULL) { mp_obj_t result = o->type->unary_op(op, arg); if (result != NULL) { return result; } } // TODO specify in error message what the operator is nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "bad operand type for unary operator: '%s'", o->type->name)); } }
static mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp_map_lookup_kind_t lookup_kind) { mp_map_elem_t *elem = mp_map_lookup(self, key, lookup_kind); mp_obj_t value; if (elem == NULL || elem->value == NULL) { if (deflt == NULL) { if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "<value>")); } else { value = mp_const_none; } } else { value = deflt; } } else { value = elem->value; if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) { // catch the leak (from mp_map_lookup) m_free(elem, sizeof(mp_map_elem_t)); } } if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) { elem->value = value; } return value; }
static mp_obj_t py_sensor_set_gainceiling(mp_obj_t gainceiling) { enum sensor_gainceiling gain; switch (mp_obj_get_int(gainceiling)) { case 2: gain = GAINCEILING_2X; break; case 4: gain = GAINCEILING_4X; break; case 8: gain = GAINCEILING_8X; break; case 16: gain = GAINCEILING_16X; break; case 32: gain = GAINCEILING_32X; break; case 64: gain = GAINCEILING_64X; break; case 128: gain = GAINCEILING_128X; break; default: nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid gainceiling")); break; } if (sensor_set_gainceiling(gain) != 0) { return mp_const_false; } return mp_const_true; }
mp_obj_t str_format(uint n_args, const mp_obj_t *args) { assert(MP_OBJ_IS_STR(args[0])); GET_STR_DATA_LEN(args[0], str, len); int arg_i = 1; vstr_t *vstr = vstr_new(); for (const byte *top = str + len; str < top; str++) { if (*str == '{') { str++; if (str < top && *str == '{') { vstr_add_char(vstr, '{'); } else { while (str < top && *str != '}') str++; if (arg_i >= n_args) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_IndexError, "tuple index out of range")); } // TODO: may be PRINT_REPR depending on formatting code mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[arg_i], PRINT_STR); arg_i++; } } else { vstr_add_char(vstr, *str); } } mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false); vstr_free(vstr); return s; }
STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code) { #if MICROPY_PY___FILE__ // TODO //qstr source_name = lex->source_name; //mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif // execute the module in its context mp_obj_dict_t *mod_globals = mp_obj_module_get_globals(module_obj); // save context mp_obj_dict_t *volatile old_globals = mp_globals_get(); mp_obj_dict_t *volatile old_locals = mp_locals_get(); // set new context mp_globals_set(mod_globals); mp_locals_set(mod_globals); nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_obj_t module_fun = mp_make_function_from_raw_code(raw_code, MP_OBJ_NULL, MP_OBJ_NULL); mp_call_function_0(module_fun); // finish nlr block, restore context nlr_pop(); mp_globals_set(old_globals); mp_locals_set(old_locals); } else { // exception; restore context and re-raise same exception mp_globals_set(old_globals); mp_locals_set(old_locals); nlr_jump(nlr.ret_val); } }
mp_obj_t rt_load_build_class(void) { DEBUG_OP_printf("load_build_class\n"); mp_map_elem_t *elem = mp_qstr_map_lookup(&map_builtins, MP_QSTR___build_class__, false); if (elem == NULL) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_NameError, "name '__build_class__' is not defined")); } return elem->value; }
mp_obj_t gen_wrap_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_gen_wrap_t *self = self_in; mp_obj_t self_fun = self->fun; assert(MP_OBJ_IS_TYPE(self_fun, &fun_bc_type)); int bc_n_args; uint bc_n_state; const byte *bc_code; mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code); if (n_args != bc_n_args) { nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)bc_n_args, (const char*)(machine_int_t)n_args)); } if (n_kw != 0) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments")); } return mp_obj_new_gen_instance(bc_code, self->n_state, n_args, args); }
STATIC mp_obj_t set_remove(mp_obj_t self_in, mp_obj_t item) { assert(MP_OBJ_IS_TYPE(self_in, &set_type)); mp_obj_set_t *self = self_in; if (mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_REMOVE_IF_FOUND) == MP_OBJ_NULL) { nlr_jump(mp_obj_new_exception(&mp_type_KeyError)); } return mp_const_none; }
STATIC mp_obj_t gen_instance_send(mp_obj_t self_in, mp_obj_t send_value) { mp_obj_t ret = gen_resume_and_raise(self_in, send_value, MP_OBJ_NULL); if (ret == MP_OBJ_NULL) { nlr_jump(mp_obj_new_exception(&mp_type_StopIteration)); } else { return ret; } }
STATIC mp_obj_t object_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { if (n_args != 0 || n_kw != 0) { nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "object takes no arguments")); } mp_obj_object_t *o = m_new_obj(mp_obj_object_t); o->base.type = &mp_type_object; return o; }
uint mp_obj_str_get_len(mp_obj_t self_in) { if (MP_OBJ_IS_STR(self_in)) { GET_STR_LEN(self_in, l); return l; } else { nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in))); } }
const byte *mp_obj_str_get_data(mp_obj_t self_in, uint *len) { if (MP_OBJ_IS_STR(self_in)) { GET_STR_DATA_LEN(self_in, s, l); *len = l; return s; } else { nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in))); } }
// only use this function if you need the str data to be zero terminated // at the moment all strings are zero terminated to help with C ASCIIZ compatibility const char *mp_obj_str_get_str(mp_obj_t self_in) { if (MP_OBJ_IS_STR(self_in)) { GET_STR_DATA_LEN(self_in, s, l); (void)l; // len unused return (const char*)s; } else { nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in))); } }
static mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(arg, &str_type)); const char *s = mp_obj_str_get_str(arg); struct hostent *h = gethostbyname(s); if (h == NULL) { nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno)); } assert(h->h_length == 4); return mp_obj_new_int(*(int*)*h->h_addr_list); }
static mp_obj_t mod_socket_inet_aton(mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(arg, &str_type)); const char *s = mp_obj_str_get_str(arg); struct in_addr addr; if (!inet_aton(s, &addr)) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Invalid IP address")); } return mp_obj_new_int(addr.s_addr); }
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_pop(mp_obj_t self_in) { assert(MP_OBJ_IS_TYPE(self_in, &set_type)); mp_obj_set_t *self = self_in; if (self->set.used == 0) { nlr_jump(mp_obj_new_exception_msg(&mp_type_KeyError, "pop from an empty set")); } mp_obj_t obj = mp_set_lookup(&self->set, NULL, MP_MAP_LOOKUP_REMOVE_IF_FOUND | MP_MAP_LOOKUP_FIRST); return obj; }