Skip to content

Commit e121cb5

Browse files
gh-94869: Fix the location in some expressions for multi-line f-string ast nodes (GH-94895)
(cherry picked from commit 2e9da8e) Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
1 parent 8c08e86 commit e121cb5

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

Lib/test/test_fstring.py

+31-2
Original file line numberDiff line numberDiff line change
@@ -346,10 +346,39 @@ def test_ast_line_numbers_multiline_fstring(self):
346346
self.assertEqual(binop.lineno, 4)
347347
self.assertEqual(binop.left.lineno, 4)
348348
self.assertEqual(binop.right.lineno, 6)
349-
self.assertEqual(binop.col_offset, 4)
350-
self.assertEqual(binop.left.col_offset, 4)
349+
self.assertEqual(binop.col_offset, 3)
350+
self.assertEqual(binop.left.col_offset, 3)
351351
self.assertEqual(binop.right.col_offset, 7)
352352

353+
expr = """
354+
a = f'''
355+
{blech}
356+
'''
357+
"""
358+
t = ast.parse(expr)
359+
self.assertEqual(type(t), ast.Module)
360+
self.assertEqual(len(t.body), 1)
361+
# Check f'...'
362+
self.assertEqual(type(t.body[0]), ast.Assign)
363+
self.assertEqual(type(t.body[0].value), ast.JoinedStr)
364+
self.assertEqual(len(t.body[0].value.values), 3)
365+
self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue)
366+
self.assertEqual(t.body[0].lineno, 2)
367+
self.assertEqual(t.body[0].value.lineno, 2)
368+
self.assertEqual(t.body[0].value.values[0].lineno, 2)
369+
self.assertEqual(t.body[0].value.values[1].lineno, 2)
370+
self.assertEqual(t.body[0].value.values[2].lineno, 2)
371+
self.assertEqual(t.body[0].col_offset, 0)
372+
self.assertEqual(t.body[0].value.col_offset, 4)
373+
self.assertEqual(t.body[0].value.values[0].col_offset, 4)
374+
self.assertEqual(t.body[0].value.values[1].col_offset, 4)
375+
self.assertEqual(t.body[0].value.values[2].col_offset, 4)
376+
# Check {blech}
377+
self.assertEqual(t.body[0].value.values[1].value.lineno, 3)
378+
self.assertEqual(t.body[0].value.values[1].value.end_lineno, 3)
379+
self.assertEqual(t.body[0].value.values[1].value.col_offset, 11)
380+
self.assertEqual(t.body[0].value.values[1].value.end_col_offset, 16)
381+
353382
def test_ast_line_numbers_with_parentheses(self):
354383
expr = """
355384
x = (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix the column offsets for some expressions in multi-line f-strings
2+
:mod:`ast` nodes. Patch by Pablo Galindo.

Parser/string_parser.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ fstring_find_expr_location(Token *parent, const char* expr_start, char *expr_str
326326
start--;
327327
}
328328
*p_cols += (int)(expr_start - start);
329+
if (*start == '\n') {
330+
*p_cols -= 1;
331+
}
329332
}
330333
/* adjust the start based on the number of newlines encountered
331334
before the f-string expression */
@@ -416,7 +419,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end,
416419
NULL, p->arena);
417420

418421
p2->starting_lineno = t->lineno + lines;
419-
p2->starting_col_offset = t->col_offset + cols;
422+
p2->starting_col_offset = lines != 0 ? cols : t->col_offset + cols;
420423

421424
expr = _PyPegen_run_parser(p2);
422425

0 commit comments

Comments
 (0)