From 4e9f800742c3048402acbaea67ec3c6bc3bd0935 Mon Sep 17 00:00:00 2001 From: Curtis Maloney Date: Thu, 19 Sep 2013 18:38:56 +1000 Subject: [PATCH] Fixed #21125 -- Removed support for cache URI syntax --- django/core/cache/__init__.py | 94 ++++++++--------------------------- docs/releases/1.7.txt | 4 ++ tests/cache/tests.py | 18 +------ 3 files changed, 25 insertions(+), 91 deletions(-) diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py index 4cafeccd2a..c242671c6c 100644 --- a/django/core/cache/__init__.py +++ b/django/core/cache/__init__.py @@ -8,9 +8,9 @@ the abstract BaseCache class in django.core.cache.backends.base. Client code should not access a cache backend directly; instead it should either use the "cache" variable made available here, or it should use the -get_cache() function made available here. get_cache() takes a backend URI -(e.g. "memcached://127.0.0.1:11211/") and returns an instance of a backend -cache class. +get_cache() function made available here. get_cache() takes a CACHES alias or a +backend path and config parameters, and returns an instance of a backend cache +class. See docs/topics/cache.txt for information on the public API. """ @@ -29,78 +29,17 @@ __all__ = [ 'get_cache', 'cache', 'DEFAULT_CACHE_ALIAS' ] -# Name for use in settings file --> name of module in "backends" directory. -# Any backend scheme that is not in this dictionary is treated as a Python -# import path to a custom backend. -BACKENDS = { - 'memcached': 'memcached', - 'locmem': 'locmem', - 'file': 'filebased', - 'db': 'db', - 'dummy': 'dummy', -} - DEFAULT_CACHE_ALIAS = 'default' -def parse_backend_uri(backend_uri): - """ - Converts the "backend_uri" into a cache scheme ('db', 'memcached', etc), a - host and any extra params that are required for the backend. Returns a - (scheme, host, params) tuple. - """ - if backend_uri.find(':') == -1: - raise InvalidCacheBackendError("Backend URI must start with scheme://") - scheme, rest = backend_uri.split(':', 1) - if not rest.startswith('//'): - raise InvalidCacheBackendError("Backend URI must start with scheme://") - - host = rest[2:] - qpos = rest.find('?') - if qpos != -1: - params = dict(parse_qsl(rest[qpos+1:])) - host = rest[2:qpos] - else: - params = {} - if host.endswith('/'): - host = host[:-1] - - return scheme, host, params - if DEFAULT_CACHE_ALIAS not in settings.CACHES: raise ImproperlyConfigured("You must define a '%s' cache" % DEFAULT_CACHE_ALIAS) -def parse_backend_conf(backend, **kwargs): - """ - Helper function to parse the backend configuration - that doesn't use the URI notation. - """ - # Try to get the CACHES entry for the given backend name first - conf = settings.CACHES.get(backend, None) - if conf is not None: - args = conf.copy() - args.update(kwargs) - backend = args.pop('BACKEND') - location = args.pop('LOCATION', '') - return backend, location, args - else: - try: - # Trying to import the given backend, in case it's a dotted path - import_by_path(backend) - except ImproperlyConfigured as e: - raise InvalidCacheBackendError("Could not find backend '%s': %s" % ( - backend, e)) - location = kwargs.pop('LOCATION', '') - return backend, location, kwargs def get_cache(backend, **kwargs): """ Function to load a cache backend dynamically. This is flexible by design to allow different use cases: - To load a backend with the old URI-based notation:: - - cache = get_cache('locmem://') - To load a backend that is pre-defined in the settings:: cache = get_cache('default') @@ -114,17 +53,24 @@ def get_cache(backend, **kwargs): """ try: - if '://' in backend: - # for backwards compatibility - backend, location, params = parse_backend_uri(backend) - if backend in BACKENDS: - backend = 'django.core.cache.backends.%s' % BACKENDS[backend] - params.update(kwargs) - mod = importlib.import_module(backend) - backend_cls = mod.CacheClass + # Try to get the CACHES entry for the given backend name first + try: + conf = settings.CACHES[backend] + except KeyError: + try: + # Trying to import the given backend, in case it's a dotted path + import_by_path(backend) + except ImproperlyConfigured as e: + raise InvalidCacheBackendError("Could not find backend '%s': %s" % ( + backend, e)) + location = kwargs.pop('LOCATION', '') + params = kwargs else: - backend, location, params = parse_backend_conf(backend, **kwargs) - backend_cls = import_by_path(backend) + params = conf.copy() + params.update(kwargs) + backend = params.pop('BACKEND') + location = params.pop('LOCATION', '') + backend_cls = import_by_path(backend) except (AttributeError, ImportError, ImproperlyConfigured) as e: raise InvalidCacheBackendError( "Could not find backend '%s': %s" % (backend, e)) diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index d0e4a07374..c34e1f37d6 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -414,6 +414,10 @@ Miscellaneous Rationale behind this is removal of dependency of non-contrib code on contrib applications. +* The old cache URI syntax (e.g. ``"locmem://"``) is no longer supported. It + still worked, even though it was not documented or officially supported. If + you're still using it, please update to the current :setting:`CACHES` syntax. + Features deprecated in 1.7 ========================== diff --git a/tests/cache/tests.py b/tests/cache/tests.py index f3380abd04..462c1b236d 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -857,10 +857,6 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase): self.cache = get_cache(self.backend_name, LOCATION=self._table_name, OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0}) self.perform_cull_test(50, 18) - def test_old_initialization(self): - self.cache = get_cache('db://%s?max_entries=30&cull_frequency=0' % self._table_name) - self.perform_cull_test(50, 18) - def test_second_call_doesnt_crash(self): with six.assertRaisesRegex(self, management.CommandError, "Cache table 'test cache table' could not be created"): @@ -956,10 +952,6 @@ class LocMemCacheTests(unittest.TestCase, BaseCacheTests): self.cache = get_cache(self.backend_name, OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0}) self.perform_cull_test(50, 19) - def test_old_initialization(self): - self.cache = get_cache('locmem://?max_entries=30&cull_frequency=0') - self.perform_cull_test(50, 19) - def test_multiple_caches(self): "Check that multiple locmem caches are isolated" mirror_cache = get_cache(self.backend_name) @@ -1075,10 +1067,6 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests): def test_cull(self): self.perform_cull_test(50, 29) - def test_old_initialization(self): - self.cache = get_cache('file://%s?max_entries=30' % self.dirname) - self.perform_cull_test(50, 29) - class CustomCacheKeyValidationTests(unittest.TestCase): """ @@ -1088,7 +1076,7 @@ class CustomCacheKeyValidationTests(unittest.TestCase): """ def test_custom_key_validation(self): - cache = get_cache('cache.liberal_backend://') + cache = get_cache('cache.liberal_backend.CacheClass') # this key is both longer than 250 characters, and has spaces key = 'some key with spaces' * 15 @@ -1100,10 +1088,6 @@ class CustomCacheKeyValidationTests(unittest.TestCase): class GetCacheTests(unittest.TestCase): def test_simple(self): - cache = get_cache('locmem://') - from django.core.cache.backends.locmem import LocMemCache - self.assertIsInstance(cache, LocMemCache) - from django.core.cache import cache self.assertIsInstance(cache, get_cache('default').__class__)