Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #18590 - Reverted Python 2.4 workaround for Model pickling

Revert of 08d521e. Refs #10547, #12121.
Thanks Michal Petrucha for the report.
  • Loading branch information...
commit 146aff3bac974e56ec8cb597c2720d1cd4f77b26 1 parent 1aa0d8a
Claude Paroz authored July 07, 2012

Showing 1 changed file with 11 additions and 29 deletions. Show diff stats Hide diff stats

  1. 40  django/db/models/base.py
40  django/db/models/base.py
@@ -16,7 +16,7 @@
16 16
 from django.db import (router, transaction, DatabaseError,
17 17
     DEFAULT_DB_ALIAS)
18 18
 from django.db.models.query import Q
19  
-from django.db.models.query_utils import DeferredAttribute
  19
+from django.db.models.query_utils import DeferredAttribute, deferred_class_factory
20 20
 from django.db.models.deletion import Collector
21 21
 from django.db.models.options import Options
22 22
 from django.db.models import signals
@@ -400,25 +400,16 @@ def __reduce__(self):
400 400
         need to do things manually, as they're dynamically created classes and
401 401
         only module-level classes can be pickled by the default path.
402 402
         """
  403
+        if not self._deferred:
  404
+            return super(Model, self).__reduce__()
403 405
         data = self.__dict__
404  
-        model = self.__class__
405  
-        # The obvious thing to do here is to invoke super().__reduce__()
406  
-        # for the non-deferred case. Don't do that.
407  
-        # On Python 2.4, there is something weird with __reduce__,
408  
-        # and as a result, the super call will cause an infinite recursion.
409  
-        # See #10547 and #12121.
410 406
         defers = []
411  
-        if self._deferred:
412  
-            from django.db.models.query_utils import deferred_class_factory
413  
-            factory = deferred_class_factory
414  
-            for field in self._meta.fields:
415  
-                if isinstance(self.__class__.__dict__.get(field.attname),
416  
-                        DeferredAttribute):
417  
-                    defers.append(field.attname)
418  
-            model = self._meta.proxy_for_model
419  
-        else:
420  
-            factory = simple_class_factory
421  
-        return (model_unpickle, (model, defers, factory), data)
  407
+        for field in self._meta.fields:
  408
+            if isinstance(self.__class__.__dict__.get(field.attname),
  409
+                    DeferredAttribute):
  410
+                defers.append(field.attname)
  411
+        model = self._meta.proxy_for_model
  412
+        return (model_unpickle, (model, defers), data)
422 413
 
423 414
     def _get_pk_val(self, meta=None):
424 415
         if not meta:
@@ -926,20 +917,11 @@ def get_absolute_url(opts, func, self, *args, **kwargs):
926 917
 class Empty(object):
927 918
     pass
928 919
 
929  
-def simple_class_factory(model, attrs):
930  
-    """Used to unpickle Models without deferred fields.
931  
-
932  
-    We need to do this the hard way, rather than just using
933  
-    the default __reduce__ implementation, because of a
934  
-    __deepcopy__ problem in Python 2.4
935  
-    """
936  
-    return model
937  
-
938  
-def model_unpickle(model, attrs, factory):
  920
+def model_unpickle(model, attrs):
939 921
     """
940 922
     Used to unpickle Model subclasses with deferred fields.
941 923
     """
942  
-    cls = factory(model, attrs)
  924
+    cls = deferred_class_factory(model, attrs)
943 925
     return cls.__new__(cls)
944 926
 model_unpickle.__safe_for_unpickle__ = True
945 927
 

0 notes on commit 146aff3

Please sign in to comment.
Something went wrong with that request. Please try again.