Fixed #12121 -- Modified __reduce__ on a model to avoid an infinite recursion problem that occurs on Python 2.4. Thanks to emulbreh for the report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@11691 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2009-11-01 03:04:20 +00:00
parent 8dd4a28721
commit 08d521efa0
1 changed files with 17 additions and 12 deletions

View File

@ -352,20 +352,25 @@ class Model(object):
only module-level classes can be pickled by the default path. only module-level classes can be pickled by the default path.
""" """
data = self.__dict__ data = self.__dict__
if not self._deferred: model = self.__class__
return super(Model, self).__reduce__() # The obvious thing to do here is to invoke super().__reduce__()
# for the non-deferred case. Don't do that.
# On Python 2.4, there is something wierd with __reduce__,
# and as a result, the super call will cause an infinite recursion.
# See #10547 and #12121.
defers = [] defers = []
pk_val = None pk_val = None
for field in self._meta.fields: if self._deferred:
if isinstance(self.__class__.__dict__.get(field.attname), for field in self._meta.fields:
DeferredAttribute): if isinstance(self.__class__.__dict__.get(field.attname),
defers.append(field.attname) DeferredAttribute):
if pk_val is None: defers.append(field.attname)
# The pk_val and model values are the same for all if pk_val is None:
# DeferredAttribute classes, so we only need to do this # The pk_val and model values are the same for all
# once. # DeferredAttribute classes, so we only need to do this
obj = self.__class__.__dict__[field.attname] # once.
model = obj.model_ref() obj = self.__class__.__dict__[field.attname]
model = obj.model_ref()
return (model_unpickle, (model, defers), data) return (model_unpickle, (model, defers), data)