8000 [3.7] bpo-39031: Include elif keyword when producing lineno/col-offse… · python/cpython@0ed45d0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0ed45d0

Browse files
[3.7] bpo-39031: Include elif keyword when producing lineno/col-offset info for if_stmt (GH-17582) (#17584)
When parsing an "elif" node, lineno and col_offset of the node now point to the "elif" keyword and not to its condition, making it consistent with the "if" node. https://bugs.python.org/issue39031 Automerge-Triggered-By: @pablogsal. (cherry picked from commit 025a602) Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
1 parent 85924a4 commit 0ed45d0

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

Lib/test/test_ast.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ def to_tuple(t):
6464
"while v:pass",
6565
# If
6666
"if v:pass",
67+
# If-Elif
68+
"if a:\n pass\nelif b:\n pass",
6769
# With
6870
"with x as y: pass",
6971
"with x as y, z as q: pass",
@@ -598,6 +600,12 @@ def test_get_docstring_none(self):
598600
node = ast.parse('async def foo():\n x = "not docstring"')
599601
self.assertIsNone(ast.get_docstring(node.body[0]))
600602

603+
def test_elif_stmt_start_position(self):
604+
node = ast.parse('if a:\n pass\nelif b:\n pass\n')
605+
elif_stmt = node.body[0].orelse[0]
606+
self.assertEqual(elif_stmt.lineno, 3)
607+
self.assertEqual(elif_stmt.col_offset, 0)
608+
601609
def test_literal_eval(self):
602610
self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
603611
self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
@@ -1235,6 +1243,7 @@ def main():
12351243
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]),
12361244
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
12371245
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
1246+
('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [])])]),
12381247
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]),
12391248
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]),
12401249
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], []), None)]),
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
When parsing an "elif" node, lineno and col_offset of the node now point to the "elif" keyword and not to its condition, making it consistent with the "if" node.
2+
Patch by Lysandros Nikolaou.

Python/ast.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,8 +3622,8 @@ ast_for_if_stmt(struct compiling *c, const node *n)
36223622

36233623
asdl_seq_SET(newobj, 0,
36243624
If(expression, suite_seq, orelse,
3625-
LINENO(CHILD(n, off)),
3626-
CHILD(n, off)->n_col_offset, c->c_arena));
3625+
LINENO(CHILD(n, off - 1)),
3626+
CHILD(n, off - 1)->n_col_offset, c->c_arena));
36273627
orelse = newobj;
36283628
}
36293629
expression = ast_for_expr(c, CHILD(n, 1));

0 commit comments

Comments
 (0)
0