diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index ba223ae124a8fb..cb14bba2602def 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -496,6 +496,24 @@ def test_ast_line_numbers_with_parentheses(self): self.assertEqual(wat2.end_col_offset, 17) self.assertEqual(fstring.end_col_offset, 18) + def test_ast_fstring_empty_format_spec(self): + expr = "f'{expr:}'" + + mod = ast.parse(expr) + self.assertEqual(type(mod), ast.Module) + self.assertEqual(len(mod.body), 1) + + fstring = mod.body[0].value + self.assertEqual(type(fstring), ast.JoinedStr) + self.assertEqual(len(fstring.values), 1) + + fv = fstring.values[0] + self.assertEqual(type(fv), ast.FormattedValue) + + format_spec = fv.format_spec + self.assertEqual(type(format_spec), ast.JoinedStr) + self.assertEqual(len(format_spec.values), 0) + def test_docstring(self): def f(): f'''Not a docstring''' diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-09-51-45.gh-issue-106396.DmYp7x.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-04-09-51-45.gh-issue-106396.DmYp7x.rst new file mode 100644 index 00000000000000..c5767e97271d9d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-07-04-09-51-45.gh-issue-106396.DmYp7x.rst @@ -0,0 +1,3 @@ +When the format specification of an f-string expression is empty, the parser now +generates an empty :class:`ast.JoinedStr` node for it instead of an one-element +:class:`ast.JoinedStr` with an empty string :class:`ast.Constant`. diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index 70c267bb212fcb..36e0750220a30d 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -997,6 +997,18 @@ _PyPegen_setup_full_format_spec(Parser *p, Token *colon, asdl_expr_seq *spec, in if (!spec) { return NULL; } + + // This is needed to keep compatibility with 3.11, where an empty format spec is parsed + // as an *empty* JoinedStr node, instead of having an empty constant in it. + if (asdl_seq_LEN(spec) == 1) { + expr_ty e = asdl_seq_GET(spec, 0); + if (e->kind == Constant_kind + && PyUnicode_Check(e->v.Constant.value) + && PyUnicode_GetLength(e->v.Constant.value) == 0) { + spec = _Py_asdl_expr_seq_new(0, arena); + } + } + expr_ty res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno, end_col_offset, p->arena); if (!res) { return NULL; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy