diff --git a/Grammar/Grammar b/Grammar/Grammar index 86ec43248e9..99fcea026a3 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -137,7 +137,7 @@ arglist: argument (',' argument)* [','] argument: ( test [comp_for] | test '=' test | '**' test | - star_expr ) + '*' test ) comp_iter: comp_for | comp_if comp_for: 'for' exprlist 'in' or_test [comp_iter] diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 8f0cf163eed..ec3d7833f7e 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -205,6 +205,8 @@ class GrammarTests(unittest.TestCase): d01() d01(1) d01(*(1,)) + d01(*[] or [2]) + d01(*() or (), *{} and (), **() or {}) d01(**{'a':2}) d01(**{'a':2} or {}) def d11(a, b=1): pass diff --git a/Misc/NEWS b/Misc/NEWS index 11e19960d0a..56e61e299e8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -40,6 +40,8 @@ Library - Issue #23812: Fix asyncio.Queue.get() to avoid loosing items on cancellation. Patch by Gustavo J. A. M. Carneiro. +- Issue #24791: Fix grammar regression for call syntax: 'g(*a or b)'. + Documentation ------------- diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 2a16dbacc62..8023558fd15 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -2859,8 +2859,8 @@ validate_arglist(node *tree) /* argument: ( test [comp_for] | * test '=' test | - * '**' expr | - * star_expr ) + * '**' test | + * '*' test ) */ static int validate_argument(node *tree) @@ -2873,8 +2873,11 @@ validate_argument(node *tree) if (TYPE(CHILD(tree, 0)) == DOUBLESTAR) { res = validate_test(CHILD(tree, 1)); } + else if (TYPE(CHILD(tree, 0)) == STAR) { + res = validate_test(CHILD(tree, 1)); + } else if (nch == 1) { - res = validate_test_or_star_expr(CHILD(tree, 0)); + res = validate_test(CHILD(tree, 0)); } else if (nch == 2) { res = (validate_test(CHILD(tree, 0)) diff --git a/Python/ast.c b/Python/ast.c index bb28437ae2f..b572088a46c 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -2664,45 +2664,44 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) expr_ty e; node *chch = CHILD(ch, 0); if (NCH(ch) == 1) { - if (TYPE(chch) == star_expr) { - /* an iterable argument unpacking */ - expr_ty starred; + /* a positional argument */ + if (nkeywords) { if (ndoublestars) { ast_error(c, chch, - "iterable argument unpacking follows " + "positional argument follows " "keyword argument unpacking"); - return NULL; } - e = ast_for_expr(c, CHILD(chch, 1)); - if (!e) - return NULL; - starred = Starred(e, Load, LINENO(chch), - chch->n_col_offset, - c->c_arena); - if (!starred) - return NULL; - asdl_seq_SET(args, nargs++, starred); - } - else { - /* a positional argument */ - if (nkeywords) { - if (ndoublestars) { - ast_error(c, chch, - "positional argument follows " - "keyword argument unpacking"); - } - else { - ast_error(c, chch, - "positional argument follows " - "keyword argument"); - } - return NULL; + else { + ast_error(c, chch, + "positional argument follows " + "keyword argument"); } - e = ast_for_expr(c, chch); - if (!e) - return NULL; - asdl_seq_SET(args, nargs++, e); + return NULL; } + e = ast_for_expr(c, chch); + if (!e) + return NULL; + asdl_seq_SET(args, nargs++, e); + } + else if (TYPE(chch) == STAR) { + /* an iterable argument unpacking */ + expr_ty starred; + if (ndoublestars) { + ast_error(c, chch, + "iterable argument unpacking follows " + "keyword argument unpacking"); + return NULL; + } + e = ast_for_expr(c, CHILD(ch, 1)); + if (!e) + return NULL; + starred = Starred(e, Load, LINENO(chch), + chch->n_col_offset, + c->c_arena); + if (!starred) + return NULL; + asdl_seq_SET(args, nargs++, starred); + } else if (TYPE(chch) == DOUBLESTAR) { /* a keyword argument unpacking */ diff --git a/Python/graminit.c b/Python/graminit.c index 14ac24f633c..8212b2a5844 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -1744,7 +1744,7 @@ static state states_77[3] = { static arc arcs_78_0[3] = { {26, 1}, {34, 2}, - {50, 3}, + {33, 2}, }; static arc arcs_78_1[3] = { {164, 3},