diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2021-01-03 01:11:41 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-03 01:11:41 (GMT) |
commit | bd2728b1e8a99ba8f8c2d481f88aeb99b8b8360f (patch) | |
tree | 45e3fc389d9dee5e63556b49995961ee7e22b48b | |
parent | 2ea320dddd553298038bb7d6789e50e199332f66 (diff) | |
download | cpython-bd2728b1e8a99ba8f8c2d481f88aeb99b8b8360f.zip cpython-bd2728b1e8a99ba8f8c2d481f88aeb99b8b8360f.tar.gz cpython-bd2728b1e8a99ba8f8c2d481f88aeb99b8b8360f.tar.bz2 |
bpo-42806: Fix ast locations of f-strings inside parentheses (GH-24067)
-rw-r--r-- | Lib/test/test_fstring.py | 53 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2021-01-03-00-20-38.bpo-42806.mLAobJ.rst | 2 | ||||
-rw-r--r-- | Parser/string_parser.c | 2 |
3 files changed, 56 insertions, 1 deletions
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index b53661a..2345832 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -332,6 +332,59 @@ non-important content self.assertEqual(binop.left.col_offset, 4) self.assertEqual(binop.right.col_offset, 7) + def test_ast_line_numbers_with_parentheses(self): + expr = """ +x = ( + f" {test(t)}" +)""" + t = ast.parse(expr) + self.assertEqual(type(t), ast.Module) + self.assertEqual(len(t.body), 1) + # check the test(t) location + call = t.body[0].value.values[1].value + self.assertEqual(type(call), ast.Call) + self.assertEqual(call.lineno, 3) + self.assertEqual(call.end_lineno, 3) + self.assertEqual(call.col_offset, 8) + self.assertEqual(call.end_col_offset, 15) + + expr = """ +x = ( + 'PERL_MM_OPT', ( + f'wat' + f'some_string={f(x)} ' + f'wat' + ), +) +""" + t = ast.parse(expr) + self.assertEqual(type(t), ast.Module) + self.assertEqual(len(t.body), 1) + # check the fstring + fstring = t.body[0].value.elts[1] + self.assertEqual(type(fstring), ast.JoinedStr) + self.assertEqual(len(fstring.values), 3) + wat1, middle, wat2 = fstring.values + # check the first wat + self.assertEqual(type(wat1), ast.Constant) + self.assertEqual(wat1.lineno, 4) + self.assertEqual(wat1.end_lineno, 6) + self.assertEqual(wat1.col_offset, 12) + self.assertEqual(wat1.end_col_offset, 18) + # check the call + call = middle.value + self.assertEqual(type(call), ast.Call) + self.assertEqual(call.lineno, 5) + self.assertEqual(call.end_lineno, 5) + self.assertEqual(call.col_offset, 27) + self.assertEqual(call.end_col_offset, 31) + # check the second wat + self.assertEqual(type(wat2), ast.Constant) + self.assertEqual(wat2.lineno, 4) + self.assertEqual(wat2.end_lineno, 6) + self.assertEqual(wat2.col_offset, 12) + self.assertEqual(wat2.end_col_offset, 18) + def test_docstring(self): def f(): f'''Not a docstring''' diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-01-03-00-20-38.bpo-42806.mLAobJ.rst b/Misc/NEWS.d/next/Core and Builtins/2021-01-03-00-20-38.bpo-42806.mLAobJ.rst new file mode 100644 index 0000000..10314fd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-01-03-00-20-38.bpo-42806.mLAobJ.rst @@ -0,0 +1,2 @@ +Fix the column offsets for f-strings :mod:`ast` nodes surrounded by +parentheses and for nodes that spawn multiple lines. Patch by Pablo Galindo. diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 09b8c35..a41f41c 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -405,7 +405,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version, NULL, p->arena); p2->starting_lineno = t->lineno + lines - 1; - p2->starting_col_offset = p->tok->first_lineno == p->tok->lineno ? t->col_offset + cols : cols; + p2->starting_col_offset = t->col_offset + cols; expr = _PyPegen_run_parser(p2); |