Made sorted() raise an exception instead of aborting when given no arguments; moved around some things in objfun.c as a consequence
This commit is contained in:
parent
2ded68db77
commit
88cb1e60e0
@ -314,4 +314,4 @@ static mp_obj_t mp_builtin_sorted(mp_obj_t args, mp_map_t *kwargs) {
|
||||
|
||||
return self;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, mp_builtin_sorted);
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
|
||||
|
2
py/obj.h
2
py/obj.h
@ -59,7 +59,7 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 3, 3, (mp_fun_3_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, 0, (~((machine_uint_t)0)), (mp_fun_kw_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, n_args_min, (~((machine_uint_t)0)), (mp_fun_kw_t)fun_name)
|
||||
|
||||
// These macros are used to declare and define constant staticmethond and classmethod objects
|
||||
// You can put "static" in front of the definitions to make them local
|
||||
|
43
py/objfun.c
43
py/objfun.c
@ -17,21 +17,44 @@
|
||||
|
||||
// mp_obj_fun_native_t defined in obj.h
|
||||
|
||||
void check_nargs(mp_obj_fun_native_t *self, int n_args, int n_kw) {
|
||||
if (n_kw && !self->is_kw) {
|
||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError,
|
||||
"function does not take keyword arguments"));
|
||||
}
|
||||
|
||||
if (self->n_args_min == self->n_args_max) {
|
||||
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));
|
||||
}
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t fun_native_call_n_kw(mp_obj_t self_in, int n_args, int n_kw, const mp_obj_t *args);
|
||||
// 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;
|
||||
// check number of arguments
|
||||
check_nargs(self, n_args, 0);
|
||||
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:
|
||||
@ -54,12 +77,6 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
||||
} 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++) {
|
||||
@ -76,9 +93,7 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
||||
mp_obj_t fun_native_call_n_kw(mp_obj_t self_in, int n_args, int n_kw, const mp_obj_t *args) {
|
||||
mp_obj_fun_native_t *self = self_in;
|
||||
|
||||
if (!self->is_kw) {
|
||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
|
||||
}
|
||||
check_nargs(self, n_args, n_kw);
|
||||
|
||||
mp_obj_t *vargs = mp_obj_new_tuple_reverse(n_args, args + 2*n_kw);
|
||||
mp_map_t *kw_args = mp_map_new(n_kw);
|
||||
|
@ -381,7 +381,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(list_insert_obj, list_insert);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(list_pop_obj, 1, 2, list_pop);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(list_remove_obj, list_remove);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(list_reverse_obj, list_reverse);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(list_sort_obj, list_sort);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(list_sort_obj, 0, list_sort);
|
||||
|
||||
static const mp_method_t list_type_methods[] = {
|
||||
{ "append", &list_append_obj },
|
||||
|
Loading…
Reference in New Issue
Block a user