[1.11.x] Fixed #28389 -- Fixed pickling of LazyObject on Python 2 when wrapped object doesn't have __reduce__().
Partial revert of 35355a4ffe
.
This commit is contained in:
parent
fe7b456825
commit
30f334cc58
|
@ -300,13 +300,14 @@ class LazyObject(object):
|
||||||
self._setup()
|
self._setup()
|
||||||
return (unpickle_lazyobject, (self._wrapped,))
|
return (unpickle_lazyobject, (self._wrapped,))
|
||||||
|
|
||||||
|
# Overriding __class__ stops __reduce__ from being called on Python 2.
|
||||||
|
# So, 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's better than nothing.
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
"""
|
if self._wrapped is empty:
|
||||||
Prevent older versions of pickle from trying to pickle the __dict__
|
self._setup()
|
||||||
(which in the case of a SimpleLazyObject may contain a lambda). The
|
return self._wrapped.__dict__
|
||||||
value will be ignored by __reduce__() and the custom unpickler.
|
|
||||||
"""
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
if self._wrapped is empty:
|
if self._wrapped is empty:
|
||||||
|
|
|
@ -15,3 +15,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed ``QuerySet.union()`` and ``difference()`` when combining with
|
* Fixed ``QuerySet.union()`` and ``difference()`` when combining with
|
||||||
a queryset raising ``EmptyResultSet`` (:ticket:`28378`).
|
a queryset raising ``EmptyResultSet`` (:ticket:`28378`).
|
||||||
|
|
||||||
|
* Fixed a regression in pickling of ``LazyObject`` on Python 2 when the wrapped
|
||||||
|
object doesn't have ``__reduce__()`` (:ticket:`28389`).
|
||||||
|
|
|
@ -187,11 +187,13 @@ class LazyObjectTestCase(TestCase):
|
||||||
def test_pickle(self):
|
def test_pickle(self):
|
||||||
# See ticket #16563
|
# See ticket #16563
|
||||||
obj = self.lazy_wrap(Foo())
|
obj = self.lazy_wrap(Foo())
|
||||||
|
obj.bar = 'baz'
|
||||||
pickled = pickle.dumps(obj)
|
pickled = pickle.dumps(obj)
|
||||||
unpickled = pickle.loads(pickled)
|
unpickled = pickle.loads(pickled)
|
||||||
self.assertIsInstance(unpickled, Foo)
|
self.assertIsInstance(unpickled, Foo)
|
||||||
self.assertEqual(unpickled, obj)
|
self.assertEqual(unpickled, obj)
|
||||||
self.assertEqual(unpickled.foo, obj.foo)
|
self.assertEqual(unpickled.foo, obj.foo)
|
||||||
|
self.assertEqual(unpickled.bar, obj.bar)
|
||||||
|
|
||||||
# Test copying lazy objects wrapping both builtin types and user-defined
|
# Test copying lazy objects wrapping both builtin types and user-defined
|
||||||
# classes since a lot of the relevant code does __dict__ manipulation and
|
# classes since a lot of the relevant code does __dict__ manipulation and
|
||||||
|
|
Loading…
Reference in New Issue