Commit e1f0001f by Tom Christie

Fix and test for #645

Yuck, pickle is weird.  Closes #645.
parent d62e4a7a
...@@ -28,20 +28,23 @@ class DictWithMetadata(dict): ...@@ -28,20 +28,23 @@ class DictWithMetadata(dict):
def __getstate__(self): def __getstate__(self):
""" """
Used by pickle (e.g., caching). Used by pickle (e.g., caching).
Overriden to remove metadata from the dict, since it shouldn't be pickled Overriden to remove the metadata from the dict, since it shouldn't be
and may in some instances be unpickleable. pickled and may in some instances be unpickleable.
""" """
# return an instance of the first dict in MRO that isn't a DictWithMetadata return dict(self)
for base in self.__class__.__mro__:
if not issubclass(base, DictWithMetadata) and issubclass(base, dict):
return base(self)
class SortedDictWithMetadata(SortedDict, DictWithMetadata): class SortedDictWithMetadata(SortedDict):
""" """
A sorted dict-like object, that can have additional properties attached. A sorted dict-like object, that can have additional properties attached.
""" """
pass def __getstate__(self):
"""
Used by pickle (e.g., caching).
Overriden to remove the metadata from the dict, since it shouldn't be
pickle and may in some instances be unpickleable.
"""
return SortedDict(self).__dict__
def _is_protected_type(obj): def _is_protected_type(obj):
......
...@@ -951,15 +951,21 @@ class SerializerPickleTests(TestCase): ...@@ -951,15 +951,21 @@ class SerializerPickleTests(TestCase):
class Meta: class Meta:
model = Person model = Person
fields = ('name', 'age') fields = ('name', 'age')
pickle.dumps(InnerPersonSerializer(Person(name="Noah", age=950)).data) pickle.dumps(InnerPersonSerializer(Person(name="Noah", age=950)).data, 0)
def test_getstate_method_should_not_return_none(self): def test_getstate_method_should_not_return_none(self):
""" """
Regression test for Regression test for #645.
https://github.com/tomchristie/django-rest-framework/issues/645
""" """
d = serializers.DictWithMetadata({1: 1}) data = serializers.DictWithMetadata({1: 1})
self.assertEqual(d.__getstate__(), serializers.SortedDict({1: 1})) self.assertEqual(data.__getstate__(), serializers.SortedDict({1: 1}))
def test_serializer_data_is_pickleable(self):
"""
Another regression test for #645.
"""
data = serializers.SortedDictWithMetadata({1: 1})
repr(pickle.loads(pickle.dumps(data, 0)))
class DepthTest(TestCase): class DepthTest(TestCase):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment