diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index f8dcf983af..c942acd52f 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -1,6 +1,7 @@ "Memcached cache backend" import time +import pickle from threading import local from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError @@ -146,6 +147,12 @@ class MemcachedCache(BaseMemcachedCache): library=memcache, value_not_found_exception=ValueError) + @property + def _cache(self): + if getattr(self, '_client', None) is None: + self._client = self._lib.Client(self._servers, pickleProtocol=pickle.HIGHEST_PROTOCOL) + return self._client + class PyLibMCCache(BaseMemcachedCache): "An implementation of a cache binding using pylibmc" def __init__(self, server, params): diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index ce1e643946..c2a3d56c53 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -89,6 +89,9 @@ Minor features :class:`~django.http.HttpResponsePermanentRedirect` now provide an ``url`` attribute (equivalent to the URL the response will redirect to). +* The ``MemcachedCache`` cache backend now uses the latest :mod:`pickle` + protocol available. + * Added the :attr:`django.db.models.ForeignKey.db_constraint` option. diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py index b446465d32..17d17f7fdd 100644 --- a/tests/regressiontests/cache/tests.py +++ b/tests/regressiontests/cache/tests.py @@ -12,6 +12,7 @@ import string import tempfile import time import warnings +import pickle from django.conf import settings from django.core import management @@ -984,6 +985,18 @@ class MemcachedCacheTests(unittest.TestCase, BaseCacheTests): # memcached limits key length to 250 self.assertRaises(Exception, self.cache.set, 'a' * 251, 'value') + # Explicitly display a skipped test if no configured cache uses MemcachedCache + @unittest.skipUnless( + any(cache['BACKEND'] == 'django.core.cache.backends.memcached.MemcachedCache' + for cache in settings.CACHES.values()), + "cache with python-memcached library not available") + def test_memcached_uses_highest_pickle_version(self): + # Regression test for #19810 + for cache_key, cache in settings.CACHES.items(): + if cache['BACKEND'] == 'django.core.cache.backends.memcached.MemcachedCache': + self.assertEqual(get_cache(cache_key)._cache.pickleProtocol, + pickle.HIGHEST_PROTOCOL) + class FileBasedCacheTests(unittest.TestCase, BaseCacheTests): """