mirror of
https://github.com/micropython/micropython.git
synced 2026-01-05 03:30:14 +01:00
py/runtime: Allow multiple **args in a function call.
This is a partial implementation of PEP 448 to allow multiple ** unpackings when calling a function or method. The compiler is modified to encode the argument as a None: obj key-value pair (similar to how regular keyword arguments are encoded as str: obj pairs). The extra object that was pushed on the stack to hold a single ** unpacking object is no longer used and is removed. The runtime is modified to decode this new format. Signed-off-by: David Lechner <david@pybricks.com>
This commit is contained in:
committed by
Damien George
parent
bb70874111
commit
1e99d29f36
18
py/compile.c
18
py/compile.c
@@ -2397,7 +2397,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
|
||||
int n_positional = n_positional_extra;
|
||||
uint n_keyword = 0;
|
||||
uint star_flags = 0;
|
||||
mp_parse_node_struct_t *star_args_node = NULL, *dblstar_args_node = NULL;
|
||||
mp_parse_node_struct_t *star_args_node = NULL;
|
||||
for (size_t i = 0; i < n_args; i++) {
|
||||
if (MP_PARSE_NODE_IS_STRUCT(args[i])) {
|
||||
mp_parse_node_struct_t *pns_arg = (mp_parse_node_struct_t *)args[i];
|
||||
@@ -2409,12 +2409,11 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
|
||||
star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
|
||||
star_args_node = pns_arg;
|
||||
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) {
|
||||
if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) {
|
||||
compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("can't have multiple **x"));
|
||||
return;
|
||||
}
|
||||
star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
|
||||
dblstar_args_node = pns_arg;
|
||||
// double-star args are stored as kw arg with key of None
|
||||
EMIT(load_null);
|
||||
compile_node(comp, pns_arg->nodes[0]);
|
||||
n_keyword++;
|
||||
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) {
|
||||
#if MICROPY_PY_ASSIGN_EXPR
|
||||
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns_arg->nodes[1], PN_argument_3)) {
|
||||
@@ -2429,7 +2428,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
|
||||
}
|
||||
EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns_arg->nodes[0]));
|
||||
compile_node(comp, pns_arg->nodes[1]);
|
||||
n_keyword += 1;
|
||||
n_keyword++;
|
||||
} else {
|
||||
compile_comprehension(comp, pns_arg, SCOPE_GEN_EXPR);
|
||||
n_positional++;
|
||||
@@ -2460,11 +2459,6 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
|
||||
} else {
|
||||
compile_node(comp, star_args_node->nodes[0]);
|
||||
}
|
||||
if (dblstar_args_node == NULL) {
|
||||
EMIT(load_null);
|
||||
} else {
|
||||
compile_node(comp, dblstar_args_node->nodes[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// emit the function/method call
|
||||
|
||||
Reference in New Issue
Block a user