Skip to content

Commit a066f23

Browse files
committed
py/lexer: Support concatenation of adjacent f-strings.
This is quite a simple and small change to support concatenation of adjacent f-strings, and improve compatibility with CPython. Signed-off-by: Damien George <[email protected]>
1 parent d7aa2fe commit a066f23

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

py/lexer.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,12 @@ static void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring)
336336
// assume there's going to be interpolation, so prep the injection data
337337
// fstring_args_idx==0 && len(fstring_args)>0 means we're extracting the args.
338338
// only when fstring_args_idx>0 will we consume the arg data
339-
// note: lex->fstring_args will be empty already (it's reset when finished)
340-
vstr_add_str(&lex->fstring_args, ".format(");
339+
// lex->fstring_args is reset when finished, so at this point there are two cases:
340+
// - lex->fstring_args is empty: start of a new f-string
341+
// - lex->fstring_args is non-empty: concatenation of adjacent f-strings
342+
if (vstr_len(&lex->fstring_args) == 0) {
343+
vstr_add_str(&lex->fstring_args, ".format(");
344+
}
341345
}
342346
#endif
343347

tests/basics/string_fstring.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,13 @@ def foo(a, b):
6565
# Still allow ! in expressions.
6666
print(f"{'1' if a != '456' else '0'!r:8s}")
6767
print(f"{'1' if a != '456' else '0'!s:8s}")
68+
69+
# Concatenation of adjacent f-strings.
70+
print(f"" f"")
71+
print(f"a" f"b")
72+
print(f"{x}" f"{y}")
73+
print(
74+
f"a{x}b---------------------------------"
75+
f"cd---------------------------------"
76+
f"e{y}f---------------------------------"
77+
)

tests/cpydiff/core_fstring_concat.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
"""
22
categories: Core
3-
description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces or are f-strings
3+
description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces
44
cause: MicroPython is optimised for code space.
5-
workaround: Use the + operator between literal strings when either or both are f-strings
5+
workaround: Use the + operator between literal strings when they are not both f-strings
66
"""
77

88
x, y = 1, 2
99
print("aa" f"{x}") # works
1010
print(f"{x}" "ab") # works
1111
print("a{}a" f"{x}") # fails
1212
print(f"{x}" "a{}b") # fails
13-
print(f"{x}" f"{y}") # fails

0 commit comments

Comments
 (0)