[3.8] bpo-40726: handle uninitalized end_lineno on ast.increment_lineno (GH-21745)
…no (GH-20312).
(cherry picked from commit 8f4380d2f5
)
Co-authored-by: Batuhan Taskaya <batuhanosmantaskaya@gmail.com>
Automerge-Triggered-By: @pablogsal
This commit is contained in:
parent
f0e030cacb
commit
b24c9d2b06
18
Lib/ast.py
18
Lib/ast.py
|
@ -144,9 +144,14 @@ def copy_location(new_node, old_node):
|
|||
attributes) from *old_node* to *new_node* if possible, and return *new_node*.
|
||||
"""
|
||||
for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset':
|
||||
if attr in old_node._attributes and attr in new_node._attributes \
|
||||
and hasattr(old_node, attr):
|
||||
setattr(new_node, attr, getattr(old_node, attr))
|
||||
if attr in old_node._attributes and attr in new_node._attributes:
|
||||
value = getattr(old_node, attr, None)
|
||||
# end_lineno and end_col_offset are optional attributes, and they
|
||||
# should be copied whether the value is None or not.
|
||||
if value is not None or (
|
||||
hasattr(old_node, attr) and attr.startswith("end_")
|
||||
):
|
||||
setattr(new_node, attr, value)
|
||||
return new_node
|
||||
|
||||
|
||||
|
@ -194,8 +199,11 @@ def increment_lineno(node, n=1):
|
|||
for child in walk(node):
|
||||
if 'lineno' in child._attributes:
|
||||
child.lineno = getattr(child, 'lineno', 0) + n
|
||||
if 'end_lineno' in child._attributes:
|
||||
child.end_lineno = getattr(child, 'end_lineno', 0) + n
|
||||
if (
|
||||
"end_lineno" in child._attributes
|
||||
and (end_lineno := getattr(child, "end_lineno", 0)) is not None
|
||||
):
|
||||
child.end_lineno = end_lineno + n
|
||||
return node
|
||||
|
||||
|
||||
|
|
|
@ -718,6 +718,15 @@ class ASTHelpers_Test(unittest.TestCase):
|
|||
'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
|
||||
'col_offset=0, end_lineno=1, end_col_offset=5))'
|
||||
)
|
||||
src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1)
|
||||
new = ast.copy_location(src, ast.Call(
|
||||
col_offset=None, lineno=None,
|
||||
end_lineno=None, end_col_offset=None
|
||||
))
|
||||
self.assertIsNone(new.end_lineno)
|
||||
self.assertIsNone(new.end_col_offset)
|
||||
self.assertEqual(new.lineno, 1)
|
||||
self.assertEqual(new.col_offset, 1)
|
||||
|
||||
def test_fix_missing_locations(self):
|
||||
src = ast.parse('write("spam")')
|
||||
|
@ -757,6 +766,12 @@ class ASTHelpers_Test(unittest.TestCase):
|
|||
'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
|
||||
'col_offset=0, end_lineno=4, end_col_offset=5))'
|
||||
)
|
||||
src = ast.Call(
|
||||
func=ast.Name("test", ast.Load()), args=[], keywords=[],
|
||||
lineno=1, end_lineno=None
|
||||
)
|
||||
self.assertEqual(ast.increment_lineno(src).lineno, 2)
|
||||
self.assertIsNone(ast.increment_lineno(src).end_lineno)
|
||||
|
||||
def test_iter_fields(self):
|
||||
node = ast.parse('foo()', mode='eval')
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Handle cases where the ``end_lineno`` is ``None`` on
|
||||
:func:`ast.increment_lineno`.
|
Loading…
Reference in New Issue