#20212 closed Bug (fixed)
Error pickling SimpleLazyObject
Reported by: | Owned by: | daniellindsley | |
---|---|---|---|
Component: | Core (Serialization) | Version: | 1.5 |
Severity: | Release blocker | Keywords: | |
Cc: | iru@…, bmispelon@…, daniellindsley | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
Pickling SimpleLazyObject doesn't seem to work.
I've noticed that new classmethod "newobj" is added in 1.5 but seems it prevents the object from pickling.
This affects some cases when request.user needs to be pickled.
>>> from django.utils.functional import SimpleLazyObject >>> from django.contrib.auth.models import User >>> u = User.objects.all()[0] >>> s = SimpleLazyObject(lambda: u) >>> import pickle >>> pickle.dumps(s) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/pickle.py", line 1374, in dumps Pickler(file, protocol).dump(obj) File "/usr/lib/python2.7/pickle.py", line 224, in dump self.save(obj) File "/usr/lib/python2.7/pickle.py", line 331, in save self.save_reduce(obj=obj, *rv) File "/usr/lib/python2.7/pickle.py", line 400, in save_reduce save(func) File "/usr/lib/python2.7/pickle.py", line 306, in save rv = reduce(self.proto) File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex raise TypeError, "can't pickle %s objects" % base.__name__ TypeError: can't pickle instancemethod objects >>>
Attachments (1)
Change History (10)
by , 12 years ago
Attachment: | simple_lazy_object.patch added |
---|
comment:1 by , 12 years ago
Cc: | added |
---|---|
Has patch: | set |
comment:2 by , 12 years ago
Cc: | added |
---|---|
Needs tests: | set |
Patch needs improvement: | set |
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 12 years ago
also checked the object is not compatible with cPickle.
>>> u = User.objects.all()[0] >>> s = SimpleLazyObject(lambda: u) >>> import cPickle >>> cPickle.dumps(s) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: expected string or Unicode object, NoneType found
comment:4 by , 12 years ago
Severity: | Normal → Release blocker |
---|
Marking as Release blocker since this has been identifier as a regression from 1.4 to 1.5.
comment:5 by , 12 years ago
in python 2.x, pickle uses protocol 0 if it is not specified. (in 3.3 it uses 3 as default which is defined as pickle.DEFAULT_PROTOCOL)
http://docs.python.org/2/library/pickle.html#data-stream-format
pickle.dumps({'method':method, 'arg':arg}, -1) or pickle.dumps({'method':method, 'arg':arg}, pickle.HIGHEST_PROTOCOL)
This solves the problem so I don't think this is a blocker issue.
comment:6 by , 12 years ago
sorry for make you guys confused ;) can we close this? or is django code still need to be checked?
comment:7 by , 12 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:8 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I can reproduce the reported issue. And it is indeed a regression (the code in the report works in 1.4).
I traced the error to the following commit: b430e1db5f26d1de3a5cd0d6eae18603070fdab4
The attached patch is not valid however because it does not work with python3.
Some regression tests will also need to be included.