summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDelio Brignoli <brignoli.delio@gmail.com>2015-09-17 12:07:06 +0200
committerDamien George <damien.p.george@gmail.com>2015-09-23 11:37:00 +0100
commite6978a4e26a17ef473e2aad78662d3bf29638578 (patch)
tree3c42f0a50a150b8f140c41211308c46562c28900
parent587914169cc6ff7f0513bd14c42dcbb275bf77bd (diff)
downloadmicropython-e6978a4e26a17ef473e2aad78662d3bf29638578.tar.gz
micropython-e6978a4e26a17ef473e2aad78662d3bf29638578.zip
py: Fix call args when a stararg is followed by keyword args.
-rw-r--r--py/compile.c13
-rw-r--r--tests/basics/fun_kwvarargs.py12
2 files changed, 23 insertions, 2 deletions
diff --git a/py/compile.c b/py/compile.c
index 34f377fb0c..9ac37c6d95 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -2203,6 +2203,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;
for (int 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];
@@ -2212,14 +2213,14 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
return;
}
star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
- compile_node(comp, pns_arg->nodes[0]);
+ 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, "can't have multiple **x");
return;
}
star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
- compile_node(comp, pns_arg->nodes[0]);
+ dblstar_args_node = pns_arg;
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) {
assert(MP_PARSE_NODE_IS_STRUCT(pns_arg->nodes[1])); // should always be
mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns_arg->nodes[1];
@@ -2250,6 +2251,14 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
}
}
+ // compile the star/double-star arguments if we had them
+ if (star_args_node != NULL) {
+ compile_node(comp, star_args_node->nodes[0]);
+ }
+ if (dblstar_args_node != NULL) {
+ compile_node(comp, dblstar_args_node->nodes[0]);
+ }
+
// emit the function/method call
if (is_method_call) {
EMIT_ARG(call_method, n_positional, n_keyword, star_flags);
diff --git a/tests/basics/fun_kwvarargs.py b/tests/basics/fun_kwvarargs.py
index 6350d20d6b..2b6893f24f 100644
--- a/tests/basics/fun_kwvarargs.py
+++ b/tests/basics/fun_kwvarargs.py
@@ -17,3 +17,15 @@ f3(1)
f3(1, 2)
f3(1, b=2)
f3(1, 2, b=3)
+
+def f4(*vargs, **kwargs):
+ print(vargs, kwargs)
+f4(*(1, 2))
+f4(kw_arg=3)
+f4(*(1, 2), kw_arg=3)
+
+# test evaluation order of arguments (in CPy 3.4 it's actually backwards)
+def print_ret(x):
+ print(x)
+ return x
+f4(*print_ret(['a', 'b']), kw_arg=print_ret(None))