diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2010-03-27 15:54:31 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2010-03-27 15:54:31 +0000 |
| commit | ad5afd6ed220ed50a2b48d7ccf9786ac0e52f807 (patch) | |
| tree | 14caa228c595f66afdaa130c1d2fe2db238ee312 /django/utils | |
| parent | b31b2d4da3772463d007c9d986c4bdd1392b09e7 (diff) | |
Fixed #12769, #12924 -- Corrected the pickling of curried and lazy objects, which was preventing queries with translated or related fields from being pickled. And lo, Alex Gaynor didst slayeth the dragon.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12866 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/utils')
| -rw-r--r-- | django/utils/functional.py | 9 | ||||
| -rw-r--r-- | django/utils/translation/__init__.py | 34 |
2 files changed, 23 insertions, 20 deletions
diff --git a/django/utils/functional.py b/django/utils/functional.py index e52ab76a38..b66fdd3012 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -147,6 +147,12 @@ def lazy(func, *resultclasses): the lazy evaluation code is triggered. Results are not memoized; the function is evaluated on every access. """ + # When lazy() is called by the __reduce_ex__ machinery to reconstitute the + # __proxy__ class it can't call with *args, so the first item will just be + # a tuple. + if len(resultclasses) == 1 and isinstance(resultclasses[0], tuple): + resultclasses = resultclasses[0] + class __proxy__(Promise): """ Encapsulate a function call and act as a proxy for methods that are @@ -162,6 +168,9 @@ def lazy(func, *resultclasses): if self.__dispatch is None: self.__prepare_class__() + def __reduce_ex__(self, protocol): + return (lazy, (self.__func, resultclasses), self.__dict__) + def __prepare_class__(cls): cls.__dispatch = {} for resultclass in resultclasses: diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index c0a0df9532..54fb86d499 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -1,8 +1,11 @@ """ Internationalization support. """ -from django.utils.functional import lazy +from django.conf import settings from django.utils.encoding import force_unicode +from django.utils.functional import lazy, curry +from django.utils.translation import trans_real, trans_null + __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext', 'ngettext_lazy', 'string_concat', 'activate', 'deactivate', @@ -19,32 +22,23 @@ __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext', # replace the functions with their real counterparts (once we do access the # settings). -def delayed_loader(*args, **kwargs): +def delayed_loader(real_name, *args, **kwargs): """ - Replace each real_* function with the corresponding function from either - trans_real or trans_null (e.g. real_gettext is replaced with - trans_real.gettext or trans_null.gettext). This function is run once, the - first time any i18n method is called. It replaces all the i18n methods at - once at that time. + Call the real, underlying function. We have a level of indirection here so + that modules can use the translation bits without actually requiring + Django's settings bits to be configured before import. """ - import traceback - from django.conf import settings if settings.USE_I18N: - import trans_real as trans + trans = trans_real else: - import trans_null as trans - caller = traceback.extract_stack(limit=2)[0][2] - g = globals() - for name in __all__: - if hasattr(trans, name): - g['real_%s' % name] = getattr(trans, name) + trans = trans_null # Make the originally requested function call on the way out the door. - return g['real_%s' % caller](*args, **kwargs) + return getattr(trans, real_name)(*args, **kwargs) g = globals() for name in __all__: - g['real_%s' % name] = delayed_loader + g['real_%s' % name] = curry(delayed_loader, name) del g, delayed_loader def gettext_noop(message): @@ -102,10 +96,10 @@ def templatize(src): def deactivate_all(): return real_deactivate_all() -def string_concat(*strings): +def _string_concat(*strings): """ Lazy variant of string concatenation, needed for translations that are constructed from multiple parts. """ return u''.join([force_unicode(s) for s in strings]) -string_concat = lazy(string_concat, unicode) +string_concat = lazy(_string_concat, unicode) |
