summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorEd Morley <emorley@mozilla.com>2016-08-31 13:12:40 +0100
committerTim Graham <timograham@gmail.com>2016-08-31 12:50:14 -0400
commit65ec8fa8ca56a5378345375e1079025c96d0b833 (patch)
treed803828eb0106f89ee909dfe7c0b69f953b280e6 /django
parent1d54fb4483f034d2dced86f1b012671c8ee6ef5d (diff)
Fixed #20892 -- Allowed configuring memcached client using OPTIONS.
Previously, the MemcachedCache backend ignored `OPTIONS` and PyLibMCCache used them to set pylibmc behaviors. Both backends now pass `OPTIONS` as keyword arguments to the client constructors.
Diffstat (limited to 'django')
-rw-r--r--django/core/cache/backends/memcached.py35
1 files changed, 27 insertions, 8 deletions
diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py
index ee6b3b7712..2ca9f663d7 100644
--- a/django/core/cache/backends/memcached.py
+++ b/django/core/cache/backends/memcached.py
@@ -2,9 +2,11 @@
import pickle
import time
+import warnings
from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
from django.utils import six
+from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_str
from django.utils.functional import cached_property
@@ -24,7 +26,7 @@ class BaseMemcachedCache(BaseCache):
self.LibraryValueNotFoundException = value_not_found_exception
self._lib = library
- self._options = params.get('OPTIONS')
+ self._options = params.get('OPTIONS') or {}
@property
def _cache(self):
@@ -32,7 +34,7 @@ class BaseMemcachedCache(BaseCache):
Implements transparent thread-safe access to a memcached client.
"""
if getattr(self, '_client', None) is None:
- self._client = self._lib.Client(self._servers)
+ self._client = self._lib.Client(self._servers, **self._options)
return self._client
@@ -163,7 +165,9 @@ class MemcachedCache(BaseMemcachedCache):
@property
def _cache(self):
if getattr(self, '_client', None) is None:
- self._client = self._lib.Client(self._servers, pickleProtocol=pickle.HIGHEST_PROTOCOL)
+ client_kwargs = dict(pickleProtocol=pickle.HIGHEST_PROTOCOL)
+ client_kwargs.update(self._options)
+ self._client = self._lib.Client(self._servers, **client_kwargs)
return self._client
@@ -175,10 +179,25 @@ class PyLibMCCache(BaseMemcachedCache):
library=pylibmc,
value_not_found_exception=pylibmc.NotFound)
+ # The contents of `OPTIONS` was formerly only used to set the behaviors
+ # attribute, but is now passed directly to the Client constructor. As such,
+ # any options that don't match a valid keyword argument are removed and set
+ # under the `behaviors` key instead, to maintain backwards compatibility.
+ legacy_behaviors = {}
+ for option in list(self._options):
+ if option not in ('behaviors', 'binary', 'username', 'password'):
+ warnings.warn(
+ "Specifying pylibmc cache behaviors as a top-level property "
+ "within `OPTIONS` is deprecated. Move `%s` into a dict named "
+ "`behaviors` inside `OPTIONS` instead." % option,
+ RemovedInDjango21Warning,
+ stacklevel=2,
+ )
+ legacy_behaviors[option] = self._options.pop(option)
+
+ if legacy_behaviors:
+ self._options.setdefault('behaviors', {}).update(legacy_behaviors)
+
@cached_property
def _cache(self):
- client = self._lib.Client(self._servers)
- if self._options:
- client.behaviors = self._options
-
- return client
+ return self._lib.Client(self._servers, **self._options)