Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1c91707

Browse files
committed
Very subtle syntax change: in a list comprehension, the testlist in
"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)+ [',']]
1 parent 69c0ff3 commit 1c91707

5 files changed

Lines changed: 150 additions & 111 deletions

File tree

Grammar/Grammar

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
8989
sliceop: ':' [test]
9090
exprlist: expr (',' expr)* [',']
9191
testlist: test (',' test)* [',']
92+
testlist_safe: test [(',' test)+ [',']]
9293
dictmaker: test ':' test (',' test ':' test)* [',']
9394

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

99100
list_iter: list_for | list_if
100-
list_for: 'for' exprlist 'in' testlist [list_iter]
101+
list_for: 'for' exprlist 'in' testlist_safe [list_iter]
101102
list_if: 'if' test [list_iter]

Include/graminit.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@
5656
#define sliceop 311
5757
#define exprlist 312
5858
#define testlist 313
59-
#define dictmaker 314
60-
#define classdef 315
61-
#define arglist 316
62-
#define argument 317
63-
#define list_iter 318
64-
#define list_for 319
65-
#define list_if 320
59+
#define testlist_safe 314
60+
#define dictmaker 315
61+
#define classdef 316
62+
#define arglist 317
63+
#define argument 318
64+
#define list_iter 319
65+
#define list_for 320
66+
#define list_if 321

Modules/parsermodule.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,14 @@ validate_testlist(node *tree)
10391039
}
10401040

10411041

1042+
static int
1043+
validate_testlist_safe(node *tree)
1044+
{
1045+
return (validate_repeating_list(tree, testlist_safe,
1046+
validate_test, "testlist_safe"));
1047+
}
1048+
1049+
10421050
/* '*' NAME [',' '**' NAME] | '**' NAME
10431051
*/
10441052
static int
@@ -1218,7 +1226,7 @@ validate_list_for(node *tree)
12181226
res = (validate_name(CHILD(tree, 0), "for")
12191227
&& validate_exprlist(CHILD(tree, 1))
12201228
&& validate_name(CHILD(tree, 2), "in")
1221-
&& validate_testlist(CHILD(tree, 3)));
1229+
&& validate_testlist_safe(CHILD(tree, 3)));
12221230

12231231
return res;
12241232
}

Python/compile.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3710,6 +3710,7 @@ com_node(struct compiling *c, node *n)
37103710
/* Expression nodes */
37113711

37123712
case testlist:
3713+
case testlist_safe:
37133714
com_list(c, n, 0);
37143715
break;
37153716
case test:

0 commit comments

Comments
 (0)