Skip to content

Commit

Permalink
Very subtle syntax change: in a list comprehension, the testlist in
Browse files Browse the repository at this point in the history
"for <var> in <testlist> may no longer be a single test followed by
a comma.  This solves SF bug #431886.  Note that if the testlist
contains more than one test, a trailing comma is still allowed, for
maximum backward compatibility; but this example is not:

    [(x, y) for x in range(10), for y in range(10)]
                              ^

The fix involved creating a new nonterminal 'testlist_safe' whose
definition doesn't allow the trailing comma if there's only one test:

    testlist_safe: test [(',' test)+ [',']]
  • Loading branch information
gvanrossum committed Oct 15, 2001
1 parent 69c0ff3 commit 1c91707
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 111 deletions.
3 changes: 2 additions & 1 deletion Grammar/Grammar
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
sliceop: ':' [test]
exprlist: expr (',' expr)* [',']
testlist: test (',' test)* [',']
testlist_safe: test [(',' test)+ [',']]
dictmaker: test ':' test (',' test ':' test)* [',']

classdef: 'class' NAME ['(' testlist ')'] ':' suite
Expand All @@ -97,5 +98,5 @@ arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test)
argument: [test '='] test # Really [keyword '='] test

list_iter: list_for | list_if
list_for: 'for' exprlist 'in' testlist [list_iter]
list_for: 'for' exprlist 'in' testlist_safe [list_iter]
list_if: 'if' test [list_iter]
15 changes: 8 additions & 7 deletions Include/graminit.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@
#define sliceop 311
#define exprlist 312
#define testlist 313
#define dictmaker 314
#define classdef 315
#define arglist 316
#define argument 317
#define list_iter 318
#define list_for 319
#define list_if 320
#define testlist_safe 314
#define dictmaker 315
#define classdef 316
#define arglist 317
#define argument 318
#define list_iter 319
#define list_for 320
#define list_if 321
10 changes: 9 additions & 1 deletion Modules/parsermodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,14 @@ validate_testlist(node *tree)
}


static int
validate_testlist_safe(node *tree)
{
return (validate_repeating_list(tree, testlist_safe,
validate_test, "testlist_safe"));
}


/* '*' NAME [',' '**' NAME] | '**' NAME
*/
static int
Expand Down Expand Up @@ -1218,7 +1226,7 @@ validate_list_for(node *tree)
res = (validate_name(CHILD(tree, 0), "for")
&& validate_exprlist(CHILD(tree, 1))
&& validate_name(CHILD(tree, 2), "in")
&& validate_testlist(CHILD(tree, 3)));
&& validate_testlist_safe(CHILD(tree, 3)));

return res;
}
Expand Down
1 change: 1 addition & 0 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -3710,6 +3710,7 @@ com_node(struct compiling *c, node *n)
/* Expression nodes */

case testlist:
case testlist_safe:
com_list(c, n, 0);
break;
case test:
Expand Down
Loading

0 comments on commit 1c91707

Please sign in to comment.