problem mixing gettext and properties

  • Thread starter =?iso-8859-1?B?QW5kcuk=?=
  • Start date
?

=?iso-8859-1?B?QW5kcuk=?=

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.install()

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.Aidez-moi!
AIDE!!!

# No surprise there so far.
'Aidez-moi!'

# all of the above are as expected; now for the first surprise
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
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é
 
M

Matimus

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.install()

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.

'Aidez-moi!'

# all of the above are as expected; now for the first surprise

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

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é

In the interpreter "_" is used to store the return value of the last
statement executed. So when this line is run:

"_" is set to 'Aidez-moi!'.

A possible fix, which I have not tested in your context, would be to
explicitly set _ to _ after your module is loaded.

So, try this:
.... The rest of your code here

I don't know for sure that this will work. From what I have tried
though, assigning to _ seems to disable that feature of the
interpreter.

Matt
 
P

Peter Otten

André said:
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.Aidez-moi!
AIDE!!!

# No surprise there so far.
'Aidez-moi!'

# all of the above are as expected; now for the first surprise
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
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:
.... i
....
0
1
22

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
 
?

=?iso-8859-1?B?QW5kcuk=?=

André said:
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!!!
'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
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.

The _ builtin is set to the result of the last expression evaluated by the
interpreter:

... i
...
0
1
2>>> _
2
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
   ...

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?

Am I missing something?

André
 
P

Peter Otten

André said:
André said:
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.

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
...
[/QUOTE]

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.
[QUOTE]
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?[/QUOTE]

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

Peter
 
?

=?iso-8859-1?B?QW5kcuk=?=

André said:
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:
... i
...
0
1
2>>> _
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.

Thanks, that works ... but,
[snip...]
One more question (back to the original) post.
Why does
i18n_test.help
does the right thing
but
i18n_test.test.help_prop
does not? Both use _() ...

Is it because help = _(...) is defined at the module level but
test.help_prop is defined locally, and that the lookup for _() is done
first locally (finds nothing) and then globally (outside the module
scope) ?

André
 
P

Peter Otten

André said:
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!!!_("HELP!")
# 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.

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__._

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.

Thanks, that works ... but,
[snip...]
One more question (back to the original) post.
Why does
i18n_test.help
does the right thing
but
i18n_test.test.help_prop
does not? Both use _() ...

Is it because help = _(...) is defined at the module level but
test.help_prop is defined locally, and that the lookup for _() is done
first locally (finds nothing) and then globally (outside the module
scope) ?

No, it has nothing to do with the scope. It is just that (assuming a
single-threaded environment)

help = _("Help me!")

is evaluated once immediately after the install() call which sets
__builtin__._ to gettext().

i18n_test.test.help_prop on the other hand invokes __builtin__._() every
time, and because you implicitly set it to a string with

you saw the exception.

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top