problem mixing gettext and properties

Peter Otten __peter__ at web.de
Tue Jun 26 22:01:43 CEST 2007


André wrote:

> On Jun 26, 3:56 pm, Peter Otten <__pete... at web.de> wrote:
>> André wrote:
>> > I've encountered a problem using gettext with properties while using a
>> > Python interpreter.
>>
>> > Here's a simple program that illustrate the problem.
>> > ==============
>> > # i18n_test.py: test of gettext & properties
>>
>> > import gettext
>>
>> > fr = gettext.translation('i18n_test', './translations',
>> > languages=['fr'])
>>
>> _ = fr.gettext # untested
>>
>>
>>
>> > help = _("Help me!")
>>
>> > class Test_i18n(object):
>> >     def get(self):
>> >         __help = _("HELP!")
>> >         return __help
>> >     help_prop = property(get, None, None, 'help')
>>
>> > test = Test_i18n()
>>
>> > print help
>> > print test.help_prop
>> > #### end of file
>>
>> > To run the above program, you need to have the strings translated and
>> > the proper ".po" and ".mo" files created.  (for those interested, I
>> > can send the whole lot in a zip file)
>>
>> > If I run the program as is, the output is:
>> > Aidez-moi!
>> > AIDE!!!
>>
>> > Ok, let's try with the Python interpreter:
>>
>> > ActivePython 2.4.2 Build 248 (ActiveState Corp.) based on
>> > Python 2.4.2 (#67, Oct 30 2005, 16:11:18) [MSC v.1310 32 bit (Intel)]
>> > on win32
>> > Type "help", "copyright", "credits" or "license" for more information.
>> >>>> import i18n_test
>> > Aidez-moi!
>> > AIDE!!!
>>
>> > #  No surprise there so far.
>>
>> >>>> print i18n_test.help
>> > Aidez-moi!
>> >>>> print i18n_test.test.help_prop
>> > AIDE!!!
>> >>>> i18n_test.help
>> > 'Aidez-moi!'
>>
>> > # all of the above are as expected; now for the first surprise
>>
>> >>>> i18n_test.test.help_prop
>> > Traceback (most recent call last):
>> >   File "<stdin>", line 1, in ?
>> >   File "i18n_test.py", line 12, in get
>> >     __help = _("HELP!")
>> > TypeError: 'str' object is not callable
>>
>> > # and a second surprise where we try to repeat something that used to
>> > work
>>
>> >>>> print i18n_test.test.help_prop
>> > Traceback (most recent call last):
>> >   File "<stdin>", line 1, in ?
>> >   File "i18n_test.py", line 12, in get
>> >     __help = _("HELP!")
>> > TypeError: 'str' object is not callable
>>
>> > #=============
>>
>> > Dare I say: "Help!"   I really need to use the above at the
>> > interpreter prompt.
>>
>> > André
>>
>> The _ builtin is set to the result of the last expression evaluated by
>> the interpreter:
>>
>> >>> for i in range(3):
>>
>> ...     i
>> ...
>> 0
>> 1
>> 2>>> _
>> 2
>> >>> import __builtin__
>> >>> __builtin__._
>>
>> 2
>>
>> Therefore you get a name clash with _() as an alias for gettext(). Use
>> module-global aliases instead, e. g.
>>
>> _ = fr.gettext
>>
>> in the above code.
>>
>> Peter
> 
> Thanks, that works ... but, it brings many other "complications".   I
> have multiple modules, and I want to be able to switch languages
> easily.   Unless I am mistaken, if I do it with module-global aliases
> instead, I will need to have something like
> 
> lang = {}
> for code in ['en', 'fr', ...]:
>    lang[code] = gettext.translation('i18n_test', './translations',
> languages=[code])
> 
> def switch_language(code):
>    ...
>    import module1
>    import module2
>    ...
>    module1._ = lang[code].gettext
>    module2._ = lang[code].gettext
>    ...
> 

If you need to change the language while the program is running you can put

def _(s):
   return gettext(s)

into one "master" module and have the other modules import that:

from master import _

This comes at the cost of one extra indirection.

> And I will need to make sure to keep track of all the modules that
> require translation...  Is there an easier, less tedious way to do
> this?

If your users don't rely on _ in the interpreter, you can write a custom
sys.displayhook that doesn't set __builtin__._

Peter



More information about the Python-list mailing list