Ticket #1671 (closed defect: wontfix)

Opened 9 months ago

Last modified 1 month ago

formencode/turbogears gettext incompatibility

Reported by: fetchinson Assigned to: Chris Arndt
Priority: normal Milestone: 1.0.x bugfix
Component: TurboGears Version: 1.0.3.2
Severity: normal Keywords:
Cc:

Description (Last modified by Chris Arndt)

The second call in the following raises a TypeError: ugettext() got an unexpected keyword argument 'domain' exception in a Python shell:

import turbogears
turbogears.validators.Int().to_python('5')
turbogears.validators.Int().to_python('x')

However only the legitimate Invalid exception is raised if executed from a script.

The following on the other hand works as expected in both a Python shell and from a script:

import formencode
formencode.validators.Int().to_python('5')
formencode.validators.Int().to_python('x')

See the thread http://groups.google.com/group/turbogears/browse_thread/thread/93b7d5f608801652

Change History

01/21/08 08:43:18 changed by Chris Arndt

  • milestone changed from 1.0.4 to 1.0.x bugfix.

04/01/08 09:54:49 changed by Chris Arndt

  • description changed.

04/09/08 00:51:05 changed by amit

We have seen similar problem. We found that this is due to the replacement of __builtins__['_']. The replacement was caused by the xpath module.

# this will replace the __builtins__['_'] with the standard `gettext` function
from xml import xpath

# so reinstall it
from turbogears.i18n import tg_gettext
tg_gettext.install()

Might be the same case with the Python shell.

08/23/08 07:11:47 changed by Chris Arndt

  • owner changed from anonymous to Chris Arndt.
  • status changed from new to assigned.

08/28/08 21:40:19 changed by Chris Arndt

  • status changed from assigned to closed.
  • resolution set to wontfix.

The interactive Python shell sets _ to the result of the last expression entered if it is not None.

So, in the above example we have the following chain of events:

  • _ gets set to 5 after the second line, overwriting the turbgears.i18n.gettext.
  • In the next line, FormEncode throws an Invalid exception and tries to translate the error message,
  • validators.Int.message gets the translation function from __builtins__._
  • it recognizes _ is not a callable
  • and therefor uses its standard translation function formencode.api._stdtrans.
  • turbogears.validators sets formencode.gettextargs to include domain=... but stdtrans does not recognize this keyword arg and we get the TypeError?` exception.

In the second example Validator.gettextargs never gets set, so _stdtrans works, even if _ has been overwritten.

So this really only happens with the interactive shell, because of the name clash around _, this is not an issue when running your TG app. If you really need this to work in the interactive shell, a workaround would be:

>>> import turbogears
>>> state = turbogears.util.Bunch(_=_)
>>> turbogears.validators.Int().to_python('5', state)
>>> turbogears.validators.Int().to_python('x', state)

Or you can just use the IPython shell, which leaves _ alone.