Skip to content

Commit 1c396f6

Browse files
Python: Fix f-string parsing for debug = with format spec (#6731)
When an f-string uses the debug specifier `=` combined with a format spec but no conversion (e.g. `{last_error=:#x}`), the `:` token was not advanced past before parsing the format spec. This caused the format spec parser to consume `:` instead of the actual format text, leaving the FSTRING_MIDDLE token unconsumed and the parser stuck.
1 parent ad53660 commit 1c396f6

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

rewrite-python/rewrite/src/rewrite/python/_parser_visitor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3488,10 +3488,10 @@ def __map_fstring(self, node, prefix: Space, tok: TokenInfo, value_idx: int = 0,
34883488

34893489
# format specifier
34903490
if tok.type == token.OP and tok.string == ':':
3491-
# After conversion handling: _token_idx points to ':' (need to advance)
3491+
# After conversion or debug handling: _token_idx points to ':' (need to advance)
34923492
# After scanning loop only: _token_idx already points past ':' (don't advance)
3493-
if conv is not None:
3494-
self._token_idx += 1 # advance past ':' (only needed after conversion)
3493+
if conv is not None or debug is not None:
3494+
self._token_idx += 1 # advance past ':' (needed after conversion or debug specifier)
34953495
format_spec, tok, _ = self.__map_fstring(
34963496
cast(ast.JoinedStr, value.format_spec), Space.EMPTY, self._tokens[self._token_idx],
34973497
_start=_start, _middle=_middle, _end=_end)

rewrite-python/rewrite/tests/python/all/tree/fstring_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ def test_debug_with_trailing_whitespace():
159159
RecipeSpec().rewrite_run(python("a = f'{1= !a}'"))
160160

161161

162+
def test_debug_with_format_spec():
163+
# language=python
164+
RecipeSpec().rewrite_run(python("a = f'{last_error=:#x}'"))
165+
# debug `=` with format spec after other expressions
166+
# language=python
167+
RecipeSpec().rewrite_run(python("""a = f"kernel32.{name} ({last_error=:#x})" """))
168+
169+
162170
def test_all_specifiers():
163171
# language=python
164172
RecipeSpec().rewrite_run(python("a = f'{1=!a:0>6}'"))

0 commit comments

Comments
 (0)