babel icon indicating copy to clipboard operation
babel copied to clipboard

Extract messages from f-strings

Open tomasr8 opened this issue 2 years ago • 2 comments

Overview Description

babel should be able to extract translatable strings when the {n,p}gettext call is inside an f-string. For example:

f'<label>{gettext("Title")}:</label>'

The nested gettext("Title") should be extracted.

Same issue from GNU xgettext: https://savannah.gnu.org/bugs/?61596

Steps to Reproduce

  1. File test.py with f'<label>{gettext("Title")}:</label>'
  2. run pybabel extract test.py

Actual Results

Title is not extracted

Expected Results

Title should be extracted

Additional Information

babel version 2.12.1

tomasr8 avatar May 01 '23 15:05 tomasr8

+1 Although it's a bit of an eyesore with the nested quotes I think this might be a better alternative to using string concatenation or embedding placeholders into the string it self.

Unless having the placeholders is somehow important for translating the text, having them in the key does not seem like good practice to me (admittingly I'm new in the translation game and is open for arguments)

_("Name: %(name)s", name=some_object.name)
# ... somewhere else another programmer might use a different placeholder key
_("Name: %(firstname)s", firstname=name)
# ... or maybe later on, we want to use other place-holder keys. Then all the translations keys become broken.
# ... or maybe essentially the same string is used elsewhere without the placeholder, forcing us to translate the string twice.
label=_("Name")

# Using
f'{_("Name")}: {some_object.name}'
# or
_("Name") +": " + some_object.name
# Avoid the above

In this constructed example (which is not that great - I know) the string concatenation is probably the best option, but hopefully it illustrates my point.


Ref: #594 (For discoverability - the issue is about something else, but was the issue which came up in my searches)

olejorgenb avatar Aug 30 '23 17:08 olejorgenb

@olejorgenb The problem with your proposal is handling languages that don't place the placeholder in the same location. For example, a language might put the name first, and then the translation for 'Name:'. Having the placeholder as part of the string is important.

You're right though, a developer may use a different variable name. Resolving that simply comes down to ensuring good practices & reviewing what other strings may already exist as far as I know.

I'm also new to the translation game, and simply came here for the f-string question (wasn't sure if babel supported it), but thought it would be useful to answer your question here.

Ralkion avatar Nov 20 '23 14:11 Ralkion

Closing since this now works as expected.

tomasr8 avatar Oct 27 '24 19:10 tomasr8

Babel-2.16.0 is not good, Which version works as expected?

luojiaaoo avatar Oct 29 '24 14:10 luojiaaoo

For me, babel 2.16 correctly extracts the original example.

tomasr8 avatar Oct 29 '24 14:10 tomasr8

Python 3.9.20 can not work to your original example (f'')

luojiaaoo avatar Oct 29 '24 15:10 luojiaaoo

Ah that might be related to how f-strings changed with pep701 so this will most likely work only on python 3.12+

tomasr8 avatar Oct 29 '24 16:10 tomasr8