]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39031: Include elif keyword when producing lineno/col-offset info for if_stmt...
authorLysandros Nikolaou <lisandrosnik@gmail.com>
Thu, 12 Dec 2019 21:40:21 +0000 (22:40 +0100)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 12 Dec 2019 21:40:21 +0000 (13:40 -0800)
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
Lib/test/test_ast.py
Misc/NEWS.d/next/Core and Builtins/2019-12-12-21-05-43.bpo-39031.imlCYZ.rst [new file with mode: 0644]
Python/ast.c

index ca75a4ab4570e1673ae9ccdca09cae8a9ee95e76..955bc0d4ea88a039fd8a447919dedf9129006bff 100644 (file)
@@ -68,6 +68,8 @@ exec_tests = [
     "while v:pass",
     # If
     "if v:pass",
+    # If-Elif
+    "if a:\n  pass\nelif b:\n  pass",
     # With
     "with x as y: pass",
     "with x as y, z as q: pass",
@@ -861,6 +863,12 @@ Module(
         self.assertEqual(node.body[2].col_offset, 0)
         self.assertEqual(node.body[2].lineno, 13)
 
+    def test_elif_stmt_start_position(self):
+        node = ast.parse('if a:\n    pass\nelif b:\n    pass\n')
+        elif_stmt = node.body[0].orelse[0]
+        self.assertEqual(elif_stmt.lineno, 3)
+        self.assertEqual(elif_stmt.col_offset, 0)
+
     def test_literal_eval(self):
         self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
         self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
@@ -1843,6 +1851,7 @@ exec_results = [
 ('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []),
 ('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []),
 ('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []),
+('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [])])], []),
 ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []),
 ('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))], None)], []),
 ('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string', None)], []), None)], []),
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-12-12-21-05-43.bpo-39031.imlCYZ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-12-12-21-05-43.bpo-39031.imlCYZ.rst
new file mode 100644 (file)
index 0000000..738902c
--- /dev/null
@@ -0,0 +1,2 @@
+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.\r
+Patch by Lysandros Nikolaou.\r
index 417b347f987417b43ec37f45e73dae6db2a748e2..c450b877f10df561ccd3f283f56feba0f6ba19fe 100644 (file)
@@ -4076,8 +4076,8 @@ ast_for_if_stmt(struct compiling *c, const node *n)
             }
             asdl_seq_SET(newobj, 0,
                          If(expression, suite_seq, orelse,
-                            LINENO(CHILD(n, off)),
-                            CHILD(n, off)->n_col_offset,
+                            LINENO(CHILD(n, off - 1)),
+                            CHILD(n, off - 1)->n_col_offset,
                             end_lineno, end_col_offset, c->c_arena));
             orelse = newobj;
         }