Skip to content

extract: Warn when skipping an f-string with substitutions - #1343

Closed
ColinHouse wants to merge 1 commit into
python-babel:masterfrom
ColinHouse:warn-skipped-fstring
Closed

ColinHouse wants to merge 1 commit into
python-babel:masterfrom
ColinHouse:warn-skipped-fstring

Conversation

@ColinHouse

Copy link
Copy Markdown

_(f"Hello {name}") cannot be translated, so extraction skips it. Since #915
replaced eval with ast, it is skipped silently: pybabel extract exits 0,
writes no message, and prints nothing. The string never reaches translators and
ships untranslated, with no signal to the author.

This warns instead, in the same format as the existing "Empty msgid" warning:

app.py:2: warning: Skipping f-string with substitutions: it cannot be
translated as written.  Extract a format string instead,
e.g. _("Hello {name}").format(name=name).

There are two code paths, because f-string tokenisation changed in 3.12:

  • before 3.12 the whole f-string is one STRING token and _parse_python_string
    returns None;
  • from 3.12 (PEP 701) a substitution arrives as a non-FSTRING_* token and the
    f-string is dropped where current_fstring_start is reset.

Both are covered, and the suite was run on 3.11 and 3.12.

It warns rather than raising, as the issue body asks ("warn the user about the
incorrect usage instead of simply crashing"). Raising would break builds that
extract successfully today. Happy to make it an error if you prefer.

A constant f-string such as _(f"spam" f"eggs") is still extracted and does not
warn; an f-string outside a translation call is untouched.

The stale # TODO: we could raise an error or warning when not all nodes are constants is replaced, since this implements it.

fixes #715

An f-string that interpolates values cannot be translated, so extraction
skips it. Since #915 replaced eval with ast it is skipped silently: the
message never reaches translators, and nothing tells the author.

Warn instead, in the same format as the existing "Empty msgid" warning.
Both tokenisation paths are covered: before Python 3.12 the whole f-string
is a single STRING token, and from 3.12 (PEP 701) a substitution arrives
as a non-FSTRING_* token and the f-string is dropped where
current_fstring_start is reset.

Fixes #715

@akx akx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@codspeed

codspeed Bot commented Sep 18, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 88 untouched benchmarks


Comparing ColinHouse:warn-skipped-fstring (6f30522) with master (6ba6701)

Open in CodSpeed

@codecov

codecov Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.38%. Comparing base (6ba6701) to head (6f30522).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1343      +/-   ##
==========================================
+ Coverage   93.37%   93.38%   +0.01%     
==========================================
  Files          27       27              
  Lines        4919     4927       +8     
==========================================
+ Hits         4593     4601       +8     
  Misses        326      326              
Flag Coverage Δ
macos-14-3.10 92.40% <62.50%> (-0.05%) ⬇️
macos-14-3.11 92.34% <62.50%> (-0.05%) ⬇️
macos-14-3.12 92.59% <87.50%> (-0.01%) ⬇️
macos-14-3.13 92.59% <87.50%> (-0.01%) ⬇️
macos-14-3.14 92.57% <87.50%> (-0.01%) ⬇️
macos-14-3.15 92.57% <87.50%> (-0.01%) ⬇️
macos-14-3.8 92.28% <62.50%> (-0.05%) ⬇️
macos-14-3.9 92.34% <62.50%> (-0.05%) ⬇️
macos-14-pypy3.10 92.40% <62.50%> (-0.05%) ⬇️
ubuntu-24.04-3.10 92.42% <62.50%> (-0.05%) ⬇️
ubuntu-24.04-3.11 92.36% <62.50%> (-0.05%) ⬇️
ubuntu-24.04-3.12 92.61% <87.50%> (-0.01%) ⬇️
ubuntu-24.04-3.13 92.61% <87.50%> (-0.01%) ⬇️
ubuntu-24.04-3.14 92.59% <87.50%> (-0.01%) ⬇️
ubuntu-24.04-3.15 92.59% <87.50%> (-0.01%) ⬇️
ubuntu-24.04-3.8 92.30% <62.50%> (-0.05%) ⬇️
ubuntu-24.04-3.9 92.36% <62.50%> (-0.05%) ⬇️
ubuntu-24.04-pypy3.10 92.42% <62.50%> (-0.05%) ⬇️
windows-2022-3.10 92.42% <62.50%> (-0.05%) ⬇️
windows-2022-3.11 92.36% <62.50%> (-0.05%) ⬇️
windows-2022-3.12 92.60% <87.50%> (-0.01%) ⬇️
windows-2022-3.13 92.60% <87.50%> (-0.01%) ⬇️
windows-2022-3.14 92.58% <87.50%> (-0.01%) ⬇️
windows-2022-3.15 92.58% <87.50%> (-0.01%) ⬇️
windows-2022-3.8 92.39% <62.50%> (-0.05%) ⬇️
windows-2022-3.9 92.35% <62.50%> (-0.05%) ⬇️
windows-2022-pypy3.10 92.42% <62.50%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ColinHouse ColinHouse closed this by deleting the head repository Sep 18, 2026
@ColinHouse

Copy link
Copy Markdown
Author

Sorry — this closed itself because I deleted my fork by accident, minutes after your review. Nothing to do with the review.

Reopened as #1350 with the same commit (6f30522) and a byte-identical diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pybabel should raise an error when it encounters f-strings

2 participants