Skip to content

Commit 49c5da1

Browse files
committed
Patch #1440601: Add col_offset attribute to AST nodes.
1 parent 3ffa59b commit 49c5da1

File tree

16 files changed

+382
-244
lines changed

16 files changed

+382
-244
lines changed

Doc/lib/libast.tex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,13 @@ \chapter{Abstract Syntax Trees\label{ast}}
3434

3535
Each instance of a concrete class has one attribute for each child node,
3636
of the type as defined in the grammar. For example, \code{_ast.BinOp}
37-
instances have an attribute \code{left} of type \code{_ast.expr}.
37+
instances have an attribute \code{left} of type \code{_ast.expr}.
38+
Instances of \code{_ast.expr} and \code{_ast.stmt} subclasses also
39+
have lineno and col_offset attributes. The lineno is the line number
40+
of source text (1 indexed so the first line is line 1) and the
41+
col_offset is the utf8 byte offset of the first token that generated
42+
the node. The utf8 offset is recorded because the parser uses utf8
43+
internally.
3844

3945
If these attributes are marked as optional in the grammar (using a
4046
question mark), the value might be \code{None}. If the attributes

Include/Python-ast.h

Lines changed: 65 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ struct _stmt {
178178

179179
} v;
180180
int lineno;
181+
int col_offset;
181182
};
182183

183184
struct _expr {
@@ -288,6 +289,7 @@ struct _expr {
288289

289290
} v;
290291
int lineno;
292+
int col_offset;
291293
};
292294

293295
struct _slice {
@@ -346,68 +348,79 @@ mod_ty Interactive(asdl_seq * body, PyArena *arena);
346348
mod_ty Expression(expr_ty body, PyArena *arena);
347349
mod_ty Suite(asdl_seq * body, PyArena *arena);
348350
stmt_ty FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
349-
asdl_seq * decorators, int lineno, PyArena *arena);
351+
asdl_seq * decorators, int lineno, int col_offset, PyArena
352+
*arena);
350353
stmt_ty ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int
351-
lineno, PyArena *arena);
352-
stmt_ty Return(expr_ty value, int lineno, PyArena *arena);
353-
stmt_ty Delete(asdl_seq * targets, int lineno, PyArena *arena);
354-
stmt_ty Assign(asdl_seq * targets, expr_ty value, int lineno, PyArena *arena);
354+
lineno, int col_offset, PyArena *arena);
355+
stmt_ty Return(expr_ty value, int lineno, int col_offset, PyArena *arena);
356+
stmt_ty Delete(asdl_seq * targets, int lineno, int col_offset, PyArena *arena);
357+
stmt_ty Assign(asdl_seq * targets, expr_ty value, int lineno, int col_offset,
358+
PyArena *arena);
355359
stmt_ty AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno,
356-
PyArena *arena);
357-
stmt_ty Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, PyArena
358-
*arena);
360+
int col_offset, PyArena *arena);
361+
stmt_ty Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int
362+
col_offset, PyArena *arena);
359363
stmt_ty For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse,
360-
int lineno, PyArena *arena);
361-
stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
362-
PyArena *arena);
363-
stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
364-
PyArena *arena);
364+
int lineno, int col_offset, PyArena *arena);
365+
stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
366+
col_offset, PyArena *arena);
367+
stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
368+
col_offset, PyArena *arena);
365369
stmt_ty With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int
366-
lineno, PyArena *arena);
367-
stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena
368-
*arena);
370+
lineno, int col_offset, PyArena *arena);
371+
stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int
372+
col_offset, PyArena *arena);
369373
stmt_ty TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int
370-
lineno, PyArena *arena);
371-
stmt_ty TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, PyArena
372-
*arena);
373-
stmt_ty Assert(expr_ty test, expr_ty msg, int lineno, PyArena *arena);
374-
stmt_ty Import(asdl_seq * names, int lineno, PyArena *arena);
374+
lineno, int col_offset, PyArena *arena);
375+
stmt_ty TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int
376+
col_offset, PyArena *arena);
377+
stmt_ty Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, PyArena
378+
*arena);
379+
stmt_ty Import(asdl_seq * names, int lineno, int col_offset, PyArena *arena);
375380
stmt_ty ImportFrom(identifier module, asdl_seq * names, int level, int lineno,
376-
PyArena *arena);
377-
stmt_ty Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, PyArena
378-
*arena);
379-
stmt_ty Global(asdl_seq * names, int lineno, PyArena *arena);
380-
stmt_ty Expr(expr_ty value, int lineno, PyArena *arena);
381-
stmt_ty Pass(int lineno, PyArena *arena);
382-
stmt_ty Break(int lineno, PyArena *arena);
383-
stmt_ty Continue(int lineno, PyArena *arena);
384-
expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno, PyArena *arena);
385-
expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, PyArena
386-
*arena);
387-
expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno, PyArena *arena);
388-
expr_ty Lambda(arguments_ty args, expr_ty body, int lineno, PyArena *arena);
389-
expr_ty IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, PyArena
390-
*arena);
391-
expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno, PyArena *arena);
392-
expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno, PyArena
393-
*arena);
394-
expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, PyArena
395-
*arena);
396-
expr_ty Yield(expr_ty value, int lineno, PyArena *arena);
381+
int col_offset, PyArena *arena);
382+
stmt_ty Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, int
383+
col_offset, PyArena *arena);
384+
stmt_ty Global(asdl_seq * names, int lineno, int col_offset, PyArena *arena);
385+
stmt_ty Expr(expr_ty value, int lineno, int col_offset, PyArena *arena);
386+
stmt_ty Pass(int lineno, int col_offset, PyArena *arena);
387+
stmt_ty Break(int lineno, int col_offset, PyArena *arena);
388+
stmt_ty Continue(int lineno, int col_offset, PyArena *arena);
389+
expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset,
390+
PyArena *arena);
391+
expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int
392+
col_offset, PyArena *arena);
393+
expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset,
394+
PyArena *arena);
395+
expr_ty Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset,
396+
PyArena *arena);
397+
expr_ty IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int
398+
col_offset, PyArena *arena);
399+
expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset,
400+
PyArena *arena);
401+
expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno, int
402+
col_offset, PyArena *arena);
403+
expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int
404+
col_offset, PyArena *arena);
405+
expr_ty Yield(expr_ty value, int lineno, int col_offset, PyArena *arena);
397406
expr_ty Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int
398-
lineno, PyArena *arena);
407+
lineno, int col_offset, PyArena *arena);
399408
expr_ty Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty
400-
starargs, expr_ty kwargs, int lineno, PyArena *arena);
401-
expr_ty Repr(expr_ty value, int lineno, PyArena *arena);
402-
expr_ty Num(object n, int lineno, PyArena *arena);
403-
expr_ty Str(string s, int lineno, PyArena *arena);
409+
starargs, expr_ty kwargs, int lineno, int col_offset, PyArena
410+
*arena);
411+
expr_ty Repr(expr_ty value, int lineno, int col_offset, PyArena *arena);
412+
expr_ty Num(object n, int lineno, int col_offset, PyArena *arena);
413+
expr_ty Str(string s, int lineno, int col_offset, PyArena *arena);
404414
expr_ty Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
405-
lineno, PyArena *arena);
415+
lineno, int col_offset, PyArena *arena);
406416
expr_ty Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int
407-
lineno, PyArena *arena);
408-
expr_ty Name(identifier id, expr_context_ty ctx, int lineno, PyArena *arena);
409-
expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena);
410-
expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena);
417+
lineno, int col_offset, PyArena *arena);
418+
expr_ty Name(identifier id, expr_context_ty ctx, int lineno, int col_offset,
419+
PyArena *arena);
420+
expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset,
421+
PyArena *arena);
422+
expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset,
423+
PyArena *arena);
411424
slice_ty Ellipsis(PyArena *arena);
412425
slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena);
413426
slice_ty ExtSlice(asdl_seq * dims, PyArena *arena);

Include/node.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ typedef struct _node {
1111
short n_type;
1212
char *n_str;
1313
int n_lineno;
14+
int n_col_offset;
1415
int n_nchildren;
1516
struct _node *n_child;
1617
} node;
1718

1819
PyAPI_FUNC(node *) PyNode_New(int type);
1920
PyAPI_FUNC(int) PyNode_AddChild(node *n, int type,
20-
char *str, int lineno);
21+
char *str, int lineno, int col_offset);
2122
PyAPI_FUNC(void) PyNode_Free(node *n);
2223

2324
/* Node access functions */

Lib/test/test_ast.py

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import sys, itertools
2+
import _ast
23

34
def to_tuple(t):
45
if t is None or isinstance(t, (basestring, int, long, complex)):
56
return t
67
elif isinstance(t, list):
78
return [to_tuple(e) for e in t]
89
result = [t.__class__.__name__]
10+
if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
11+
result.append((t.lineno, t.col_offset))
912
if t._fields is None:
1013
return tuple(result)
1114
for f in t._fields:
@@ -106,7 +109,10 @@ def to_tuple(t):
106109
# List
107110
"[1,2,3]",
108111
# Tuple
109-
"1,2,3"
112+
"1,2,3",
113+
# Combination
114+
"a.b.c.d(a.b[1:2])",
115+
110116
]
111117

112118
# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
@@ -121,58 +127,77 @@ def to_tuple(t):
121127
print "run_tests()"
122128
raise SystemExit
123129

130+
def test_order(ast_node, parent_pos):
131+
132+
if not isinstance(ast_node, _ast.AST) or ast_node._fields == None:
133+
return
134+
if isinstance(ast_node, (_ast.expr, _ast.stmt)):
135+
node_pos = (ast_node.lineno, ast_node.col_offset)
136+
assert node_pos >= parent_pos, (node_pos, parent_pos)
137+
parent_pos = (ast_node.lineno, ast_node.col_offset)
138+
for name in ast_node._fields:
139+
value = getattr(ast_node, name)
140+
if isinstance(value, list):
141+
for child in value:
142+
test_order(child, parent_pos)
143+
elif value != None:
144+
test_order(value, parent_pos)
145+
124146
def run_tests():
125147
for input, output, kind in ((exec_tests, exec_results, "exec"),
126148
(single_tests, single_results, "single"),
127149
(eval_tests, eval_results, "eval")):
128150
for i, o in itertools.izip(input, output):
129-
assert to_tuple(compile(i, "?", kind, 0x400)) == o
151+
ast_tree = compile(i, "?", kind, 0x400)
152+
assert to_tuple(ast_tree) == o
153+
test_order(ast_tree, (0, 0))
130154

131155
#### EVERYTHING BELOW IS GENERATED #####
132156
exec_results = [
133-
('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Pass',)], [])]),
134-
('Module', [('ClassDef', 'C', [], [('Pass',)])]),
135-
('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Return', ('Num', 1))], [])]),
136-
('Module', [('Delete', [('Name', 'v', ('Del',))])]),
137-
('Module', [('Assign', [('Name', 'v', ('Store',))], ('Num', 1))]),
138-
('Module', [('AugAssign', ('Name', 'v', ('Load',)), ('Add',), ('Num', 1))]),
139-
('Module', [('Print', ('Name', 'f', ('Load',)), [('Num', 1)], False)]),
140-
('Module', [('For', ('Name', 'v', ('Store',)), ('Name', 'v', ('Load',)), [('Pass',)], [])]),
141-
('Module', [('While', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
142-
('Module', [('If', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
143-
('Module', [('Raise', ('Name', 'Exception', ('Load',)), ('Str', 'string'), None)]),
144-
('Module', [('TryExcept', [('Pass',)], [('excepthandler', ('Name', 'Exception', ('Load',)), None, [('Pass',)])], [])]),
145-
('Module', [('TryFinally', [('Pass',)], [('Pass',)])]),
146-
('Module', [('Assert', ('Name', 'v', ('Load',)), None)]),
147-
('Module', [('Import', [('alias', 'sys', None)])]),
148-
('Module', [('ImportFrom', 'sys', [('alias', 'v', None)], 0)]),
149-
('Module', [('Exec', ('Str', 'v'), None, None)]),
150-
('Module', [('Global', ['v'])]),
151-
('Module', [('Expr', ('Num', 1))]),
152-
('Module', [('Pass',)]),
153-
('Module', [('Break',)]),
154-
('Module', [('Continue',)]),
157+
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Pass', (1, 9))], [])]),
158+
('Module', [('ClassDef', (1, 0), 'C', [], [('Pass', (1, 8))])]),
159+
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [])]),
160+
('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
161+
('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]),
162+
('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Load',)), ('Add',), ('Num', (1, 5), 1))]),
163+
('Module', [('Print', (1, 0), ('Name', (1, 8), 'f', ('Load',)), [('Num', (1, 11), 1)], False)]),
164+
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]),
165+
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
166+
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
167+
('Module', [('Raise', (1, 0), ('Name', (1, 6), 'Exception', ('Load',)), ('Str', (1, 17), 'string'), None)]),
168+
('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('excepthandler', ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [])]),
169+
('Module', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]),
170+
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
171+
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
172+
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
173+
('Module', [('Exec', (1, 0), ('Str', (1, 5), 'v'), None, None)]),
174+
('Module', [('Global', (1, 0), ['v'])]),
175+
('Module', [('Expr', (1, 0), ('Num', (1, 0), 1))]),
176+
('Module', [('Pass', (1, 0))]),
177+
('Module', [('Break', (1, 0))]),
178+
('Module', [('Continue', (1, 0))]),
155179
]
156180
single_results = [
157-
('Interactive', [('Expr', ('BinOp', ('Num', 1), ('Add',), ('Num', 2)))]),
181+
('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),
158182
]
159183
eval_results = [
160-
('Expression', ('BoolOp', ('And',), [('Name', 'a', ('Load',)), ('Name', 'b', ('Load',))])),
161-
('Expression', ('BinOp', ('Name', 'a', ('Load',)), ('Add',), ('Name', 'b', ('Load',)))),
162-
('Expression', ('UnaryOp', ('Not',), ('Name', 'v', ('Load',)))),
163-
('Expression', ('Lambda', ('arguments', [], None, None, []), ('Name', 'None', ('Load',)))),
164-
('Expression', ('Dict', [('Num', 1)], [('Num', 2)])),
165-
('Expression', ('ListComp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])),
166-
('Expression', ('GeneratorExp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])),
167-
('Expression', ('Compare', ('Num', 1), [('Lt',), ('Lt',)], [('Num', 2), ('Num', 3)])),
168-
('Expression', ('Call', ('Name', 'f', ('Load',)), [('Num', 1), ('Num', 2)], [('keyword', 'c', ('Num', 3))], ('Name', 'd', ('Load',)), ('Name', 'e', ('Load',)))),
169-
('Expression', ('Repr', ('Name', 'v', ('Load',)))),
170-
('Expression', ('Num', 10L)),
171-
('Expression', ('Str', 'string')),
172-
('Expression', ('Attribute', ('Name', 'a', ('Load',)), 'b', ('Load',))),
173-
('Expression', ('Subscript', ('Name', 'a', ('Load',)), ('Slice', ('Name', 'b', ('Load',)), ('Name', 'c', ('Load',)), None), ('Load',))),
174-
('Expression', ('Name', 'v', ('Load',))),
175-
('Expression', ('List', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
176-
('Expression', ('Tuple', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
184+
('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
185+
('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
186+
('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
187+
('Expression', ('Lambda', (1, 0), ('arguments', [], None, None, []), ('Name', (1, 7), 'None', ('Load',)))),
188+
('Expression', ('Dict', (1, 0), [('Num', (1, 2), 1)], [('Num', (1, 4), 2)])),
189+
('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
190+
('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
191+
('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])),
192+
('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2)], [('keyword', 'c', ('Num', (1, 8), 3))], ('Name', (1, 11), 'd', ('Load',)), ('Name', (1, 15), 'e', ('Load',)))),
193+
('Expression', ('Repr', (1, 0), ('Name', (1, 1), 'v', ('Load',)))),
194+
('Expression', ('Num', (1, 0), 10L)),
195+
('Expression', ('Str', (1, 0), 'string')),
196+
('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
197+
('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))),
198+
('Expression', ('Name', (1, 0), 'v', ('Load',))),
199+
('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))),
200+
('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))),
201+
('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)),
177202
]
178203
run_tests()

Modules/parsermodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
715715
Py_XDECREF(elem);
716716
return (0);
717717
}
718-
err = PyNode_AddChild(root, type, strn, *line_num);
718+
err = PyNode_AddChild(root, type, strn, *line_num, 0);
719719
if (err == E_NOMEM) {
720720
PyMem_DEL(strn);
721721
return (node *) PyErr_NoMemory();

Parser/Python.asdl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ module Python version "$Revision$"
4646
| Pass | Break | Continue
4747

4848
-- XXX Jython will be different
49-
attributes (int lineno)
49+
-- col_offset is the byte offset in the utf8 string the parser uses
50+
attributes (int lineno, int col_offset)
5051

5152
-- BoolOp() can use left & right?
5253
expr = BoolOp(boolop op, expr* values)
@@ -76,7 +77,8 @@ module Python version "$Revision$"
7677
| List(expr* elts, expr_context ctx)
7778
| Tuple(expr *elts, expr_context ctx)
7879

79-
attributes (int lineno)
80+
-- col_offset is the byte offset in the utf8 string the parser uses
81+
attributes (int lineno, int col_offset)
8082

8183
expr_context = Load | Store | Del | AugLoad | AugStore | Param
8284

Parser/asdl.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ def p_type_2(self, (sum, id, _0, attributes, _1)):
156156
if id.value != "attributes":
157157
raise ASDLSyntaxError(id.lineno,
158158
msg="expected attributes, found %s" % id)
159+
if attributes:
160+
attributes.reverse()
159161
return Sum(sum, attributes)
160162

161163
def p_product(self, (_0, fields, _1)):

0 commit comments

Comments
 (0)