示例#1
0
void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_uint_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) {
    mp_uint_t pos_found = 0, kws_found = 0;
    for (mp_uint_t i = 0; i < n_allowed; i++) {
        mp_obj_t given_arg;
        if (i < n_pos) {
            if (allowed[i].flags & MP_ARG_KW_ONLY) {
                goto extra_positional;
            }
            pos_found++;
            given_arg = pos[i];
        } else {
            mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qst), MP_MAP_LOOKUP);
            if (kw == NULL) {
                if (allowed[i].flags & MP_ARG_REQUIRED) {
                    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,
                            "'%s' argument required",
                            qstr_str(allowed[i].qst)));
                    }
                }
                out_vals[i] = allowed[i].defval;
                continue;
            } else {
                kws_found++;
                given_arg = kw->value;
            }
        }
        if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_BOOL) {
            out_vals[i].u_bool = mp_obj_is_true(given_arg);
        } else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_INT) {
            out_vals[i].u_int = mp_obj_get_int(given_arg);
        } else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_OBJ) {
            out_vals[i].u_obj = given_arg;
        } else {
            assert(0);
        }
    }
    if (pos_found < n_pos) {
        extra_positional:
        if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
            mp_arg_error_terse_mismatch();
        } else {
            // TODO better error message
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
                "extra positional arguments given"));
        }
    }
    if (kws_found < kws->used) {
        if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
            mp_arg_error_terse_mismatch();
        } else {
            // TODO better error message
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
                "extra keyword arguments given"));
        }
    }
}
示例#2
0
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);
}
示例#3
0
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));
        }
    }

    // Create a tuple and set the type to this namedtuple
    mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_fields, NULL));
    tuple->base.type = type_in;

    // Copy the positional args into the first slots of the namedtuple
    memcpy(&tuple->items[0], args, sizeof(mp_obj_t) * n_args);

    // Fill in the remaining slots with the keyword args
    memset(&tuple->items[n_args], 0, sizeof(mp_obj_t) * n_kw);
    for (size_t i = n_args; i < n_args + 2 * n_kw; i += 2) {
        qstr kw = mp_obj_str_get_qstr(args[i]);
        size_t id = mp_obj_namedtuple_find_field(type, kw);
        if (id == (size_t)-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 (tuple->items[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));
            }
        }
        tuple->items[id] = args[i + 1];
    }

    return MP_OBJ_FROM_PTR(tuple);
}
示例#4
0
void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp_uint_t n_args_max, bool takes_kw) {
    // TODO maybe take the function name as an argument so we can print nicer error messages

    if (n_kw && !takes_kw) {
        if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
            mp_arg_error_terse_mismatch();
        } else {
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
                "function does not take keyword arguments"));
        }
    }

    if (n_args_min == n_args_max) {
        if (n_args != n_args_min) {
            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 takes %d positional arguments but %d were given",
                    n_args_min, n_args));
            }
        }
    } else {
        if (n_args < n_args_min) {
            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 missing %d required positional arguments",
                    n_args_min - n_args));
            }
        } else if (n_args > n_args_max) {
            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 expected at most %d arguments, got %d",
                    n_args_max, n_args));
            }
        }
    }
}
示例#5
0
STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, mp_uint_t expected, mp_uint_t given) {
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
    // generic message, used also for other argument issues
    mp_arg_error_terse_mismatch();
#elif 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", expected, given));
#elif 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",
        mp_obj_fun_get_name(f), expected, given));
#endif
}