Skip to content

Commit 619e7ba

Browse files
committed
#10869: do not visit root node twice in ast.increment_lineno().
1 parent 5b2d9dd commit 619e7ba

File tree

5 files changed

+17
-8
lines changed

5 files changed

+17
-8
lines changed

Doc/library/ast.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ and classes for traversing abstract syntax trees:
173173

174174
.. function:: walk(node)
175175

176-
Recursively yield all child nodes of *node*, in no specified order. This is
177-
useful if you only want to modify nodes in place and don't care about the
178-
context.
176+
Recursively yield all descendant nodes in the tree starting at *node*
177+
(including *node* itself), in no specified order. This is useful if you only
178+
want to modify nodes in place and don't care about the context.
179179

180180

181181
.. class:: NodeVisitor()

Lib/ast.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,6 @@ def increment_lineno(node, n=1):
159159
Increment the line number of each node in the tree starting at *node* by *n*.
160160
This is useful to "move code" to a different location in a file.
161161
"""
162-
if 'lineno' in node._attributes:
163-
node.lineno = getattr(node, 'lineno', 0) + n
164162
for child in walk(node):
165163
if 'lineno' in child._attributes:
166164
child.lineno = getattr(child, 'lineno', 0) + n
@@ -211,9 +209,9 @@ def get_docstring(node, clean=True):
211209

212210
def walk(node):
213211
"""
214-
Recursively yield all child nodes of *node*, in no specified order. This is
215-
useful if you only want to modify nodes in place and don't care about the
216-
context.
212+
Recursively yield all descendant nodes in the tree starting at *node*
213+
(including *node* itself), in no specified order. This is useful if you
214+
only want to modify nodes in place and don't care about the context.
217215
"""
218216
from collections import deque
219217
todo = deque([node])

Lib/test/test_ast.py

+7
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,13 @@ def test_increment_lineno(self):
264264
'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, '
265265
'col_offset=0))'
266266
)
267+
# issue10869: do not increment lineno of root twice
268+
self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
269+
self.assertEqual(ast.dump(src, include_attributes=True),
270+
'Expression(body=BinOp(left=Num(n=1, lineno=4, col_offset=0), '
271+
'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, '
272+
'col_offset=0))'
273+
)
267274

268275
def test_iter_fields(self):
269276
node = ast.parse('foo()', mode='eval')

Misc/ACKS

+1
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,7 @@ Cliff Wells
905905
Rickard Westman
906906
Jeff Wheeler
907907
Christopher White
908+
David White
908909
Mats Wichmann
909910
Truida Wiedijk
910911
Felix Wiemann

Misc/NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ Core and Builtins
4040
Library
4141
-------
4242

43+
- Issue #10869: Fixed bug where ast.increment_lineno modified the root
44+
node twice.
45+
4346
- Issue #5871: email.header.Header.encode now raises an error if any
4447
continuation line in the formatted value has no leading white space
4548
and looks like a header. Since Generator uses Header to format all

0 commit comments

Comments
 (0)