Index: Python/ast.c =================================================================== --- Python/ast.c (revision 51856) +++ Python/ast.c (working copy) @@ -566,10 +566,15 @@ if (!args) return NULL; + /* fpdef: NAME | '(' fplist ')' + fplist: fpdef (',' fpdef)* [','] + */ REQ(n, fplist); for (i = 0; i < len; i++) { - const node *child = CHILD(CHILD(n, 2*i), 0); + const node *arg_node = CHILD(n, 2*i); + const node *child = CHILD(arg_node, 0); expr_ty arg; + set_name: if (TYPE(child) == NAME) { if (!strcmp(STR(child), "None")) { ast_error(child, "assignment to None"); @@ -579,7 +584,18 @@ child->n_col_offset, c->c_arena); } else { - arg = compiler_complex_args(c, CHILD(CHILD(n, 2*i), 1)); + child = CHILD(arg_node, 1); + /* NCH == 1 means we have (x), we need to elide the extra parens */ + if (NCH(child) != 1) + arg = compiler_complex_args(c, child); + else { + assert(TYPE(child) == fplist); + child = CHILD(child, 0); assert(TYPE(child) == fpdef); + child = CHILD(child, 1); assert(TYPE(child) == fplist); + child = CHILD(child, 0); assert(TYPE(child) == fpdef); + child = CHILD(child, 0); assert(TYPE(child) == NAME); + goto set_name; + } } asdl_seq_SET(args, i, arg); } @@ -637,6 +653,7 @@ ch = CHILD(n, i); switch (TYPE(ch)) { case fpdef: + handle_fpdef: /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is anything other than EQUAL or a comma? */ /* XXX Should NCH(n) check be made a separate check? */ @@ -662,7 +679,11 @@ asdl_seq_SET(args, k++, compiler_complex_args(c, ch)); } else { /* def foo((x)): setup for checking NAME below. */ + /* Loop because there can be many parens and tuple + unpacking mixed in. */ ch = CHILD(ch, 0); + assert(TYPE(ch) == fpdef); + goto handle_fpdef; } } if (TYPE(CHILD(ch, 0)) == NAME) {