Loading django/utils/functional.py +10 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,16 @@ class SimpleLazyObject(LazyObject): else: return copy.deepcopy(self._wrapped, memo) # Because we have messed with __class__ below, we confuse pickle as to what # class we are pickling. It also appears to stop __reduce__ from being # called. So, we define __getstate__ in a way that cooperates with the way # that pickle interprets this class. This fails when the wrapped class is a # builtin, but it is better than nothing. def __getstate__(self): if self._wrapped is empty: self._setup() return self._wrapped.__dict__ # Need to pretend to be the wrapped class, for the sake of objects that care # about this (especially in equality tests) __class__ = property(new_method_proxy(operator.attrgetter("__class__"))) Loading tests/regressiontests/utils/simplelazyobject.py +10 −0 Original line number Diff line number Diff line import copy import pickle from django.utils.unittest import TestCase from django.utils.functional import SimpleLazyObject, empty Loading Loading @@ -96,3 +97,12 @@ class TestUtilsSimpleLazyObject(TestCase): self.assertTrue(x) x = SimpleLazyObject(lambda: 0) self.assertFalse(x) def test_pickle_complex(self): # See ticket #16563 x = SimpleLazyObject(complex_object) pickled = pickle.dumps(x) unpickled = pickle.loads(pickled) self.assertEqual(unpickled, x) self.assertEqual(unicode(unpickled), unicode(x)) self.assertEqual(unpickled.name, x.name) Loading
django/utils/functional.py +10 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,16 @@ class SimpleLazyObject(LazyObject): else: return copy.deepcopy(self._wrapped, memo) # Because we have messed with __class__ below, we confuse pickle as to what # class we are pickling. It also appears to stop __reduce__ from being # called. So, we define __getstate__ in a way that cooperates with the way # that pickle interprets this class. This fails when the wrapped class is a # builtin, but it is better than nothing. def __getstate__(self): if self._wrapped is empty: self._setup() return self._wrapped.__dict__ # Need to pretend to be the wrapped class, for the sake of objects that care # about this (especially in equality tests) __class__ = property(new_method_proxy(operator.attrgetter("__class__"))) Loading
tests/regressiontests/utils/simplelazyobject.py +10 −0 Original line number Diff line number Diff line import copy import pickle from django.utils.unittest import TestCase from django.utils.functional import SimpleLazyObject, empty Loading Loading @@ -96,3 +97,12 @@ class TestUtilsSimpleLazyObject(TestCase): self.assertTrue(x) x = SimpleLazyObject(lambda: 0) self.assertFalse(x) def test_pickle_complex(self): # See ticket #16563 x = SimpleLazyObject(complex_object) pickled = pickle.dumps(x) unpickled = pickle.loads(pickled) self.assertEqual(unpickled, x) self.assertEqual(unicode(unpickled), unicode(x)) self.assertEqual(unpickled.name, x.name)