Browse Source

Cleans up deprecation warnings, and always display them in celery programs

Ask Solem 13 years ago
parent
commit
f6a5c316c6

+ 2 - 1
celery/app/base.py

@@ -23,7 +23,7 @@ from threading import Lock
 from .. import datastructures
 from .. import datastructures
 from ..utils import cached_property, instantiate, lpmerge
 from ..utils import cached_property, instantiate, lpmerge
 
 
-from .defaults import DEFAULTS
+from .defaults import DEFAULTS, find_deprecated_settings
 
 
 import kombu
 import kombu
 if kombu.VERSION < (1, 1, 0):
 if kombu.VERSION < (1, 1, 0):
@@ -315,6 +315,7 @@ class BaseApp(object):
 
 
     def prepare_config(self, c):
     def prepare_config(self, c):
         """Prepare configuration before it is merged with the defaults."""
         """Prepare configuration before it is merged with the defaults."""
+        find_deprecated_settings(c)
         return c
         return c
 
 
     def mail_admins(self, subject, body, fail_silently=False):
     def mail_admins(self, subject, body, fail_silently=False):

+ 27 - 9
celery/app/defaults.py

@@ -1,5 +1,6 @@
 import sys
 import sys
 
 
+from collections import deque
 from datetime import timedelta
 from datetime import timedelta
 
 
 is_jython = sys.platform.startswith("java")
 is_jython = sys.platform.startswith("java")
@@ -32,12 +33,17 @@ def str_to_bool(term, table={"false": False, "no": False, "0": False,
 
 
 
 
 class Option(object):
 class Option(object):
+    alt = None
+    deprecate_by = None
+    remove_by = None
     typemap = dict(string=str, int=int, float=float, any=lambda v: v,
     typemap = dict(string=str, int=int, float=float, any=lambda v: v,
                    bool=str_to_bool, dict=dict, tuple=tuple)
                    bool=str_to_bool, dict=dict, tuple=tuple)
 
 
     def __init__(self, default=None, *args, **kwargs):
     def __init__(self, default=None, *args, **kwargs):
         self.default = default
         self.default = default
         self.type = kwargs.get("type") or "string"
         self.type = kwargs.get("type") or "string"
+        for attr, value in kwargs.iteritems():
+            setattr(self, attr, value)
 
 
     def to_python(self, value):
     def to_python(self, value):
         return self.typemap[self.type](value)
         return self.typemap[self.type](value)
@@ -174,13 +180,25 @@ NAMESPACES = {
 }
 }
 
 
 
 
-def _flatten(d, ns=""):
-    acc = []
-    for key, value in d.iteritems():
-        if isinstance(value, dict):
-            acc.extend(_flatten(value, ns=key + '_'))
-        else:
-            acc.append((ns + key, value.default))
-    return acc
+def flatten(d, ns=""):
+    stack = deque([(ns, d)])
+    while stack:
+        name, space = stack.popleft()
+        for key, value in space.iteritems():
+            if isinstance(value, dict):
+                stack.append((name + key + '_', value))
+            else:
+                yield name + key, value
 
 
-DEFAULTS = dict(_flatten(NAMESPACES))
+
+def find_deprecated_settings(source):
+    from celery.utils import warn_deprecated
+    for name, opt in flatten(NAMESPACES):
+        if (opt.deprecate_by or opt.remove_by) and getattr(source, name, None):
+            warn_deprecated(description="The %r setting" % (name, ),
+                            deprecation=opt.deprecate_by,
+                            removal=opt.remove_by,
+                            alternative=opt.alt)
+
+
+DEFAULTS = dict((key, value.default) for key, value in flatten(NAMESPACES))

+ 1 - 0
celery/backends/mongodb.py

@@ -14,6 +14,7 @@ from ..utils.timeutils import maybe_timedelta
 
 
 from .base import BaseDictBackend
 from .base import BaseDictBackend
 
 
+
 class Bunch:
 class Bunch:
 
 
     def __init__(self, **kw):
     def __init__(self, **kw):

+ 7 - 0
celery/bin/base.py

@@ -2,10 +2,17 @@ from __future__ import absolute_import
 
 
 import os
 import os
 import sys
 import sys
+import warnings
 
 
 from optparse import OptionParser, make_option as Option
 from optparse import OptionParser, make_option as Option
 
 
 from .. import __version__, Celery
 from .. import __version__, Celery
+from ..exceptions import CDeprecationWarning, CPendingDeprecationWarning
+
+
+# always enable DeprecationWarnings, so our users can see them.
+for warning in (CDeprecationWarning, CPendingDeprecationWarning):
+    warnings.simplefilter("once", warning, 0)
 
 
 
 
 class Command(object):
 class Command(object):

+ 2 - 1
celery/decorators.py

@@ -17,9 +17,10 @@ from __future__ import absolute_import
 import warnings
 import warnings
 
 
 from . import task as _task
 from . import task as _task
+from .exceptions import CDeprecationWarning
 
 
 
 
-warnings.warn(PendingDeprecationWarning("""
+warnings.warn(CDeprecationWarning("""
 The `celery.decorators` module and the magic keyword arguments
 The `celery.decorators` module and the magic keyword arguments
 are pending deprecation and will be deprecated in 2.4, then removed
 are pending deprecation and will be deprecated in 2.4, then removed
 in 3.0.
 in 3.0.

+ 8 - 0
celery/exceptions.py

@@ -61,3 +61,11 @@ class TaskRevokedError(Exception):
 
 
 class NotConfigured(UserWarning):
 class NotConfigured(UserWarning):
     """Celery has not been configured, as no config module has been found."""
     """Celery has not been configured, as no config module has been found."""
+
+
+class CPendingDeprecationWarning(PendingDeprecationWarning):
+    pass
+
+
+class CDeprecationWarning(DeprecationWarning):
+    pass

+ 0 - 2
celery/loaders/__init__.py

@@ -1,7 +1,5 @@
 from __future__ import absolute_import
 from __future__ import absolute_import
 
 
-import os
-
 from .. import current_app
 from .. import current_app
 from ..utils import deprecated, get_cls_by_name
 from ..utils import deprecated, get_cls_by_name
 
 

+ 2 - 1
celery/task/__init__.py

@@ -4,6 +4,7 @@ from __future__ import absolute_import
 import warnings
 import warnings
 
 
 from ..app import app_or_default
 from ..app import app_or_default
+from ..exceptions import CDeprecationWarning
 
 
 from .base import Task, PeriodicTask
 from .base import Task, PeriodicTask
 from .sets import TaskSet, subtask
 from .sets import TaskSet, subtask
@@ -98,7 +99,7 @@ def ping():  # ✞
     Please use :meth:`celery.task.control.ping` instead.
     Please use :meth:`celery.task.control.ping` instead.
 
 
     """
     """
-    warnings.warn(DeprecationWarning(
+    warnings.warn(CDeprecationWarning(
         "The ping task has been deprecated and will be removed in Celery "
         "The ping task has been deprecated and will be removed in Celery "
         "v2.3.  Please use inspect.ping instead."))
         "v2.3.  Please use inspect.ping instead."))
     return PingTask.apply_async().get()
     return PingTask.apply_async().get()

+ 2 - 1
celery/task/schedules.py

@@ -2,8 +2,9 @@ from __future__ import absolute_import
 
 
 import warnings
 import warnings
 from ..schedules import schedule, crontab_parser, crontab
 from ..schedules import schedule, crontab_parser, crontab
+from ..exceptions import CDeprecationWarning
 
 
 __all__ = ["schedule", "crontab_parser", "crontab"]
 __all__ = ["schedule", "crontab_parser", "crontab"]
 
 
-warnings.warn(DeprecationWarning(
+warnings.warn(CDeprecationWarning(
     "celery.task.schedules is deprecated and renamed to celery.schedules"))
     "celery.task.schedules is deprecated and renamed to celery.schedules"))

+ 4 - 3
celery/task/sets.py

@@ -6,6 +6,7 @@ import warnings
 from .. import registry
 from .. import registry
 from ..app import app_or_default
 from ..app import app_or_default
 from ..datastructures import AttributeDict
 from ..datastructures import AttributeDict
+from ..exceptions import CDeprecationWarning
 from ..utils import cached_property, reprcall, uuid
 from ..utils import cached_property, reprcall, uuid
 from ..utils.compat import UserList
 from ..utils.compat import UserList
 
 
@@ -138,7 +139,7 @@ class TaskSet(UserList):
                 self._task_name = task.name
                 self._task_name = task.name
                 warnings.warn(TASKSET_DEPRECATION_TEXT % {
                 warnings.warn(TASKSET_DEPRECATION_TEXT % {
                                 "cls": task.__class__.__name__},
                                 "cls": task.__class__.__name__},
-                              DeprecationWarning)
+                              CDeprecationWarning)
         self.data = list(tasks or [])
         self.data = list(tasks or [])
         self.total = len(self.tasks)
         self.total = len(self.tasks)
         self.Publisher = Publisher or self.app.amqp.TaskPublisher
         self.Publisher = Publisher or self.app.amqp.TaskPublisher
@@ -182,12 +183,12 @@ class TaskSet(UserList):
     def task(self):
     def task(self):
         warnings.warn(
         warnings.warn(
             "TaskSet.task is deprecated and will be removed in 1.4",
             "TaskSet.task is deprecated and will be removed in 1.4",
-            DeprecationWarning)
+            CDeprecationWarning)
         return self._task
         return self._task
 
 
     @property
     @property
     def task_name(self):
     def task_name(self):
         warnings.warn(
         warnings.warn(
             "TaskSet.task_name is deprecated and will be removed in 1.4",
             "TaskSet.task_name is deprecated and will be removed in 1.4",
-            DeprecationWarning)
+            CDeprecationWarning)
         return self._task_name
         return self._task_name

+ 1 - 1
celery/tests/test_app/test_loaders.py

@@ -12,7 +12,7 @@ from celery.loaders import default
 from celery.loaders.app import AppLoader
 from celery.loaders.app import AppLoader
 
 
 from celery.tests.compat import catch_warnings
 from celery.tests.compat import catch_warnings
-from celery.tests.utils import unittest, AppCase, with_environ
+from celery.tests.utils import unittest, AppCase
 
 
 
 
 class ObjectConfig(object):
 class ObjectConfig(object):

+ 3 - 2
celery/tests/test_task/test_task_builtins.py

@@ -3,6 +3,7 @@ from __future__ import with_statement
 import warnings
 import warnings
 
 
 from celery.task import ping, PingTask, backend_cleanup
 from celery.task import ping, PingTask, backend_cleanup
+from celery.exceptions import CDeprecationWarning
 from celery.tests.compat import catch_warnings
 from celery.tests.compat import catch_warnings
 from celery.tests.utils import unittest
 from celery.tests.utils import unittest
 
 
@@ -23,7 +24,7 @@ class test_deprecated(unittest.TestCase):
                 pong = ping()
                 pong = ping()
                 warning = log[0].message
                 warning = log[0].message
                 self.assertEqual(pong, "pong")
                 self.assertEqual(pong, "pong")
-                self.assertIsInstance(warning, DeprecationWarning)
+                self.assertIsInstance(warning, CDeprecationWarning)
                 self.assertIn("ping task has been deprecated",
                 self.assertIn("ping task has been deprecated",
                               warning.args[0])
                               warning.args[0])
             finally:
             finally:
@@ -37,7 +38,7 @@ class test_deprecated(unittest.TestCase):
             TaskSet()
             TaskSet()
             subtask(PingTask)
             subtask(PingTask)
             for w in (log[0].message, log[1].message):
             for w in (log[0].message, log[1].message):
-                self.assertIsInstance(w, DeprecationWarning)
+                self.assertIsInstance(w, CDeprecationWarning)
                 self.assertIn("is deprecated", w.args[0])
                 self.assertIn("is deprecated", w.args[0])
 
 
 
 

+ 18 - 8
celery/utils/__init__.py

@@ -20,6 +20,8 @@ from pprint import pprint
 from kombu.utils import cached_property, gen_unique_id  # noqa
 from kombu.utils import cached_property, gen_unique_id  # noqa
 uuid = gen_unique_id
 uuid = gen_unique_id
 
 
+from ..exceptions import CPendingDeprecationWarning, CDeprecationWarning
+
 from .compat import StringIO
 from .compat import StringIO
 from .encoding import safe_repr as _safe_repr
 from .encoding import safe_repr as _safe_repr
 
 
@@ -39,6 +41,18 @@ DEPRECATION_FMT = """
 """
 """
 
 
 
 
+def warn_deprecated(description=None, deprecation=None, removal=None,
+        alternative=None):
+    ctx = {"description": description,
+           "deprecation": deprecation, "removal": removal,
+           "alternative": alternative}
+    if deprecation is not None:
+        w = CPendingDeprecationWarning(PENDING_DEPRECATION_FMT % ctx)
+    else:
+        w = CDeprecationWarning(DEPRECATION_FMT % ctx)
+    warnings.warn(w)
+
+
 def deprecated(description=None, deprecation=None, removal=None,
 def deprecated(description=None, deprecation=None, removal=None,
         alternative=None):
         alternative=None):
 
 
@@ -46,14 +60,10 @@ def deprecated(description=None, deprecation=None, removal=None,
 
 
         @wraps(fun)
         @wraps(fun)
         def __inner(*args, **kwargs):
         def __inner(*args, **kwargs):
-            ctx = {"description": description or get_full_cls_name(fun),
-                   "deprecation": deprecation, "removal": removal,
-                   "alternative": alternative}
-            if deprecation is not None:
-                w = PendingDeprecationWarning(PENDING_DEPRECATION_FMT % ctx)
-            else:
-                w = DeprecationWarning(DEPRECATION_FMT % ctx)
-            warnings.warn(w)
+            warn_deprecated(description=description or get_full_cls_name(fun),
+                            deprecation=deprecation,
+                            removal=removal,
+                            alternative=alternative)
             return fun(*args, **kwargs)
             return fun(*args, **kwargs)
         return __inner
         return __inner
     return _inner
     return _inner

+ 0 - 1
celery/worker/control/__init__.py

@@ -6,4 +6,3 @@ from . import registry
 from . import builtins  # noqa
 from . import builtins  # noqa
 
 
 Panel = registry.Panel
 Panel = registry.Panel
-