ruff/crates/ruff_python_parser/src/parser
Brent Westbrook 8b9ab48ac6
Fix syntax error false positives for escapes and quotes in f-strings (#20867)
Summary
--

Fixes #20844 by refining the unsupported syntax error check for [PEP
701]
f-strings before Python 3.12 to allow backslash escapes and escaped
outer quotes
in the format spec part of f-strings. These are only disallowed within
the
f-string expression part on earlier versions. Using the examples from
the PR:

```pycon
>>> f"{1:\x64}"
'1'
>>> f"{1:\"d\"}"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Invalid format specifier '"d"' for object of type 'int'
```

Note that the second case is a runtime error, but this is actually
avoidable if
you override `__format__`, so despite being pretty weird, this could
actually be
a valid use case.

```pycon
>>> class C:
...     def __format__(*args, **kwargs): return "<C>"
...
>>> f"{C():\"d\"}"
'<C>'
```

At first I thought narrowing the range we check to exclude the format
spec would
only work for escapes, but it turns out that cases like `f"{1:""}"` are
already
covered by an existing `ParseError`, so we can just narrow the range of
both our
escape and quote checks.

Our comment check also seems to be working correctly because it's based
on the
actual tokens. A case like
[this](https://play.ruff.rs/9f1c2ff2-cd8e-4ad7-9f40-56c0a524209f):

```python
f"""{1:# }"""
```

doesn't include a comment token, instead the `#` is part of an
`InterpolatedStringLiteralElement`.

Test Plan
--

New inline parser tests

[PEP 701]: https://peps.python.org/pep-0701/
2025-10-15 09:23:16 -04:00
..
snapshots Improved error recovery for unclosed strings (including f- and t-strings) (#20848) 2025-10-15 09:50:56 +02:00
expression.rs Fix syntax error false positives for escapes and quotes in f-strings (#20867) 2025-10-15 09:23:16 -04:00
helpers.rs Update Rust toolchain to 1.89 (#19807) 2025-08-07 18:21:50 +02:00
mod.rs [ty] Shrink size of `AstNodeRef` (#20028) 2025-08-22 17:03:22 -04:00
options.rs [syntax-errors] Store to or delete `__debug__` (#16984) 2025-03-29 12:07:20 -04:00
pattern.rs [ty] Shrink size of `AstNodeRef` (#20028) 2025-08-22 17:03:22 -04:00
progress.rs Replace LALRPOP parser with hand-written parser (#10036) 2024-04-18 17:57:39 +05:30
recovery.rs [ty] AST garbage collection (#18482) 2025-06-13 08:40:11 -04:00
statement.rs Fix syntax error false positives on parenthesized context managers (#20846) 2025-10-13 14:13:27 -04:00
tests.rs Fix `unreachable` panic in parser (#19183) 2025-07-20 22:04:14 +00:00