#25501 closed Bug (fixed)
Filebased cache should use the highest pickling protocol
Reported by: | Bertrand Bordage | Owned by: | Andrew Artajos |
---|---|---|---|
Component: | Core (Cache system) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
I came across this bug when caching psycopg2._range.NumericRange
objects in django-cachalot (in order to add Django 1.8 support to it). My test suite was failing only on Python 2 and with filebased (and of course, Django 1.8, because django.contrib.postgres
didn’t exist before). This error was thrown:
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
This is because, unlike locmem or db, filebased uses the default pickling protocol and not the highest available. Since we are not trying to achieve read compatibility with old Python versions, we can use the highest protocol here as well.
This issue occur on master, Django 1.7.10, 1.8.4, & 1.9 alpha 1.
Change History (10)
comment:1 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 9 years ago
Hi Andrew,
If you need to be able to test it when psycopg2 is not installed, you can also reproduce this bug by creating a class with the same problem:
class UnpickableType(object): __slots__ = ('a',)
If you try to pickle an instance of this class, you’ll get the same error.
comment:9 by , 9 years ago
I've commented on the commit, but I'll do it here as well:
The original intent has always been to use the highest protocol. From help(pickle.dumps):
Specifying a negative protocol version selects the highest protocol version supported.
So this line:
f.write(zlib.compress(pickle.dumps(value), -1))
Was supposed to be:
f.write(zlib.compress(pickle.dumps(value, -1)))
Calling zlib.compress with a compression level of -1 seems to fall back to the default level of 6.
Hi Bertrand,
I am a new to contributing to Django. Do you have any steps on how to reproduce this?
Nevermind, I managed to reproduce it with this: