Skip to content

Commit

Permalink
py/lexer: Support concatenation of adjacent f-strings.
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
dpgeorge committed Jun 6, 2024
1 parent d7aa2fe commit a066f23
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
8 changes: 6 additions & 2 deletions py/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,12 @@ static void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring)
// assume there's going to be interpolation, so prep the injection data
// fstring_args_idx==0 && len(fstring_args)>0 means we're extracting the args.
// only when fstring_args_idx>0 will we consume the arg data
// note: lex->fstring_args will be empty already (it's reset when finished)
vstr_add_str(&lex->fstring_args, ".format(");
// lex->fstring_args is reset when finished, so at this point there are two cases:
// - lex->fstring_args is empty: start of a new f-string
// - lex->fstring_args is non-empty: concatenation of adjacent f-strings
if (vstr_len(&lex->fstring_args) == 0) {
vstr_add_str(&lex->fstring_args, ".format(");
}
}
#endif

Expand Down
10 changes: 10 additions & 0 deletions tests/basics/string_fstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,13 @@ def foo(a, b):
# Still allow ! in expressions.
print(f"{'1' if a != '456' else '0'!r:8s}")
print(f"{'1' if a != '456' else '0'!s:8s}")

# Concatenation of adjacent f-strings.
print(f"" f"")
print(f"a" f"b")
print(f"{x}" f"{y}")
print(
f"a{x}b---------------------------------"
f"cd---------------------------------"
f"e{y}f---------------------------------"
)
5 changes: 2 additions & 3 deletions tests/cpydiff/core_fstring_concat.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"""
categories: Core
description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces or are f-strings
description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces
cause: MicroPython is optimised for code space.
workaround: Use the + operator between literal strings when either or both are f-strings
workaround: Use the + operator between literal strings when they are not both f-strings
"""

x, y = 1, 2
print("aa" f"{x}") # works
print(f"{x}" "ab") # works
print("a{}a" f"{x}") # fails
print(f"{x}" "a{}b") # fails
print(f"{x}" f"{y}") # fails

0 comments on commit a066f23

Please sign in to comment.