Skip to content

Commit e6978a4

Browse files
dxxbdpgeorge
authored andcommitted
py: Fix call args when a stararg is followed by keyword args.
1 parent 5879141 commit e6978a4

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

py/compile.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
22032203
int n_positional = n_positional_extra;
22042204
uint n_keyword = 0;
22052205
uint star_flags = 0;
2206+
mp_parse_node_struct_t *star_args_node = NULL, *dblstar_args_node = NULL;
22062207
for (int i = 0; i < n_args; i++) {
22072208
if (MP_PARSE_NODE_IS_STRUCT(args[i])) {
22082209
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
22122213
return;
22132214
}
22142215
star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
2215-
compile_node(comp, pns_arg->nodes[0]);
2216+
star_args_node = pns_arg;
22162217
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) {
22172218
if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) {
22182219
compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "can't have multiple **x");
22192220
return;
22202221
}
22212222
star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
2222-
compile_node(comp, pns_arg->nodes[0]);
2223+
dblstar_args_node = pns_arg;
22232224
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) {
22242225
assert(MP_PARSE_NODE_IS_STRUCT(pns_arg->nodes[1])); // should always be
22252226
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
22502251
}
22512252
}
22522253

2254+
// compile the star/double-star arguments if we had them
2255+
if (star_args_node != NULL) {
2256+
compile_node(comp, star_args_node->nodes[0]);
2257+
}
2258+
if (dblstar_args_node != NULL) {
2259+
compile_node(comp, dblstar_args_node->nodes[0]);
2260+
}
2261+
22532262
// emit the function/method call
22542263
if (is_method_call) {
22552264
EMIT_ARG(call_method, n_positional, n_keyword, star_flags);

tests/basics/fun_kwvarargs.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,15 @@ def f3(a, *vargs, **kwargs):
1717
f3(1, 2)
1818
f3(1, b=2)
1919
f3(1, 2, b=3)
20+
21+
def f4(*vargs, **kwargs):
22+
print(vargs, kwargs)
23+
f4(*(1, 2))
24+
f4(kw_arg=3)
25+
f4(*(1, 2), kw_arg=3)
26+
27+
# test evaluation order of arguments (in CPy 3.4 it's actually backwards)
28+
def print_ret(x):
29+
print(x)
30+
return x
31+
f4(*print_ret(['a', 'b']), kw_arg=print_ret(None))

0 commit comments

Comments
 (0)