|
|
Log in / Subscribe / Register

Don't forget the i18n use case

Don't forget the i18n use case

Posted Jan 24, 2025 14:48 UTC (Fri) by mgedmin (guest, #34497)
Parent article: A revamped Python string-formatting proposal

Personally, I'm waiting for template strings because you cannot use f-strings with gettext.

from gettext import gettext as _
name = 'world'
print(_(f"Hello, {name.capitalize()}!")) # WRONG: interpolates first, calls gettext on the result

from gettext import gettext as _
name = 'world'
print(_("Hello, {name}").format(name=name.capitalize())) # what you have to use today

from sometranslationhelper import _ # I'll probably have to write it
name = 'world'
print(_(t"Hello, {name.capitalize()}") # now it's possible to glue back the original template string and pass it to gettext, then interpolate afterwards


to post comments

Don't forget the i18n use case

Posted Feb 3, 2025 0:29 UTC (Mon) by zahlman (guest, #175387) [Link]

Neat idea. I guess the implementation for your helper is something like:
from itertools import count
from gettext import gettext

def escape_braces(s: str):
    return s.replace('{', '{{').replace('}', '}}')

def _lookup_pieces(t: Template):
    placeholders = (f'{i}' for i in count())
    for item in t:
        if isinstance(t, Interpolation): yield next(placeholders)
        else: yield escape_braces(t)

def _(t: Template):
    lookup = ''.join(_lookup_pieces(t))
    interpolations = (i.value for i in t if isinstance(i, Interpolation))
    return gettext(lookup).format(*interpolations)

That is: we need to normalize the Template into a canonical string that can be looked up in the usual way - and if we follow appropriate conventions (using only numeric placeholders, and following standard brace-escaping convention) in the localized strings, the result will be suitable for use with str.format. We want to look up a string that depends only on the literal parts of the t-string - not on either the values that will be interpolated nor the expressions used to compute them. So e.g. t"Hello, {firstname} {lastname}!" and t"Hello, {firstname} {lastname.capitalize()}!" should both map to a lookup string "Hello, {0} {1}!", which can then retrieve a localized string like "{1} {0}ーさん、今日は!".

But it should be noted that none of this helps if the interpolated values need to be localized as well...


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds