STATIC void namedtuple_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_namedtuple_t *self = self_in; const char *fields = ((mp_obj_namedtuple_type_t*)self->tuple.base.type)->fields; int id = namedtuple_find_field(qstr_str(attr), fields); if (id < 0) { return; } dest[0] = self->tuple.items[id]; }
STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t*)type_in; size_t num_fields = type->n_fields; if (n_args + n_kw != num_fields) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", num_fields, n_args + n_kw)); } else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%q() takes %d positional arguments but %d were given", type->base.name, num_fields, n_args + n_kw)); } } mp_obj_t *arg_objects; if (n_args == num_fields) { arg_objects = (mp_obj_t*)args; } else { size_t alloc_size = sizeof(mp_obj_t) * num_fields; arg_objects = alloca(alloc_size); memset(arg_objects, 0, alloc_size); for (mp_uint_t i = 0; i < n_args; i++) { arg_objects[i] = args[i]; } for (mp_uint_t i = n_args; i < n_args + 2 * n_kw; i += 2) { qstr kw = mp_obj_str_get_qstr(args[i]); int id = namedtuple_find_field(type, kw); if (id == -1) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unexpected keyword argument '%q'", kw)); } } if (arg_objects[id] != MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function got multiple values for argument '%q'", kw)); } } arg_objects[id] = args[i + 1]; } } mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_fields, arg_objects)); tuple->base.type = type_in; return MP_OBJ_FROM_PTR(tuple); }
STATIC void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // load attribute mp_obj_namedtuple_t *self = MP_OBJ_TO_PTR(self_in); int id = namedtuple_find_field((mp_obj_namedtuple_type_t*)self->tuple.base.type, attr); if (id == -1) { return; } dest[0] = self->tuple.items[id]; } else { // delete/store attribute // provide more detailed error message than we'd get by just returning mp_raise_msg(&mp_type_AttributeError, "can't set attribute"); } }