-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: update i18n guidelines for string interpolation in Python #740
docs: update i18n guidelines for string interpolation in Python #740
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not very deep in this translation business, so i can't judge the importance of e.g. lazy strings, but here's my two cents anyway (please correct me if i'm wrong!):
from my understanding, there's usually[1] no real downside of using lazy_gettext()
over gettext()
, and i think it enables postponing the translation until the very last moment, at which some more context (e.g. user preferences for locale) may become available... in the worst case it's effectively the same.
either way, i would suggest keeping the format aligned either way, to reduce mental overhead – also, maybe some changes will make lazy evaluation more relevant for individual messages at a later point than when they were initially added?
as such, i would suggest moving the old-style formatting up to the top as the suggested variant, and making the alternatives less prominent (perhaps even as a folded accordion per default?)
💭 an alternative would of course be to simply submit a PR to flask_babel
that enables new-style formatting in addition to old-style formatting, to allow something like _("hello, {name}", name=name)
😄
that might actually save us quite a bit of effort of updating all the translations all over the place (though the _()
calls will still likely need fixups).
[1] except for when there are...
i remember not being able to use lazy strings in the context of requests & events (i.e. comments) easily because lazy strings don't support being serialized (e.g. into the JSON in the DB) all that well.
back then, i just went for normal strings via gettext()
instead.
not sure if that's still the case though, maybe somebody put in some more work!
docs/develop/howtos/i18n.md
Outdated
@@ -9,12 +9,35 @@ In order to translate strings, they have to be marked. This ensures that they wi | |||
### Python | |||
|
|||
!!! warning | |||
Do not use `f-strings` for translatable text. Interpolation is not supported for these types of strings (see [Issue](https://github.com/python-babel/babel/issues/594)). | |||
Do not use f‑strings for translatable text. | |||
F‑strings perform interpolation immediately, so the extracted message will contain the interpolated text (e.g. "Hello, max") rather than the intended placeholder (e.g. "Hello, {username}"). This means that your translators will see the wrong string and translations will not work as expected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think that even with f-strings
, the extracted message will still have the shape "Hello, {username}"
because the extraction runs on static code by parsing the syntax tree, and doesn't need to run the code (which would be required to know the content of variables (unless they're hard-coded values)
Similarly, do not pass keyword arguments to `_()` when using new‑style (curly‑brace) placeholders. For example, avoid this pattern: | ||
|
||
```python | ||
# ❌ Incorrect – the placeholder is not interpolated at runtime. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed, the placeholder isn't replaced at runtime – because flask_babel.gettext()
uses s % variables
(old-style formatting), but for new-style formatting we would require s.format(variables)
410910a
to
05a395d
Compare
Thanks for sharing your thoughts @max-moser I agree that For this PR, I mainly kicked things off based on the discussions and your testing shared on Discord. Feel free to update or even close it if you think a different approach makes more sense, I'm keeping it open for further discussion by others as well. |
05a395d
to
f163633
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ Thank you for your contribution!
Description
Read the comment on Discord: https://discord.com/channels/692989811736182844/852219787005919242/1336648054488567868
Checklist
Ticks in all boxes and 🟢 on all GitHub actions status checks are required to merge:
master
branch.production
branch following approval or indicate to a maintainer that it should be backported.Reminder
By using GitHub, you have already agreed to the GitHub’s Terms of Service including that: