Skip to content

Commit 930df7b

Browse files
[3.12] gh-106396: Special-case empty format spec to gen empty JoinedStr node (GH-106401) (#106416)
(cherry picked from commit dfe4de2) Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
1 parent fda2970 commit 930df7b

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

Lib/test/test_fstring.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,24 @@ def test_ast_line_numbers_with_parentheses(self):
496496
self.assertEqual(wat2.end_col_offset, 17)
497497
self.assertEqual(fstring.end_col_offset, 18)
498498

499+
def test_ast_fstring_empty_format_spec(self):
500+
expr = "f'{expr:}'"
501+
502+
mod = ast.parse(expr)
503+
self.assertEqual(type(mod), ast.Module)
504+
self.assertEqual(len(mod.body), 1)
505+
506+
fstring = mod.body[0].value
507+
self.assertEqual(type(fstring), ast.JoinedStr)
508+
self.assertEqual(len(fstring.values), 1)
509+
510+
fv = fstring.values[0]
511+
self.assertEqual(type(fv), ast.FormattedValue)
512+
513+
format_spec = fv.format_spec
514+
self.assertEqual(type(format_spec), ast.JoinedStr)
515+
self.assertEqual(len(format_spec.values), 0)
516+
499517
def test_docstring(self):
500518
def f():
501519
f'''Not a docstring'''
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
When the format specification of an f-string expression is empty, the parser now
2+
generates an empty :class:`ast.JoinedStr` node for it instead of an one-element
3+
:class:`ast.JoinedStr` with an empty string :class:`ast.Constant`.

Parser/action_helpers.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,18 @@ _PyPegen_setup_full_format_spec(Parser *p, Token *colon, asdl_expr_seq *spec, in
10031003
if (!spec) {
10041004
return NULL;
10051005
}
1006+
1007+
// This is needed to keep compatibility with 3.11, where an empty format spec is parsed
1008+
// as an *empty* JoinedStr node, instead of having an empty constant in it.
1009+
if (asdl_seq_LEN(spec) == 1) {
1010+
expr_ty e = asdl_seq_GET(spec, 0);
1011+
if (e->kind == Constant_kind
1012+
&& PyUnicode_Check(e->v.Constant.value)
1013+
&& PyUnicode_GetLength(e->v.Constant.value) == 0) {
1014+
spec = _Py_asdl_expr_seq_new(0, arena);
1015+
}
1016+
}
1017+
10061018
expr_ty res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno, end_col_offset, p->arena);
10071019
if (!res) {
10081020
return NULL;

0 commit comments

Comments
 (0)
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