Opened 12 years ago
Closed 11 years ago
#22565 closed Bug (fixed)
pgettext_lazy returns "unexpected type"
| Reported by: | ygbo | Owned by: | Claude Paroz |
|---|---|---|---|
| Component: | Internationalization | Version: | 1.5 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The issue is similar to https://code.djangoproject.com/ticket/19272 but with pgettext_lazy:
In [1]: from django.utils.translation import pgettext_lazy
In [2]: s = pgettext_lazy("a context", "foo bar") # using bytestring
In [3]: s.upper()
/usr/lib/python2.7/dist-packages/django/db/backends/sqlite3/base.py:53: RuntimeWarning: SQLite received a naive datetime (2014-04-29 12:18:28.940685) while time zone support is active.
RuntimeWarning)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/usr/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 s.upper()
/usr/lib/python2.7/dist-packages/django/utils/functional.pyc in __wrapper__(self, *args, **kw)
121 if t in self.__dispatch:
122 return self.__dispatch[t][funcname](res, *args, **kw)
--> 123 raise TypeError("Lazy object returned unexpected type.")
124
125 if klass not in cls.__dispatch:
TypeError: Lazy object returned unexpected type.
In [4]: s = pgettext_lazy("a context", u"foo bar") # using unicode string
In [5]: s.upper()
Out[5]: u'FOO BAR'
Change History (7)
comment:1 by , 12 years ago
| Component: | Uncategorized → Internationalization |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
| Triage Stage: | Unreviewed → Accepted |
| Type: | Uncategorized → Bug |
comment:2 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
comment:5 by , 11 years ago
For those affected on 1.4:
--- django/utils/translation/trans_real.py.orig 2014-05-15 11:16:54.384046616 +0200
+++ django/utils/translation/trans_real.py 2014-05-15 11:17:03.491749365 +0200
@@ -282,7 +282,7 @@ def pgettext(context, message):
u"%s%s%s" % (context, CONTEXT_SEPARATOR, message), 'ugettext')
if CONTEXT_SEPARATOR in result:
# Translation not found
- result = message
+ result = unicode(message)
return result
def gettext_noop(message):
And a slightly longer explanation:
- You're use
pgettext_lazy('context', 'bytestring')instead ofpgettext_lazy('context', u'unicodestring'). - The translation is NOT found. Generally happens for English, since that's your base language: no need for po/mo files for that.
resultholdscontext\x04bytestring(which means it wasn't translated), so it is overwritten by the original which was a bytestring.- When the lazy object is converted to non-lazy it trips on the wrong data type, since it expected unicode --
pgettext_lazy = lazy(pgettext, unicode)-- and gets a bytestring, hence theTypeError: Lazy object returned unexpected type.
After patching you can safely forget the u again which you weren't used to using for ugettext_lazy either.
Cheers,
Walter Doekes
OSSO B.V.
comment:6 by , 11 years ago
| Resolution: | fixed |
|---|---|
| Status: | closed → new |
| Version: | 1.6 → 1.5 |
Django 1.5 also has this bug. Can this be backported?
comment:7 by , 11 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Sorry, but probably not. 1.5 is in security-fix mode, and you can easily workaround this issue by passing unicode strings to pgettext_lazy.
The situation is a bit different, as
pgettext_lazyis unicode-based (it calls ugettext internally). But I think this can still be fixed.