python-babel / babel

The official repository for Babel, the Python Internationalization Library
http://babel.pocoo.org/
BSD 3-Clause "New" or "Revised" License
1.29k stars 433 forks source link

Extract messages from f-strings #1001

Open tomasr8 opened 1 year ago

tomasr8 commented 1 year ago

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

olejorgenb commented 10 months ago

+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)

Ralkion commented 7 months ago

@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.