diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index c35efce92cb..88a8b528b5b 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -54,8 +54,8 @@ class FileBasedCache(BaseCache): try: with io.open(fd, 'wb') as f: expiry = self.get_backend_timeout(timeout) - f.write(pickle.dumps(expiry, -1)) - f.write(zlib.compress(pickle.dumps(value), -1)) + f.write(pickle.dumps(expiry, pickle.HIGHEST_PROTOCOL)) + f.write(zlib.compress(pickle.dumps(value, pickle.HIGHEST_PROTOCOL), -1)) file_move_safe(tmp_path, fname, allow_overwrite=True) renamed = True finally: diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt index 1087c0bb55e..46cc18f467f 100644 --- a/docs/releases/1.10.txt +++ b/docs/releases/1.10.txt @@ -106,7 +106,7 @@ Minor features Cache ^^^^^ -* ... +* The file-based cache backend now uses the highest pickling protocol. CSRF ^^^^ diff --git a/tests/cache/tests.py b/tests/cache/tests.py index dca08ee081f..e77cec91514 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -65,6 +65,11 @@ class Unpickable(object): raise pickle.PickleError() +class UnpicklableType(object): + # Unpicklable using the default pickling protocol on Python 2. + __slots__ = 'a', + + @override_settings(CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', @@ -1221,6 +1226,10 @@ class FileBasedCacheTests(BaseCacheTests, TestCase): cache.set('foo', 'bar') os.path.exists(self.dirname) + def test_cache_write_unpickable_type(self): + # This fails if not using the highest pickling protocol on Python 2. + cache.set('unpickable', UnpicklableType()) + @override_settings(CACHES={ 'default': {