@@ -130,8 +130,8 @@ atom: ('(' [yield_expr|testlist_gexp] ')' |
130130 '{' [dictsetmaker] '}' |
131131 '`' testlist1 '`' |
132132 NAME | NUMBER | STRING+ | '.' '.' '.')
133- listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
134- testlist_gexp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
133+ listmaker: (test|star_expr) ( old_comp_for | (',' (test|star_expr))* [','] )
134+ testlist_gexp: (test|star_expr) ( old_comp_for | (',' (test|star_expr))* [','] )
135135lambdef: 'lambda' [varargslist] ':' test
136136trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
137137subscriptlist: subscript (',' subscript)* [',']
@@ -161,9 +161,28 @@ argument: ( test [comp_for] |
161161 star_expr )
162162
163163comp_iter: comp_for | comp_if
164- comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [comp_iter]
164+ comp_for: [ASYNC] 'for' exprlist 'in' or_test [comp_iter]
165165comp_if: 'if' old_test [comp_iter]
166166
167+ # As noted above, testlist_safe extends the syntax allowed in list
168+ # comprehensions and generators. We can't use it indiscriminately in all
169+ # derivations using a comp_for-like pattern because the testlist_safe derivation
170+ # contains comma which clashes with trailing comma in arglist.
171+ #
172+ # This was an issue because the parser would not follow the correct derivation
173+ # when parsing syntactically valid Python code. Since testlist_safe was created
174+ # specifically to handle list comprehensions and generator expressions enclosed
175+ # with parentheses, it's safe to only use it in those. That avoids the issue; we
176+ # can parse code like set(x for x in [],).
177+ #
178+ # The syntax supported by this set of rules is not a valid Python 3 syntax,
179+ # hence the prefix "old".
180+ #
181+ # See https://bugs.python.org/issue27494
182+ old_comp_iter: old_comp_for | old_comp_if
183+ old_comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [old_comp_iter]
184+ old_comp_if: 'if' old_test [old_comp_iter]
185+
167186testlist1: test (',' test)*
168187
169188# not used in grammar, but may appear in "node" passed from Parser to Compiler
0 commit comments