Search code examples
pythongettextf-string

How to use gettext with python >3.6 f-strings


Previously you would use gettext as following:

_('Hey {},').format(username)

but what about new Python's f-string?

f'Hey {username}'

Solution

  • My solution is to make a function f() which performs the f-string interpolation after gettext has been called.

    from copy import copy
    from inspect import currentframe
    
    def f(s: str) -> str:
        frame = currentframe().f_back 
        return eval(f"f'{s}'", copy(frame.f_globals) | frame.f_locals)
    

    Now you just wrap _(...) in f() and don’t preface the string with an f:

    f(_('Hey, {username}'))
    

    Note of caution

    I’m usually against the use of eval as it could make the function potentially unsafe, but I personally think it should be justified here, so long as you’re aware of what’s being formatted. That said use at your own risk.

    Remember

    This isn’t a perfect solution, this is just my solution. As per PEP 498 states each formatting method “have their advantages, but in addition have disadvantages” including this.

    For example if you need to change the expression inside the string then it will no longer match, therefore not be translated unless you also update your .po file as well. Also if you’re not the one translating them and you use an expression that’s hard to decipher what the outcome will be then that can cause miscommunication or other issues in translation.