From e1f0001f92b812c7406b009edff786dfbccc32cb Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 22 Feb 2013 22:59:55 +0000 Subject: Fix and test for #645 Yuck, pickle is weird. Closes #645. --- rest_framework/serializers.py | 19 +++++++++++-------- rest_framework/tests/serializer.py | 16 +++++++++++----- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 764313f7..266a2402 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -28,20 +28,23 @@ class DictWithMetadata(dict): def __getstate__(self): """ Used by pickle (e.g., caching). - Overriden to remove metadata from the dict, since it shouldn't be pickled - and may in some instances be unpickleable. + Overriden to remove the metadata from the dict, since it shouldn't be + pickled and may in some instances be unpickleable. """ - # return an instance of the first dict in MRO that isn't a DictWithMetadata - for base in self.__class__.__mro__: - if not issubclass(base, DictWithMetadata) and issubclass(base, dict): - return base(self) + return dict(self) -class SortedDictWithMetadata(SortedDict, DictWithMetadata): +class SortedDictWithMetadata(SortedDict): """ 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): diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index ee415eea..671494b5 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -951,15 +951,21 @@ class SerializerPickleTests(TestCase): class Meta: model = Person 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): """ - Regression test for - https://github.com/tomchristie/django-rest-framework/issues/645 + Regression test for #645. """ - d = serializers.DictWithMetadata({1: 1}) - self.assertEqual(d.__getstate__(), serializers.SortedDict({1: 1})) + data = serializers.DictWithMetadata({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): -- cgit v1.2.3