py: Fix call args when a stararg is followed by keyword args.
This commit is contained in:
parent
587914169c
commit
e6978a4e26
13
py/compile.c
13
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);
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue