Skip to content

Commit 4905e80

Browse files
committed
fix an ambiguity in the grammar from the implementation of extended unpacking
(one which was strangely "resolved" by pgen) This also kills the unused testlist1 rule and fixes parse tree validation of extended unpacking.
1 parent 10430ad commit 4905e80

File tree

8 files changed

+1039
-1005
lines changed

8 files changed

+1039
-1005
lines changed

‎Grammar/Grammar‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ stmt: simple_stmt | compound_stmt
3737
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
3838
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
3939
import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
40-
expr_stmt: testlist (augassign (yield_expr|testlist) |
41-
('=' (yield_expr|testlist))*)
40+
expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
41+
('=' (yield_expr|testlist_star_expr))*)
42+
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
4243
augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
4344
'<<=' | '>>=' | '**=' | '//=')
4445
# For normal assignments, additional restrictions enforced by the interpreter
@@ -86,9 +87,9 @@ lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
8687
or_test: and_test ('or' and_test)*
8788
and_test: not_test ('and' not_test)*
8889
not_test: 'not' not_test | comparison
89-
comparison: star_expr (comp_op star_expr)*
90+
comparison: expr (comp_op expr)*
9091
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
91-
star_expr: ['*'] expr
92+
star_expr: '*' expr
9293
expr: xor_expr ('|' xor_expr)*
9394
xor_expr: and_expr ('^' and_expr)*
9495
and_expr: shift_expr ('&' shift_expr)*
@@ -101,12 +102,12 @@ atom: ('(' [yield_expr|testlist_comp] ')' |
101102
'[' [testlist_comp] ']' |
102103
'{' [dictorsetmaker] '}' |
103104
NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
104-
testlist_comp: test ( comp_for | (',' test)* [','] )
105+
testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
105106
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
106107
subscriptlist: subscript (',' subscript)* [',']
107108
subscript: test | [test] ':' [test] [sliceop]
108109
sliceop: ':' [test]
109-
exprlist: star_expr (',' star_expr)* [',']
110+
exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
110111
testlist: test (',' test)* [',']
111112
dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
112113
(test (comp_for | (',' test)* [','])) )
@@ -123,8 +124,6 @@ comp_iter: comp_for | comp_if
123124
comp_for: 'for' exprlist 'in' or_test [comp_iter]
124125
comp_if: 'if' test_nocond [comp_iter]
125126

126-
testlist1: test (',' test)*
127-
128127
# not used in grammar, but may appear in "node" passed from Parser to Compiler
129128
encoding_decl: NAME
130129

‎Include/graminit.h‎

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,68 +16,68 @@
1616
#define simple_stmt 269
1717
#define small_stmt 270
1818
#define expr_stmt 271
19-
#define augassign 272
20-
#define del_stmt 273
21-
#define pass_stmt 274
22-
#define flow_stmt 275
23-
#define break_stmt 276
24-
#define continue_stmt 277
25-
#define return_stmt 278
26-
#define yield_stmt 279
27-
#define raise_stmt 280
28-
#define import_stmt 281
29-
#define import_name 282
30-
#define import_from 283
31-
#define import_as_name 284
32-
#define dotted_as_name 285
33-
#define import_as_names 286
34-
#define dotted_as_names 287
35-
#define dotted_name 288
36-
#define global_stmt 289
37-
#define nonlocal_stmt 290
38-
#define assert_stmt 291
39-
#define compound_stmt 292
40-
#define if_stmt 293
41-
#define while_stmt 294
42-
#define for_stmt 295
43-
#define try_stmt 296
44-
#define with_stmt 297
45-
#define with_item 298
46-
#define except_clause 299
47-
#define suite 300
48-
#define test 301
49-
#define test_nocond 302
50-
#define lambdef 303
51-
#define lambdef_nocond 304
52-
#define or_test 305
53-
#define and_test 306
54-
#define not_test 307
55-
#define comparison 308
56-
#define comp_op 309
57-
#define star_expr 310
58-
#define expr 311
59-
#define xor_expr 312
60-
#define and_expr 313
61-
#define shift_expr 314
62-
#define arith_expr 315
63-
#define term 316
64-
#define factor 317
65-
#define power 318
66-
#define atom 319
67-
#define testlist_comp 320
68-
#define trailer 321
69-
#define subscriptlist 322
70-
#define subscript 323
71-
#define sliceop 324
72-
#define exprlist 325
73-
#define testlist 326
74-
#define dictorsetmaker 327
75-
#define classdef 328
76-
#define arglist 329
77-
#define argument 330
78-
#define comp_iter 331
79-
#define comp_for 332
80-
#define comp_if 333
81-
#define testlist1 334
19+
#define testlist_star_expr 272
20+
#define augassign 273
21+
#define del_stmt 274
22+
#define pass_stmt 275
23+
#define flow_stmt 276
24+
#define break_stmt 277
25+
#define continue_stmt 278
26+
#define return_stmt 279
27+
#define yield_stmt 280
28+
#define raise_stmt 281
29+
#define import_stmt 282
30+
#define import_name 283
31+
#define import_from 284
32+
#define import_as_name 285
33+
#define dotted_as_name 286
34+
#define import_as_names 287
35+
#define dotted_as_names 288
36+
#define dotted_name 289
37+
#define global_stmt 290
38+
#define nonlocal_stmt 291
39+
#define assert_stmt 292
40+
#define compound_stmt 293
41+
#define if_stmt 294
42+
#define while_stmt 295
43+
#define for_stmt 296
44+
#define try_stmt 297
45+
#define with_stmt 298
46+
#define with_item 299
47+
#define except_clause 300
48+
#define suite 301
49+
#define test 302
50+
#define test_nocond 303
51+
#define lambdef 304
52+
#define lambdef_nocond 305
53+
#define or_test 306
54+
#define and_test 307
55+
#define not_test 308
56+
#define comparison 309
57+
#define comp_op 310
58+
#define star_expr 311
59+
#define expr 312
60+
#define xor_expr 313
61+
#define and_expr 314
62+
#define shift_expr 315
63+
#define arith_expr 316
64+
#define term 317
65+
#define factor 318
66+
#define power 319
67+
#define atom 320
68+
#define testlist_comp 321
69+
#define trailer 322
70+
#define subscriptlist 323
71+
#define subscript 324
72+
#define sliceop 325
73+
#define exprlist 326
74+
#define testlist 327
75+
#define dictorsetmaker 328
76+
#define classdef 329
77+
#define arglist 330
78+
#define argument 331
79+
#define comp_iter 332
80+
#define comp_for 333
81+
#define comp_if 334
8282
#define encoding_decl 335
8383
#define yield_expr 336

‎Lib/symbol.py‎

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -26,69 +26,69 @@
2626
simple_stmt = 269
2727
small_stmt = 270
2828
expr_stmt = 271
29-
augassign = 272
30-
del_stmt = 273
31-
pass_stmt = 274
32-
flow_stmt = 275
33-
break_stmt = 276
34-
continue_stmt = 277
35-
return_stmt = 278
36-
yield_stmt = 279
37-
raise_stmt = 280
38-
import_stmt = 281
39-
import_name = 282
40-
import_from = 283
41-
import_as_name = 284
42-
dotted_as_name = 285
43-
import_as_names = 286
44-
dotted_as_names = 287
45-
dotted_name = 288
46-
global_stmt = 289
47-
nonlocal_stmt = 290
48-
assert_stmt = 291
49-
compound_stmt = 292
50-
if_stmt = 293
51-
while_stmt = 294
52-
for_stmt = 295
53-
try_stmt = 296
54-
with_stmt = 297
55-
with_item = 298
56-
except_clause = 299
57-
suite = 300
58-
test = 301
59-
test_nocond = 302
60-
lambdef = 303
61-
lambdef_nocond = 304
62-
or_test = 305
63-
and_test = 306
64-
not_test = 307
65-
comparison = 308
66-
comp_op = 309
67-
star_expr = 310
68-
expr = 311
69-
xor_expr = 312
70-
and_expr = 313
71-
shift_expr = 314
72-
arith_expr = 315
73-
term = 316
74-
factor = 317
75-
power = 318
76-
atom = 319
77-
testlist_comp = 320
78-
trailer = 321
79-
subscriptlist = 322
80-
subscript = 323
81-
sliceop = 324
82-
exprlist = 325
83-
testlist = 326
84-
dictorsetmaker = 327
85-
classdef = 328
86-
arglist = 329
87-
argument = 330
88-
comp_iter = 331
89-
comp_for = 332
90-
comp_if = 333
91-
testlist1 = 334
29+
testlist_star_expr = 272
30+
augassign = 273
31+
del_stmt = 274
32+
pass_stmt = 275
33+
flow_stmt = 276
34+
break_stmt = 277
35+
continue_stmt = 278
36+
return_stmt = 279
37+
yield_stmt = 280
38+
raise_stmt = 281
39+
import_stmt = 282
40+
import_name = 283
41+
import_from = 284
42+
import_as_name = 285
43+
dotted_as_name = 286
44+
import_as_names = 287
45+
dotted_as_names = 288
46+
dotted_name = 289
47+
global_stmt = 290
48+
nonlocal_stmt = 291
49+
assert_stmt = 292
50+
compound_stmt = 293
51+
if_stmt = 294
52+
while_stmt = 295
53+
for_stmt = 296
54+
try_stmt = 297
55+
with_stmt = 298
56+
with_item = 299
57+
except_clause = 300
58+
suite = 301
59+
test = 302
60+
test_nocond = 303
61+
lambdef = 304
62+
lambdef_nocond = 305
63+
or_test = 306
64+
and_test = 307
65+
not_test = 308
66+
comparison = 309
67+
comp_op = 310
68+
star_expr = 311
69+
expr = 312
70+
xor_expr = 313
71+
and_expr = 314
72+
shift_expr = 315
73+
arith_expr = 316
74+
term = 317
75+
factor = 318
76+
power = 319
77+
atom = 320
78+
testlist_comp = 321
79+
trailer = 322
80+
subscriptlist = 323
81+
subscript = 324
82+
sliceop = 325
83+
exprlist = 326
84+
testlist = 327
85+
dictorsetmaker = 328
86+
classdef = 329
87+
arglist = 330
88+
argument = 331
89+
comp_iter = 332
90+
comp_for = 333
91+
comp_if = 334
9292
encoding_decl = 335
9393
yield_expr = 336
9494
#--end constants--

‎Lib/test/test_parser.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ def walk(tree):
242242
(0, '', 2, -1)],
243243
terminals)
244244

245+
def test_extended_unpacking(self):
246+
self.check_suite("*a = y")
247+
self.check_suite("x, *b, = m")
248+
self.check_suite("[*a, *b] = y")
249+
self.check_suite("for [*x, b] in x: pass")
250+
245251

246252
#
247253
# Second, we take *invalid* trees and make sure we get ParserError

‎Misc/NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ What's New in Python 3.2 Alpha 1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #5460: Fix an ambiguity in the grammar.
16+
1517
- Issue #1766304: Improve performance of membership tests on range objects.
1618

1719
- Issue #6713: Improve performance of integer -> string conversions.

0 commit comments

Comments
 (0)