diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index d331642f09..ed3f2af492 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -23,17 +23,15 @@ class BaseMemcachedCache(BaseCache): self.LibraryValueNotFoundException = value_not_found_exception self._lib = library + self._class = library.Client self._options = params.get('OPTIONS') or {} - @property + @cached_property def _cache(self): """ Implement transparent thread-safe access to a memcached client. """ - if getattr(self, '_client', None) is None: - self._client = self._lib.Client(self._servers, **self._options) - - return self._client + return self._class(self._servers, **self._options) def get_backend_timeout(self, timeout=DEFAULT_TIMEOUT): """ @@ -166,14 +164,7 @@ class MemcachedCache(BaseMemcachedCache): # incr/decr(), python-memcached < 1.45 raises ValueError. import memcache super().__init__(server, params, library=memcache, value_not_found_exception=ValueError) - - @property - def _cache(self): - if getattr(self, '_client', None) is None: - client_kwargs = {'pickleProtocol': pickle.HIGHEST_PROTOCOL} - client_kwargs.update(self._options) - self._client = self._lib.Client(self._servers, **client_kwargs) - return self._client + self._options = {'pickleProtocol': pickle.HIGHEST_PROTOCOL, **self._options} def get(self, key, default=None, version=None): key = self.make_key(key, version=version) @@ -201,10 +192,6 @@ class PyLibMCCache(BaseMemcachedCache): import pylibmc super().__init__(server, params, library=pylibmc, value_not_found_exception=pylibmc.NotFound) - @cached_property - def _cache(self): - return self._lib.Client(self._servers, **self._options) - def touch(self, key, timeout=DEFAULT_TIMEOUT, version=None): key = self.make_key(key, version=version) self.validate_key(key) diff --git a/tests/cache/tests.py b/tests/cache/tests.py index d5532fa1e6..3aa01ccced 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -1374,7 +1374,7 @@ class BaseMemcachedTests(BaseCacheTests): # connection is closed when the request is complete. signals.request_finished.disconnect(close_old_connections) try: - with mock.patch.object(cache._lib.Client, 'disconnect_all', autospec=True) as mock_disconnect: + with mock.patch.object(cache._class, 'disconnect_all', autospec=True) as mock_disconnect: signals.request_finished.send(self.__class__) self.assertIs(mock_disconnect.called, self.should_disconnect_on_close) finally: @@ -1383,7 +1383,7 @@ class BaseMemcachedTests(BaseCacheTests): def test_set_many_returns_failing_keys(self): def fail_set_multi(mapping, *args, **kwargs): return mapping.keys() - with mock.patch('%s.Client.set_multi' % self.client_library_name, side_effect=fail_set_multi): + with mock.patch.object(cache._class, 'set_multi', side_effect=fail_set_multi): failing_keys = cache.set_many({'key': 'value'}) self.assertEqual(failing_keys, ['key']) @@ -1395,7 +1395,6 @@ class BaseMemcachedTests(BaseCacheTests): )) class MemcachedCacheTests(BaseMemcachedTests, TestCase): base_params = MemcachedCache_params - client_library_name = 'memcache' def test_memcached_uses_highest_pickle_version(self): # Regression test for #19810 @@ -1427,7 +1426,6 @@ class MemcachedCacheTests(BaseMemcachedTests, TestCase): )) class PyLibMCCacheTests(BaseMemcachedTests, TestCase): base_params = PyLibMCCache_params - client_library_name = 'pylibmc' # libmemcached manages its own connections. should_disconnect_on_close = False