]> granicus.if.org Git - python/commitdiff
bpo-18374: fix wrong col_offset of some ast.BinOp instances (GH-14607)
authorCarl Friedrich Bolz-Tereick <cfbolz@gmx.de>
Mon, 8 Jul 2019 21:17:56 +0000 (23:17 +0200)
committerIvan Levkivskyi <levkivskyi@gmail.com>
Mon, 8 Jul 2019 21:17:56 +0000 (22:17 +0100)
Nested BinOp instances (e.g. a+b+c) had a wrong col_offset for the
second BinOp (e.g. 2 instead of 0 in the example). Fix it by using the
correct st node to copy the line and col_offset from in ast.c.

Lib/test/test_ast.py
Misc/ACKS
Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst [new file with mode: 0644]
Python/ast.c

index e251e254afddaa2bfe1c202c76a3bd38959c4230..1e07c573c8463234d63d17a57ed70d168b3154c4 100644 (file)
@@ -576,6 +576,36 @@ class AST_Tests(unittest.TestCase):
         with support.swap_attr(unicodedata, 'normalize', bad_normalize):
             self.assertRaises(TypeError, ast.parse, '\u03D5')
 
+    def test_issue18374_binop_col_offset(self):
+        tree = ast.parse('4+5+6+7')
+        parent_binop = tree.body[0].value
+        child_binop = parent_binop.left
+        grandchild_binop = child_binop.left
+        self.assertEqual(parent_binop.col_offset, 0)
+        self.assertEqual(parent_binop.end_col_offset, 7)
+        self.assertEqual(child_binop.col_offset, 0)
+        self.assertEqual(child_binop.end_col_offset, 5)
+        self.assertEqual(grandchild_binop.col_offset, 0)
+        self.assertEqual(grandchild_binop.end_col_offset, 3)
+
+        tree = ast.parse('4+5-\\\n 6-7')
+        parent_binop = tree.body[0].value
+        child_binop = parent_binop.left
+        grandchild_binop = child_binop.left
+        self.assertEqual(parent_binop.col_offset, 0)
+        self.assertEqual(parent_binop.lineno, 1)
+        self.assertEqual(parent_binop.end_col_offset, 4)
+        self.assertEqual(parent_binop.end_lineno, 2)
+
+        self.assertEqual(child_binop.col_offset, 0)
+        self.assertEqual(parent_binop.lineno, 1)
+        self.assertEqual(child_binop.end_col_offset, 2)
+        self.assertEqual(parent_binop.end_lineno, 2)
+
+        self.assertEqual(grandchild_binop.col_offset, 0)
+        self.assertEqual(parent_binop.lineno, 1)
+        self.assertEqual(grandchild_binop.end_col_offset, 3)
+        self.assertEqual(parent_binop.end_lineno, 2)
 
 class ASTHelpers_Test(unittest.TestCase):
     maxDiff = None
index 36fe727c8421c06842b5e987ce95dfaa46699842..d916c45a8e441b46ced3acd188eac7df95b32c2a 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -178,6 +178,7 @@ Nikolay Bogoychev
 David Bolen
 Wouter Bolsterlee
 Gawain Bolton
+Carl Friedrich Bolz-Tereick
 Forest Bond
 Gregory Bond
 Médéric Boquien
diff --git a/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst b/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst
new file mode 100644 (file)
index 0000000..f9e99e0
--- /dev/null
@@ -0,0 +1,2 @@
+Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` instances
+which had a too large value in some situations.
index 16895ce62ec01b17d9ee24f9aed50180c45213b5..8dc86c23d62deaef6d984d1395c85868b959629e 100644 (file)
@@ -2645,7 +2645,7 @@ ast_for_binop(struct compiling *c, const node *n)
             return NULL;
 
         tmp_result = BinOp(result, newoperator, tmp,
-                           LINENO(next_oper), next_oper->n_col_offset,
+                           LINENO(n), n->n_col_offset,
                            CHILD(n, i * 2 + 2)->n_end_lineno,
                            CHILD(n, i * 2 + 2)->n_end_col_offset,
                            c->c_arena);