Opened 10 years ago

Closed 10 years ago

#22566 closed Uncategorized (wontfix)

ngettext_lazy returns "unexpected type" when one of the strings is also a lazy reference.

Reported by: ygbo Owned by: nobody
Component: Uncategorized Version: 1.6
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

We have objects or dictionaries which store gettext_lazy strings,
If they are passed to ngettext_lazy we have a behaviour similar to https://code.djangoproject.com/ticket/19272 :

In [1]: from django.utils.translation import ngettext_lazy, gettext_lazy

In [2]: messages = {"singular": gettext_lazy("I'm alone"), "plural": gettext_lazy("We are plenty")}

In [3]: count = 1

In [4]: message = ngettext_lazy(messages['singular'], messages['plural'], count)

In [5]: 'alone' in message
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-a57c63f0b996> in <module>()
----> 1 'alone' in message

/home/yves/openstack/horizon/.venv/local/lib/python2.7/site-packages/django/utils/functional.pyc in __wrapper__(self, *args, **kw)
    127                     if t in self.__dispatch:
    128                         return self.__dispatch[t][funcname](res, *args, **kw)
--> 129                 raise TypeError("Lazy object returned unexpected type.")
    130 
    131             if klass not in cls.__dispatch:

TypeError: Lazy object returned unexpected type.

I know we could use gettext_noop in this case, but we also use pgettext_lazy since there is no pgettext_noop and we really need a context in many cases. So this is why we use a lazy reference since the strings are stored on an object and some strings require a context.
whether we use gettext_lazy or pgettext_lazy, the error is the same after they go thru ngettext_lazy:

In [1]: from django.utils.translation import ngettext_lazy, pgettext_lazy

In [2]: messages = {"singular": pgettext_lazy('context', "I'm alone"), "plural": pgettext_lazy('context', "We are plenty")}

In [3]: count = 1

In [4]: message = ngettext_lazy(messages['singular'], messages['plural'], count)

In [5]: 'alone' in message
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-a57c63f0b996> in <module>()
----> 1 'alone' in message

/home/yves/openstack/horizon/.venv/local/lib/python2.7/site-packages/django/utils/functional.pyc in __wrapper__(self, *args, **kw)
    127                     if t in self.__dispatch:
    128                         return self.__dispatch[t][funcname](res, *args, **kw)
--> 129                 raise TypeError("Lazy object returned unexpected type.")
    130 
    131             if klass not in cls.__dispatch:

TypeError: Lazy object returned unexpected type.

Change History (1)

comment:1 by Claude Paroz, 10 years ago

Resolution: wontfix
Status: newclosed

Please, avoid using the bytestring versions of gettext calls (gettext_lazy/ngettext_lazy), if possible. Use ugettext_lazy/ungettext_lazy instead. There is no bytestring version of pgettext_lazy, hence the problems you encountered when mixing it with ngettext_lazy. Always using the modern unicode versions is preferred (and prepares the way for Python 3).

Note: See TracTickets for help on using tickets.
Back to Top