Skip to content

Commit 9ecbe33

Browse files
Revert "closes bpo-27494: Fix 2to3 handling of trailing comma after a generator expression (GH-3771)" (GH-8241)
This reverts commit af810b3. This is not valid syntax (see bpo-32012). (cherry picked from commit 4b8a7f5) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent a621f40 commit 9ecbe33

File tree

7 files changed

+12
-36
lines changed

7 files changed

+12
-36
lines changed

Lib/lib2to3/Grammar.txt

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ atom: ('(' [yield_expr|testlist_gexp] ')' |
111111
'{' [dictsetmaker] '}' |
112112
'`' testlist1 '`' |
113113
NAME | NUMBER | STRING+ | '.' '.' '.')
114-
listmaker: (test|star_expr) ( old_comp_for | (',' (test|star_expr))* [','] )
115-
testlist_gexp: (test|star_expr) ( old_comp_for | (',' (test|star_expr))* [','] )
114+
listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
115+
testlist_gexp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
116116
lambdef: 'lambda' [varargslist] ':' test
117117
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
118118
subscriptlist: subscript (',' subscript)* [',']
@@ -142,28 +142,9 @@ argument: ( test [comp_for] |
142142
star_expr )
143143

144144
comp_iter: comp_for | comp_if
145-
comp_for: [ASYNC] 'for' exprlist 'in' or_test [comp_iter]
145+
comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [comp_iter]
146146
comp_if: 'if' old_test [comp_iter]
147147

148-
# As noted above, testlist_safe extends the syntax allowed in list
149-
# comprehensions and generators. We can't use it indiscriminately in all
150-
# derivations using a comp_for-like pattern because the testlist_safe derivation
151-
# contains comma which clashes with trailing comma in arglist.
152-
#
153-
# This was an issue because the parser would not follow the correct derivation
154-
# when parsing syntactically valid Python code. Since testlist_safe was created
155-
# specifically to handle list comprehensions and generator expressions enclosed
156-
# with parentheses, it's safe to only use it in those. That avoids the issue; we
157-
# can parse code like set(x for x in [],).
158-
#
159-
# The syntax supported by this set of rules is not a valid Python 3 syntax,
160-
# hence the prefix "old".
161-
#
162-
# See https://bugs.python.org/issue27494
163-
old_comp_iter: old_comp_for | old_comp_if
164-
old_comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [old_comp_iter]
165-
old_comp_if: 'if' old_test [old_comp_iter]
166-
167148
testlist1: test (',' test)*
168149

169150
# not used in grammar, but may appear in "node" passed from Parser to Compiler

Lib/lib2to3/fixer_util.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ def ListComp(xp, fp, it, test=None):
101101
test.prefix = " "
102102
if_leaf = Leaf(token.NAME, "if")
103103
if_leaf.prefix = " "
104-
inner_args.append(Node(syms.old_comp_if, [if_leaf, test]))
105-
inner = Node(syms.listmaker, [xp, Node(syms.old_comp_for, inner_args)])
104+
inner_args.append(Node(syms.comp_if, [if_leaf, test]))
105+
inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)])
106106
return Node(syms.atom,
107107
[Leaf(token.LBRACE, "["),
108108
inner,
@@ -208,7 +208,7 @@ def attr_chain(obj, attr):
208208
next = getattr(next, attr)
209209

210210
p0 = """for_stmt< 'for' any 'in' node=any ':' any* >
211-
| old_comp_for< 'for' any 'in' node=any any* >
211+
| comp_for< 'for' any 'in' node=any any* >
212212
"""
213213
p1 = """
214214
power<

Lib/lib2to3/fixes/fix_dict.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def transform(self, node, results):
8383
p1 = patcomp.compile_pattern(P1)
8484

8585
P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
86-
| old_comp_for< 'for' any 'in' node=any any* >
86+
| comp_for< 'for' any 'in' node=any any* >
8787
"""
8888
p2 = patcomp.compile_pattern(P2)
8989

Lib/lib2to3/fixes/fix_paren.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class FixParen(fixer_base.BaseFix):
1515
PATTERN = """
1616
atom< ('[' | '(')
1717
(listmaker< any
18-
old_comp_for<
18+
comp_for<
1919
'for' NAME 'in'
2020
target=testlist_safe< any (',' any)+ [',']
2121
>
@@ -24,7 +24,7 @@ class FixParen(fixer_base.BaseFix):
2424
>
2525
|
2626
testlist_gexp< any
27-
old_comp_for<
27+
comp_for<
2828
'for' NAME 'in'
2929
target=testlist_safe< any (',' any)+ [',']
3030
>

Lib/lib2to3/fixes/fix_xrange.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def transform_range(self, node, results):
5555
p1 = patcomp.compile_pattern(P1)
5656

5757
P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
58-
| old_comp_for< 'for' any 'in' node=any any* >
58+
| comp_for< 'for' any 'in' node=any any* >
5959
| comparison< any 'in' node=any any*>
6060
"""
6161
p2 = patcomp.compile_pattern(P2)

Lib/lib2to3/tests/test_parser.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -612,13 +612,6 @@ def test_multiline_str_literals(self):
612612
self.validate(s)
613613

614614

615-
class TestGeneratorExpressions(GrammarTest):
616-
617-
def test_trailing_comma_after_generator_expression_argument_works(self):
618-
# BPO issue 27494
619-
self.validate("set(x for x in [],)")
620-
621-
622615
def diff_texts(a, b, filename):
623616
a = a.splitlines()
624617
b = b.splitlines()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Reverted :issue:`27494`. 2to3 rejects now a trailing comma in generator
2+
expressions.

0 commit comments

Comments
 (0)