Fixes bug with configuration key prefix

This commit is contained in:
Ask Solem 2015-12-08 14:09:59 -08:00
Родитель 5ae95c8a01
Коммит 7b87698992
5 изменённых файлов: 31 добавлений и 19 удалений

Просмотреть файл

@ -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()