Commit e5d371b5 authored by Damien George's avatar Damien George
Browse files

py: Pass keyword arguments to byte code.

parent 2e482cdb
...@@ -141,15 +141,18 @@ typedef struct _mp_obj_fun_bc_t { ...@@ -141,15 +141,18 @@ typedef struct _mp_obj_fun_bc_t {
}; };
uint n_state; // total state size for the executing function (incl args, locals, stack) uint n_state; // total state size for the executing function (incl args, locals, stack)
const byte *bytecode; // bytecode for the function const byte *bytecode; // bytecode for the function
mp_obj_t extra_args[]; // values of default args (if any), plus a slot at the end for var args (if it takes them) mp_obj_t extra_args[]; // values of default args (if any), plus a slot at the end for var args and/or kw args (if it takes them)
} mp_obj_fun_bc_t; } mp_obj_fun_bc_t;
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
mp_obj_fun_bc_t *self = self_in; mp_obj_fun_bc_t *self = self_in;
const mp_obj_t *kwargs = args + n_args;
mp_obj_t *extra_args = self->extra_args + self->n_def_args; mp_obj_t *extra_args = self->extra_args + self->n_def_args;
uint n_extra_args = 0; uint n_extra_args = 0;
// check positional arguments
if (n_args > self->n_args) { if (n_args > self->n_args) {
// given more than enough arguments // given more than enough arguments
if (!self->takes_var_args) { if (!self->takes_var_args) {
...@@ -171,8 +174,25 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o ...@@ -171,8 +174,25 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
goto arg_error; goto arg_error;
} }
// check keyword arguments
if (n_kw != 0) { if (n_kw != 0) {
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); // keyword arguments given
if (!self->takes_kw_args) {
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
}
mp_obj_t dict = mp_obj_new_dict(n_kw);
for (uint i = 0; i < n_kw; i++) {
mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
}
extra_args[n_extra_args] = dict;
n_extra_args += 1;
} else {
// no keyword arguments given
if (self->takes_kw_args) {
extra_args[n_extra_args] = mp_obj_new_dict(0);
n_extra_args += 1;
}
} }
mp_map_t *old_globals = rt_globals_get(); mp_map_t *old_globals = rt_globals_get();
...@@ -208,6 +228,9 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, uint n_args, mp_obj_t def_args_in, ...@@ -208,6 +228,9 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, uint n_args, mp_obj_t def_args_in,
if ((scope_flags & MP_SCOPE_FLAG_VARARGS) != 0) { if ((scope_flags & MP_SCOPE_FLAG_VARARGS) != 0) {
n_extra_args += 1; n_extra_args += 1;
} }
if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
n_extra_args += 1;
}
mp_obj_fun_bc_t *o = m_new_obj_var(mp_obj_fun_bc_t, mp_obj_t, n_extra_args); mp_obj_fun_bc_t *o = m_new_obj_var(mp_obj_fun_bc_t, mp_obj_t, n_extra_args);
o->base.type = &fun_bc_type; o->base.type = &fun_bc_type;
o->globals = rt_globals_get(); o->globals = rt_globals_get();
......
def f1(**kwargs):
print(kwargs)
f1()
f1(a=1)
def f2(a, **kwargs):
print(a, kwargs)
f2(1)
f2(1, b=2)
def f3(a, *vargs, **kwargs):
print(a, vargs, kwargs)
f3(1)
f3(1, 2)
f3(1, b=2)
f3(1, 2, b=3)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment