[Python-checkins] gh-94869: Fix the location in some expressions for multi-line f-string ast nodes (GH-94895)

miss-islington webhook-mailer at python.org
Sat Jul 16 15:17:19 EDT 2022


https://github.com/python/cpython/commit/e121cb5814b4e24cabf44b65a395d69c5acdafd5
commit: e121cb5814b4e24cabf44b65a395d69c5acdafd5
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-07-16T12:16:51-07:00
summary:

gh-94869: Fix the location in some expressions for multi-line f-string ast nodes (GH-94895)

(cherry picked from commit 2e9da8e3522764d09f1d6054a2be567e91a30812)

Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com>

files:
A Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst
M Lib/test/test_fstring.py
M Parser/string_parser.c

diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py
index 93aa229709a0a..453de6212a8da 100644
--- a/Lib/test/test_fstring.py
+++ b/Lib/test/test_fstring.py
@@ -346,10 +346,39 @@ def test_ast_line_numbers_multiline_fstring(self):
         self.assertEqual(binop.lineno, 4)
         self.assertEqual(binop.left.lineno, 4)
         self.assertEqual(binop.right.lineno, 6)
-        self.assertEqual(binop.col_offset, 4)
-        self.assertEqual(binop.left.col_offset, 4)
+        self.assertEqual(binop.col_offset, 3)
+        self.assertEqual(binop.left.col_offset, 3)
         self.assertEqual(binop.right.col_offset, 7)
 
+        expr = """
+a = f'''
+          {blech}
+    '''
+"""
+        t = ast.parse(expr)
+        self.assertEqual(type(t), ast.Module)
+        self.assertEqual(len(t.body), 1)
+        # Check f'...'
+        self.assertEqual(type(t.body[0]), ast.Assign)
+        self.assertEqual(type(t.body[0].value), ast.JoinedStr)
+        self.assertEqual(len(t.body[0].value.values), 3)
+        self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue)
+        self.assertEqual(t.body[0].lineno, 2)
+        self.assertEqual(t.body[0].value.lineno, 2)
+        self.assertEqual(t.body[0].value.values[0].lineno, 2)
+        self.assertEqual(t.body[0].value.values[1].lineno, 2)
+        self.assertEqual(t.body[0].value.values[2].lineno, 2)
+        self.assertEqual(t.body[0].col_offset, 0)
+        self.assertEqual(t.body[0].value.col_offset, 4)
+        self.assertEqual(t.body[0].value.values[0].col_offset, 4)
+        self.assertEqual(t.body[0].value.values[1].col_offset, 4)
+        self.assertEqual(t.body[0].value.values[2].col_offset, 4)
+        # Check {blech}
+        self.assertEqual(t.body[0].value.values[1].value.lineno, 3)
+        self.assertEqual(t.body[0].value.values[1].value.end_lineno, 3)
+        self.assertEqual(t.body[0].value.values[1].value.col_offset, 11)
+        self.assertEqual(t.body[0].value.values[1].value.end_col_offset, 16)
+
     def test_ast_line_numbers_with_parentheses(self):
         expr = """
 x = (
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst
new file mode 100644
index 0000000000000..2ccf91b0cd99a
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst	
@@ -0,0 +1,2 @@
+Fix the column offsets for some expressions in multi-line f-strings
+:mod:`ast` nodes. Patch by Pablo Galindo.
diff --git a/Parser/string_parser.c b/Parser/string_parser.c
index 5e94d477bc04a..4f3f046673cbe 100644
--- a/Parser/string_parser.c
+++ b/Parser/string_parser.c
@@ -326,6 +326,9 @@ fstring_find_expr_location(Token *parent, const char* expr_start, char *expr_str
                 start--;
             }
             *p_cols += (int)(expr_start - start);
+            if (*start == '\n') {
+                *p_cols -= 1;
+            }
         }
         /* adjust the start based on the number of newlines encountered
            before the f-string expression */
@@ -416,7 +419,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end,
                                      NULL, p->arena);
 
     p2->starting_lineno = t->lineno + lines;
-    p2->starting_col_offset = t->col_offset + cols;
+    p2->starting_col_offset = lines != 0 ? cols : t->col_offset + cols;
 
     expr = _PyPegen_run_parser(p2);
 



More information about the Python-checkins mailing list