Selaa lähdekoodia

celery.decorators.task replaced with celery.task, where the latter does not support magic keyword arguments.

Ask Solem 14 vuotta sitten
vanhempi
commit
d4013e5389

+ 1 - 1
FAQ

@@ -655,7 +655,7 @@ Or to schedule a periodic task at a specific time, use the
 .. code-block:: python
 
     from celery.task.schedules import crontab
-    from celery.decorators import periodic_task
+    from celery.task import periodic_task
 
     @periodic_task(run_every=crontab(hours=7, minute=30, day_of_week="mon"))
     def every_monday_morning():

+ 11 - 0
celery/app/base.py

@@ -219,8 +219,19 @@ class BaseApp(object):
         if isinstance(c.CELERY_TASK_RESULT_EXPIRES, int):
             c["CELERY_TASK_RESULT_EXPIRES"] = timedelta(
                     seconds=c.CELERY_TASK_RESULT_EXPIRES)
+
+        # Install backend cleanup periodic task.
+        if c.CELERY_TASK_RESULT_EXPIRES:
+            from celery.schedules import crontab
+            c.CELERYBEAT_SCHEDULE.setdefault("celery.backend_cleanup",
+                    dict(task="celery.backend_cleanup",
+                         schedule=crontab(minute="00", hour="04",
+                                          day_of_week="*"),
+                         options={"expires": 12 * 3600}))
+
         return c
 
+
     def mail_admins(self, subject, body, fail_silently=False):
         """Send an e-mail to the admins in conf.ADMINS."""
         if not self.conf.ADMINS:

+ 27 - 5
celery/decorators.py

@@ -1,18 +1,40 @@
+# -*- coding: utf-8 -*-
 """
+celery.decorators✞
+==================
 
-Decorators
+Depreacted decorators, use `celery.task.task`,
+and `celery.task.periodic_task` instead.
+
+The new decorators does not support magic keyword arguments.
+
+:copyright: (c) 2009 - 2010 by Ask Solem.
+:license: BSD, see LICENSE for more details.
 
 """
+import warnings
+
 from celery import task as _task
 
 
-def task(*args, **kwargs):
+DEPRECATION_TEXT = """\
+The `celery.decorators` module and the magic keyword arguments
+are pending deprecation and will be deprecated in 2.4, then removed
+in 3.0.
+
+`task.request` should be used instead of magic keyword arguments,
+and `celery.task.task` used instead of `celery.decorators.task`.
+
+"""
+
+
+def task(*args, **kwargs):  # ✞
+    warnings.warn(PendingDeprecationWarning(DEPRECATION_TEXT))
     kwargs.setdefault("accept_magic_kwargs", True)
     return _task.task(*args, **kwargs)
 
 
-def periodic_task(*args, **kwargs):
+def periodic_task(*args, **kwargs):  # ✞
+    warnings.warn(PendingDeprecationWarning(DEPRECATION_TEXT))
     kwargs.setdefault("accept_magic_kwargs", True)
     return _task.periodic_task(*args, **kwargs)
-
-

+ 16 - 7
celery/task/__init__.py

@@ -1,8 +1,4 @@
-"""
-
-Working with tasks and task sets.
-
-"""
+# -*- coding: utf-8 -*-
 import warnings
 
 from celery.app import app_or_default
@@ -79,7 +75,19 @@ def periodic_task(*args, **options):
     return task(**dict({"base": PeriodicTask}, **options))
 
 
-def ping():
+@task(name="celery.backend_cleanup")
+def backend_cleanup():
+    backend_cleanup.backend.cleanup()
+
+
+class PingTask(Task):  # ✞
+    name = "celery.ping"
+
+    def run(self, **kwargs):
+        return "pong"
+
+
+def ping():  # ✞
     """Deprecated and scheduled for removal in Celery 2.3.
 
     Please use :meth:`celery.task.control.ping` instead.
@@ -88,5 +96,6 @@ def ping():
     warnings.warn(DeprecationWarning(
         "The ping task has been deprecated and will be removed in Celery "
         "v2.3.  Please use inspect.ping instead."))
-    from celery.task.builtins import PingTask
     return PingTask.apply_async().get()
+
+

+ 1 - 1
celery/tests/functional/tasks.py

@@ -1,6 +1,6 @@
 import time
 
-from celery.decorators import task
+from celery.task import task
 from celery.task.sets import subtask
 
 

+ 1 - 1
celery/tests/test_task.py

@@ -6,7 +6,7 @@ from pyparsing import ParseException
 
 from celery import task
 from celery.app import app_or_default
-from celery.decorators import task as task_dec
+from celery.task import task as task_dec
 from celery.exceptions import RetryTaskError
 from celery.execute import send_task
 from celery.result import EagerResult

+ 4 - 4
celery/tests/test_task_builtins.py

@@ -1,6 +1,6 @@
 from celery.tests.utils import unittest
 
-from celery.task.builtins import PingTask, DeleteExpiredTaskMetaTask
+from celery.task import PingTask, backend_cleanup
 from celery.utils.serialization import pickle
 
 
@@ -8,13 +8,13 @@ def some_func(i):
     return i * i
 
 
-class TestPingTask(unittest.TestCase):
+class test_PingTask(unittest.TestCase):
 
     def test_ping(self):
         self.assertEqual(PingTask.apply().get(), 'pong')
 
 
-class TestDeleteExpiredTaskMetaTask(unittest.TestCase):
+class test_backend_cleanup(unittest.TestCase):
 
     def test_run(self):
-        DeleteExpiredTaskMetaTask.apply()
+        backend_cleanup.apply()

+ 1 - 1
celery/tests/test_task_control.py

@@ -4,7 +4,7 @@ from kombu.pidbox import Mailbox
 
 from celery.app import app_or_default
 from celery.task import control
-from celery.task.builtins import PingTask
+from celery.task import PingTask
 from celery.utils import gen_unique_id
 from celery.utils.functional import wraps
 

+ 2 - 2
celery/tests/test_worker.py

@@ -10,8 +10,8 @@ from celery.utils.timer2 import Timer
 
 from celery.app import app_or_default
 from celery.concurrency.base import BasePool
-from celery.decorators import task as task_dec
-from celery.decorators import periodic_task as periodic_task_dec
+from celery.task import task as task_dec
+from celery.task import periodic_task as periodic_task_dec
 from celery.utils import gen_unique_id
 from celery.worker import WorkController
 from celery.worker.buckets import FastQueue

+ 2 - 2
celery/tests/test_worker_control.py

@@ -9,9 +9,9 @@ from celery.utils.timer2 import Timer
 
 from celery.app import app_or_default
 from celery.datastructures import AttributeDict
-from celery.decorators import task
+from celery.task import task
 from celery.registry import tasks
-from celery.task.builtins import PingTask
+from celery.task import PingTask
 from celery.utils import gen_unique_id
 from celery.worker.buckets import FastQueue
 from celery.worker.job import TaskRequest

+ 4 - 4
celery/tests/test_worker_job.py

@@ -11,7 +11,7 @@ from celery import states
 from celery.app import app_or_default
 from celery.concurrency.base import BasePool
 from celery.datastructures import ExceptionInfo
-from celery.decorators import task as task_dec
+from celery.task import task as task_dec
 from celery.exceptions import RetryTaskError, NotRegistered
 from celery.log import setup_logger
 from celery.result import AsyncResult
@@ -37,7 +37,7 @@ def on_ack():
     scratch["ACK"] = True
 
 
-@task_dec()
+@task_dec(accept_magic_kwargs=True)
 def mytask(i, **kwargs):
     return i ** i
 
@@ -54,13 +54,13 @@ class MyTaskIgnoreResult(Task):
         return i ** i
 
 
-@task_dec()
+@task_dec(accept_magic_kwargs=True)
 def mytask_some_kwargs(i, logfile):
     some_kwargs_scratchpad["logfile"] = logfile
     return i ** i
 
 
-@task_dec()
+@task_dec(accept_magic_kwargs=True)
 def mytask_raising(i, **kwargs):
     raise KeyError(i)
 

+ 0 - 1
contrib/release/core-modules.txt

@@ -28,7 +28,6 @@ celery/signals.py
 celery/states.py
 celery/task/__init__.py
 celery/task/base.py
-celery/task/builtins.py
 celery/task/control.py
 celery/task/sets.py
 celery/worker/__init__.py

+ 2 - 2
docs/configuration.rst

@@ -640,7 +640,7 @@ Time (in seconds, or a :class:`~datetime.timedelta` object) for when after
 stored task tombstones will be deleted.
 
 A built-in periodic task will delete the results after this time
-(:class:`celery.task.builtins.backend_cleanup`).
+(:class:`celery.task.backend_cleanup`).
 
 .. note::
 
@@ -760,7 +760,7 @@ Example:
 
 .. code-block:: python
 
-    from celery.decorators import task
+    from celery.task import task
     from celery.exceptions import SoftTimeLimitExceeded
 
     @task()

+ 1 - 1
docs/getting-started/first-steps-with-celery.rst

@@ -22,7 +22,7 @@ like this:
 
 .. code-block:: python
 
-    from celery.decorators import task
+    from celery.task import task
 
     @task
     def add(x, y):

+ 1 - 1
docs/homepage/exampletask.txt

@@ -1,4 +1,4 @@
-from celery.decorators import task
+from celery.task import task
 
 
 @task

+ 1 - 1
docs/homepage/index.html

@@ -80,7 +80,7 @@ pageTracker._trackPageview();
 
         <h3>Example</h3>
         <p>This is a simple task adding two numbers:</p>
-<div class="highlight"><pre><span class="kn">from</span> <span class="nn">celery.decorators</span> <span class="kn">import</span> <span class="n">task</span>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">celery.task</span> <span class="kn">import</span> <span class="n">task</span>
 
 <span class="nd">@task</span>
 <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>

+ 1 - 1
docs/includes/introduction.txt

@@ -69,7 +69,7 @@ adding two numbers:
 
 .. code-block:: python
 
-    from celery.decorators import task
+    from celery.task import task
 
     @task
     def add(x, y):

+ 2 - 2
docs/internals/app-overview.rst

@@ -93,7 +93,7 @@ Deprecations
 ============
 
 * celery.task.ping
-  celery.task.builtins.PingTask
+  celery.task.PingTask
 
   Inferior to the ping remote control command.
   Will be removed in Celery 2.3.
@@ -125,7 +125,7 @@ Aliases (Pending deprecation)
 * celery.task.sets
     * .TaskSet -> {app.TaskSet}
 
-* celery.decorators
+* celery.decorators / celery.task
     * .task -> {app.task}
 
 * celery.execute

+ 0 - 5
docs/internals/moduleindex.rst

@@ -58,8 +58,6 @@ celery.worker.control
 
 * celery.worker.registry
 
-* celery.worker.builtins
-
 
 Tasks
 =====
@@ -82,9 +80,6 @@ celery.task.http
 celery.task.control
 -------------------
 
-celery.task.builtins
---------------------
-
 Execution
 =========
 

+ 0 - 11
docs/reference/celery.task.builtins.rst

@@ -1,11 +0,0 @@
-==============================================
- celery.task.builtins
-==============================================
-
-.. contents::
-    :local:
-.. currentmodule:: celery.task.builtins
-
-.. automodule:: celery.task.builtins
-    :members:
-    :undoc-members:

+ 0 - 1
docs/reference/index.rst

@@ -21,7 +21,6 @@
     celery.schedules
     celery.signals
     celery.exceptions
-    celery.task.builtins
     celery.loaders
     celery.loaders.app
     celery.loaders.default

+ 6 - 51
docs/userguide/tasks.rst

@@ -422,64 +422,19 @@ This makes more sense from the reusable app perspective anyway.
 Decorating tasks
 ================
 
-Using decorators with tasks requires extra steps because of the magic keyword
-arguments.
-
-If you have the following task and decorator:
+When using other decorators you must make sure that the `task`
+decorator is applied last:
 
 .. code-block:: python
 
-    from celery.utils.functional import wraps
-
-    def decorator(task):
-
-        @wraps(task)
-        def _decorated(*args, **kwargs):
-            print("inside decorator")
-            return task(*args, **kwargs)
-
-
-    @decorator
     @task
+    @decorator2
+    @decorator1
     def add(x, y):
         return x + y
 
-Then the worker will see that the task is accepting keyword arguments,
-while it really doesn't, resulting in an error.
-
-The workaround is to either have your task accept arbitrary keyword
-arguments:
-
-.. code-block:: python
-
-    @decorator
-    @task
-    def add(x, y, **kwargs):
-        return x + y
-
-or patch the decorator to preserve the original signature:
-
-.. code-block:: python
-
-    from inspect import getargspec
-    from celery.utils.functional import wraps
-
-    def decorator(task):
-
-        @wraps(task)
-        def _decorated(*args, **kwargs):
-            print("in decorator")
-            return task(*args, **kwargs)
-        _decorated.argspec = inspect.getargspec(task)
-
-Also note the use of :func:`~celery.utils.functional.wraps` here,
-this is necessary to keep the original function name and docstring.
-
-.. note::
 
-    The magic keyword arguments will be deprecated in the future,
-    replaced by the `task.request` attribute in 2.2, and the
-    keyword arguments will be removed in 3.0.
+Which means the `@task` decorator must be the top statement.
 
 .. _task-states:
 
@@ -1022,7 +977,7 @@ blog/tasks.py
 .. code-block:: python
 
     from akismet import Akismet
-    from celery.decorators import task
+    from celery.task import task
 
     from django.core.exceptions import ImproperlyConfigured
     from django.contrib.sites.models import Site

+ 1 - 1
docs/userguide/tasksets.rst

@@ -43,7 +43,7 @@ Callbacks
 Let's improve our `add` task so it can accept a callback that
 takes the result as an argument::
 
-    from celery.decorators import task
+    from celery.task import task
     from celery.task.sets import subtask
 
     @task

+ 1 - 1
docs/userguide/workers.rst

@@ -120,7 +120,7 @@ time limit kills it:
 
 .. code-block:: python
 
-    from celery.decorators import task
+    from celery.task import task
     from celery.exceptions import SoftTimeLimitExceeded
 
     @task()

+ 1 - 1
examples/celery_http_gateway/urls.py

@@ -1,6 +1,6 @@
 from django.conf.urls.defaults import *
 
-from celery.task.builtins import PingTask
+from celery.task import PingTask
 from djcelery import views as celery_views
 
 # Uncomment the next two lines to enable the admin:

+ 1 - 1
examples/eventlet/tasks.py

@@ -1,4 +1,4 @@
-from celery.decorators import task
+from celery.task import task
 from eventlet.green import urllib2
 
 

+ 1 - 1
examples/eventlet/webcrawler.py

@@ -27,7 +27,7 @@ import re
 import time
 import urlparse
 
-from celery.decorators import task
+from celery.task import task
 from celery.task.sets import TaskSet
 from eventlet import Timeout
 from eventlet.green import urllib2

+ 1 - 1
examples/gevent/tasks.py

@@ -1,6 +1,6 @@
 import urllib2
 
-from celery.decorators import task
+from celery.task import task
 
 
 @task(ignore_result=True)

+ 1 - 1
examples/pythonproject/demoapp/tasks.py

@@ -1,4 +1,4 @@
-from celery.decorators import task
+from celery.task import task
 
 
 @task()