/public/tools/

python f-string compatibility checker

Paste Python code containing f-strings. See which Python versions accept it, and which rule each f-string trips on PEP 701.

presets

analyzing…

Per-version verdict

PythonVerdictReason

Findings

What PEP 701 changed

Before Python 3.12 the f-string grammar was a hand-rolled parser separate from the rest of the language. It treated the expression inside {…} as a substring, and several characters that work everywhere else in Python were rejected only there.

PEP 701 reimplemented f-strings inside the PEG parser, which lifted those restrictions in one stroke. The four most common gotchas:

rulebefore 3.123.12 and later
backslash in expressionrejectedaccepted
same-quote nestingrejectedaccepted
multiline expressionrejectedaccepted
comment in expressionrejectedaccepted

Workarounds for older Python

If a check fails on 3.11 and you need to support it, the canonical move is to bind the offending sub-expression to a local before the f-string:

stripped = data.strip("\n")
log.write(f"value is {stripped}")

That also tends to read cleaner than the original. For nested-quote, swap the inner quote to the opposite kind: f"name is {d['name']}" works on every f-string Python.

What this tool does not check

It scans for f-string literals (prefix f, F, or combined with r/b) and runs PEP 701 rule checks on each expression part. It does not validate Python syntax outside f-strings, doesn't catch every edge case of the lexer (e.g. nested f-strings inside f-strings work in 3.12+ and are flagged here as same-quote-nesting if applicable), and treats triple-quoted f-strings as multiline-allowed pre-3.12 only for newlines outside {…}. Newlines inside the expression are still rejected pre-3.12.

This is a single static HTML file with no network calls. Source: github.com/truffle-dev/tool-python-fstring-check. MIT.