Fixed #13370 -- Corrected the handling of pickling for lazy() proxy objects. Thanks to Alex Gaynor for the report and patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13000 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-04-19 12:40:46 +00:00
parent 56eb340528
commit ebfe9383bf
2 changed files with 17 additions and 9 deletions

View File

@ -147,11 +147,6 @@ def lazy(func, *resultclasses):
the lazy evaluation code is triggered. Results are not memoized; the the lazy evaluation code is triggered. Results are not memoized; the
function is evaluated on every access. 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): class __proxy__(Promise):
""" """
@ -168,8 +163,11 @@ def lazy(func, *resultclasses):
if self.__dispatch is None: if self.__dispatch is None:
self.__prepare_class__() self.__prepare_class__()
def __reduce_ex__(self, protocol): def __reduce__(self):
return (lazy, (self.__func, resultclasses), self.__dict__) return (
_lazy_proxy_unpickle,
(self.__func, self.__args, self.__kw) + resultclasses
)
def __prepare_class__(cls): def __prepare_class__(cls):
cls.__dispatch = {} cls.__dispatch = {}
@ -249,6 +247,9 @@ def lazy(func, *resultclasses):
return wraps(func)(__wrapper__) return wraps(func)(__wrapper__)
def _lazy_proxy_unpickle(func, args, kwargs, *resultclasses):
return lazy(func, *resultclasses)(*args, **kwargs)
def allow_lazy(func, *resultclasses): def allow_lazy(func, *resultclasses):
""" """
A decorator that allows a function to be called with one or more lazy A decorator that allows a function to be called with one or more lazy

View File

@ -1,8 +1,9 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
import datetime
import decimal
import os import os
import sys import sys
import decimal import pickle
import datetime
from django.template import Template, Context from django.template import Template, Context
from django.conf import settings from django.conf import settings
@ -41,6 +42,12 @@ class TranslationTests(TestCase):
s4 = ugettext_lazy('Some other string') s4 = ugettext_lazy('Some other string')
self.assertEqual(False, s == s4) self.assertEqual(False, s == s4)
def test_lazy_pickle(self):
s1 = ugettext_lazy("test")
self.assertEqual(unicode(s1), "test")
s2 = pickle.loads(pickle.dumps(s1))
self.assertEqual(unicode(s2), "test")
def test_string_concat(self): def test_string_concat(self):
""" """
unicode(string_concat(...)) should not raise a TypeError - #4796 unicode(string_concat(...)) should not raise a TypeError - #4796