Fixes bug with configuration key prefix
This commit is contained in:
Родитель
5ae95c8a01
Коммит
7b87698992
|
@ -22,6 +22,7 @@ from kombu.utils.limits import TokenBucket # noqa
|
|||
|
||||
from celery.five import items
|
||||
from celery.utils.functional import LRUCache, first, uniq # noqa
|
||||
from celery.utils.text import match_case
|
||||
|
||||
try:
|
||||
from django.utils.functional import LazyObject, LazySettings
|
||||
|
@ -462,14 +463,17 @@ class ConfigurationView(AttributeDictMixin):
|
|||
defaults=defaults,
|
||||
key_t=key_t,
|
||||
_order=[changes] + defaults,
|
||||
prefix=prefix,
|
||||
prefix=prefix.rstrip('_') + '_' if prefix else prefix,
|
||||
)
|
||||
|
||||
def _to_keys(self, key):
|
||||
prefix = self.prefix
|
||||
if prefix:
|
||||
pkey = prefix + key if not key.startswith(prefix) else key
|
||||
return match_case(pkey, prefix), self._key(key)
|
||||
return self._key(key),
|
||||
|
||||
def _key(self, key):
|
||||
if self.prefix:
|
||||
key = self.prefix + key
|
||||
if self.prefix.isupper():
|
||||
key = key.upper()
|
||||
return self.key_t(key) if self.key_t is not None else key
|
||||
|
||||
def add_defaults(self, d):
|
||||
|
@ -478,23 +482,27 @@ class ConfigurationView(AttributeDictMixin):
|
|||
self._order.insert(1, d)
|
||||
|
||||
def __getitem__(self, key):
|
||||
key = self._key(key)
|
||||
for d in self._order:
|
||||
try:
|
||||
return d[key]
|
||||
except KeyError:
|
||||
pass
|
||||
keys = self._to_keys(key)
|
||||
for k in keys:
|
||||
for d in self._order:
|
||||
try:
|
||||
return d[k]
|
||||
except KeyError:
|
||||
pass
|
||||
if len(keys) > 1:
|
||||
raise KeyError(
|
||||
'Key not found: {0!r} (with prefix: {0!r})'.format(*keys))
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.changes[self._key(key)] = value
|
||||
|
||||
def first(self, *keys):
|
||||
return first(None, (self.get(self._key(key)) for key in keys))
|
||||
return first(None, (self.get(key) for key in keys))
|
||||
|
||||
def get(self, key, default=None):
|
||||
try:
|
||||
return self[self._key(key)]
|
||||
return self[key]
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
|
@ -511,8 +519,8 @@ class ConfigurationView(AttributeDictMixin):
|
|||
return self.changes.update(*args, **kwargs)
|
||||
|
||||
def __contains__(self, key):
|
||||
key = self._key(key)
|
||||
return any(key in m for m in self._order)
|
||||
keys = self._to_keys(key)
|
||||
return any(any(k in m for k in keys) for m in self._order)
|
||||
|
||||
def __bool__(self):
|
||||
return any(self._order)
|
||||
|
|
|
@ -599,7 +599,7 @@ class test_App(AppCase):
|
|||
CELERY_TASK_ALWAYS_EAGER = 44
|
||||
CELERY_TASK_DEFAULT_DELIVERY_MODE = 301
|
||||
|
||||
self.app.config_from_object(Config(), namespace='CELERY_')
|
||||
self.app.config_from_object(Config(), namespace='CELERY')
|
||||
self.assertEqual(self.app.conf.task_always_eager, 44)
|
||||
|
||||
def test_config_from_object__namespace_lowercase(self):
|
||||
|
@ -608,7 +608,7 @@ class test_App(AppCase):
|
|||
celery_task_always_eager = 44
|
||||
celery_task_default_delivery_mode = 301
|
||||
|
||||
self.app.config_from_object(Config(), namespace='celery_')
|
||||
self.app.config_from_object(Config(), namespace='celery')
|
||||
self.assertEqual(self.app.conf.task_always_eager, 44)
|
||||
|
||||
def test_config_from_object__mixing_new_and_old(self):
|
||||
|
|
|
@ -90,3 +90,7 @@ def pretty(value, width=80, nl_width=80, sep='\n', **kw):
|
|||
)
|
||||
else:
|
||||
return pformat(value, width=width, **kw)
|
||||
|
||||
|
||||
def match_case(s, other):
|
||||
return s.upper() if other.isupper() else s.lower()
|
||||
|
|
|
@ -90,7 +90,7 @@ or execv:
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
app.config_from_object('django.conf:settings', namespace='CELERY_')
|
||||
app.config_from_object('django.conf:settings', namespace='CELERY')
|
||||
|
||||
Next, a common practice for reusable apps is to define all tasks
|
||||
in a separate ``tasks.py`` module, and Celery does have a way to
|
||||
|
|
|
@ -11,7 +11,7 @@ app = Celery('proj')
|
|||
|
||||
# Using a string here means the worker will not have to
|
||||
# pickle the object when using Windows.
|
||||
app.config_from_object('django.conf:settings', namespace='CELERY_')
|
||||
app.config_from_object('django.conf:settings', namespace='CELERY')
|
||||
|
||||
# load task modules from all registered Django app configs.
|
||||
app.autodiscover_tasks()
|
||||
|
|
Загрузка…
Ссылка в новой задаче