Browse Source

Remove support for callables, only Task classes is allowed

Ask Solem 15 years ago
parent
commit
cdffcb08b9

+ 4 - 5
celery/execute.py

@@ -203,9 +203,8 @@ class ExecuteWrapper(object):
     If the call results in an exception, it saves the exception as the task
     If the call results in an exception, it saves the exception as the task
     result, and sets the task status to ``"FAILURE"``.
     result, and sets the task status to ``"FAILURE"``.
 
 
-    :param fun: Callable object to execute.
+    :param task_name: The name of the task to execute.
     :param task_id: The unique id of the task.
     :param task_id: The unique id of the task.
-    :param task_name: Name of the task.
     :param args: List of positional args to pass on to the function.
     :param args: List of positional args to pass on to the function.
     :param kwargs: Keyword arguments mapping to pass on to the function.
     :param kwargs: Keyword arguments mapping to pass on to the function.
 
 
@@ -214,8 +213,7 @@ class ExecuteWrapper(object):
 
 
     """
     """
 
 
-    def __init__(self, fun, task_id, task_name, args=None, kwargs=None):
-        self.fun = fun
+    def __init__(self, task_name, task_id, args=None, kwargs=None):
         self.task_id = task_id
         self.task_id = task_id
         self.task_name = task_name
         self.task_name = task_name
         self.args = args or []
         self.args = args or []
@@ -236,11 +234,12 @@ class ExecuteWrapper(object):
 
 
     def execute(self):
     def execute(self):
         # Convenience variables
         # Convenience variables
-        fun = self.fun
         task_id = self.task_id
         task_id = self.task_id
         task_name = self.task_name
         task_name = self.task_name
         args = self.args
         args = self.args
         kwargs = self.kwargs
         kwargs = self.kwargs
+        fun = tasks[task_name]
+        self.fun = fun # Set fun for handlers.
 
 
         # Run task loader init handler.
         # Run task loader init handler.
         current_loader.on_task_init(task_id, fun)
         current_loader.on_task_init(task_id, fun)

+ 1 - 1
celery/task/__init__.py

@@ -12,7 +12,7 @@ from celery.task.base import Task, TaskSet, PeriodicTask
 from celery.task.base import ExecuteRemoteTask
 from celery.task.base import ExecuteRemoteTask
 from celery.task.base import AsynchronousMapTask
 from celery.task.base import AsynchronousMapTask
 from celery.task.builtins import DeleteExpiredTaskMetaTask, PingTask
 from celery.task.builtins import DeleteExpiredTaskMetaTask, PingTask
-from celery.execute import apply_async, delay_task
+from celery.execute import apply_async
 from celery.serialization import pickle
 from celery.serialization import pickle
 from celery.task.rest import RESTProxyTask
 from celery.task.rest import RESTProxyTask
 
 

+ 0 - 13
celery/tests/test_registry.py

@@ -2,8 +2,6 @@ import unittest
 from celery import registry
 from celery import registry
 from celery.task import Task, PeriodicTask
 from celery.task import Task, PeriodicTask
 
 
-FUNC_TASK_NAME = "celery.unittest.func_task"
-
 
 
 class TestTask(Task):
 class TestTask(Task):
     name = "celery.unittest.test_task"
     name = "celery.unittest.test_task"
@@ -20,9 +18,6 @@ class TestPeriodicTask(PeriodicTask):
         return True
         return True
 
 
 
 
-def func_task(**kwargs):
-    return True
-
 
 
 class TestTaskRegistry(unittest.TestCase):
 class TestTaskRegistry(unittest.TestCase):
 
 
@@ -44,37 +39,29 @@ class TestTaskRegistry(unittest.TestCase):
                 "TaskRegistry has composited dict")
                 "TaskRegistry has composited dict")
 
 
         self.assertRegisterUnregisterCls(r, TestTask)
         self.assertRegisterUnregisterCls(r, TestTask)
-        self.assertRegisterUnregisterFunc(r, func_task, FUNC_TASK_NAME)
         self.assertRegisterUnregisterCls(r, TestPeriodicTask)
         self.assertRegisterUnregisterCls(r, TestPeriodicTask)
 
 
         tasks = r.get_all()
         tasks = r.get_all()
         self.assertTrue(isinstance(tasks.get(TestTask.name), TestTask))
         self.assertTrue(isinstance(tasks.get(TestTask.name), TestTask))
         self.assertTrue(isinstance(tasks.get(TestPeriodicTask.name),
         self.assertTrue(isinstance(tasks.get(TestPeriodicTask.name),
                                    TestPeriodicTask))
                                    TestPeriodicTask))
-        self.assertEquals(tasks.get(FUNC_TASK_NAME), func_task)
 
 
         regular = r.get_all_regular()
         regular = r.get_all_regular()
         self.assertTrue(TestTask.name in regular)
         self.assertTrue(TestTask.name in regular)
         self.assertFalse(TestPeriodicTask.name in regular)
         self.assertFalse(TestPeriodicTask.name in regular)
-        self.assertTrue(FUNC_TASK_NAME in regular)
 
 
         periodic = r.get_all_periodic()
         periodic = r.get_all_periodic()
         self.assertFalse(TestTask.name in periodic)
         self.assertFalse(TestTask.name in periodic)
         self.assertTrue(TestPeriodicTask.name in periodic)
         self.assertTrue(TestPeriodicTask.name in periodic)
-        self.assertFalse(FUNC_TASK_NAME in periodic)
 
 
         self.assertTrue(isinstance(r.get_task(TestTask.name), TestTask))
         self.assertTrue(isinstance(r.get_task(TestTask.name), TestTask))
         self.assertTrue(isinstance(r.get_task(TestPeriodicTask.name),
         self.assertTrue(isinstance(r.get_task(TestPeriodicTask.name),
                                    TestPeriodicTask))
                                    TestPeriodicTask))
-        self.assertEquals(r.get_task(FUNC_TASK_NAME), func_task)
 
 
         r.unregister(TestTask)
         r.unregister(TestTask)
         self.assertFalse(TestTask.name in r)
         self.assertFalse(TestTask.name in r)
         r.unregister(TestPeriodicTask)
         r.unregister(TestPeriodicTask)
         self.assertFalse(TestPeriodicTask.name in r)
         self.assertFalse(TestPeriodicTask.name in r)
-        r.unregister(FUNC_TASK_NAME)
-        self.assertFalse(FUNC_TASK_NAME in r)
 
 
-        self.assertTrue(func_task())
         self.assertTrue(TestTask().run())
         self.assertTrue(TestTask().run())
         self.assertTrue(TestPeriodicTask().run())
         self.assertTrue(TestPeriodicTask().run())

+ 9 - 9
celery/tests/test_task.py

@@ -10,12 +10,14 @@ from celery import messaging
 from celery.result import EagerResult
 from celery.result import EagerResult
 from celery.backends import default_backend
 from celery.backends import default_backend
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
+from celery.decorators import task as task_dec
 
 
-
-def return_True(self, **kwargs):
+def return_True(*args, **kwargs):
     # Task run functions can't be closures/lambdas, as they're pickled.
     # Task run functions can't be closures/lambdas, as they're pickled.
     return True
     return True
-registry.tasks.register(return_True, "cu.return-true")
+
+
+return_True_task = task_dec()(return_True)
 
 
 
 
 def raise_exception(self, **kwargs):
 def raise_exception(self, **kwargs):
@@ -167,6 +169,7 @@ class TestCeleryTasks(unittest.TestCase):
         task_kwargs = task_data.get("kwargs", {})
         task_kwargs = task_data.get("kwargs", {})
         if test_eta:
         if test_eta:
             self.assertTrue(isinstance(task_data.get("eta"), datetime))
             self.assertTrue(isinstance(task_data.get("eta"), datetime))
+            print("TASK_KWARGS: %s" % task_kwargs)
         for arg_name, arg_value in kwargs.items():
         for arg_name, arg_value in kwargs.items():
             self.assertEquals(task_kwargs.get(arg_name), arg_value)
             self.assertEquals(task_kwargs.get(arg_name), arg_value)
 
 
@@ -202,7 +205,7 @@ class TestCeleryTasks(unittest.TestCase):
         self.assertNextTaskDataEquals(consumer, presult, t1.name)
         self.assertNextTaskDataEquals(consumer, presult, t1.name)
 
 
         # With arguments.
         # With arguments.
-        presult2 = task.delay_task(t1.name, name="George Constanza")
+        presult2 = task.apply_async(t1, name="George Constanza")
         self.assertNextTaskDataEquals(consumer, presult2, t1.name,
         self.assertNextTaskDataEquals(consumer, presult2, t1.name,
                 name="George Constanza")
                 name="George Constanza")
 
 
@@ -218,12 +221,9 @@ class TestCeleryTasks(unittest.TestCase):
         self.assertNextTaskDataEquals(consumer, presult2, t1.name,
         self.assertNextTaskDataEquals(consumer, presult2, t1.name,
                 name="George Constanza", test_eta=True)
                 name="George Constanza", test_eta=True)
 
 
-        self.assertRaises(registry.tasks.NotRegistered, task.delay_task,
-                "some.task.that.should.never.exist.X.X.X.X.X")
-
         # Discarding all tasks.
         # Discarding all tasks.
         task.discard_all()
         task.discard_all()
-        tid3 = task.delay_task(t1.name)
+        tid3 = task.apply_async(t1)
         self.assertEquals(task.discard_all(), 1)
         self.assertEquals(task.discard_all(), 1)
         self.assertTrue(consumer.fetch() is None)
         self.assertTrue(consumer.fetch() is None)
 
 
@@ -250,7 +250,7 @@ class TestTaskSet(unittest.TestCase):
     def test_function_taskset(self):
     def test_function_taskset(self):
         from celery import conf
         from celery import conf
         conf.ALWAYS_EAGER = True
         conf.ALWAYS_EAGER = True
-        ts = task.TaskSet("cu.return-true", [
+        ts = task.TaskSet(return_True_task.name, [
             [[1], {}], [[2], {}], [[3], {}], [[4], {}], [[5], {}]])
             [[1], {}], [[2], {}], [[3], {}], [[4], {}], [[5], {}]])
         res = ts.run()
         res = ts.run()
         self.assertEquals(res.join(), [True, True, True, True, True])
         self.assertEquals(res.join(), [True, True, True, True, True])

+ 11 - 8
celery/tests/test_worker.py

@@ -10,11 +10,12 @@ from celery import registry
 from celery.serialization import pickle
 from celery.serialization import pickle
 from celery.utils import gen_unique_id
 from celery.utils import gen_unique_id
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
+from celery.decorators import task as task_dec
 
 
 
 
+@task_dec()
 def foo_task(x, y, z, **kwargs):
 def foo_task(x, y, z, **kwargs):
     return x * y * z
     return x * y * z
-registry.tasks.register(foo_task, name="c.u.foo")
 
 
 
 
 class MockLogger(object):
 class MockLogger(object):
@@ -108,13 +109,14 @@ class TestAMQPListener(unittest.TestCase):
     def test_receieve_message(self):
     def test_receieve_message(self):
         l = AMQPListener(self.bucket_queue, self.hold_queue, self.logger)
         l = AMQPListener(self.bucket_queue, self.hold_queue, self.logger)
         backend = MockBackend()
         backend = MockBackend()
-        m = create_message(backend, task="c.u.foo", args=[2, 4, 8], kwargs={})
+        m = create_message(backend, task=foo_task.name,
+                           args=[2, 4, 8], kwargs={})
 
 
         l.receive_message(m.decode(), m)
         l.receive_message(m.decode(), m)
 
 
         in_bucket = self.bucket_queue.get_nowait()
         in_bucket = self.bucket_queue.get_nowait()
         self.assertTrue(isinstance(in_bucket, TaskWrapper))
         self.assertTrue(isinstance(in_bucket, TaskWrapper))
-        self.assertEquals(in_bucket.task_name, "c.u.foo")
+        self.assertEquals(in_bucket.task_name, foo_task.name)
         self.assertEquals(in_bucket.execute(), 2 * 4 * 8)
         self.assertEquals(in_bucket.execute(), 2 * 4 * 8)
         self.assertRaises(Empty, self.hold_queue.get_nowait)
         self.assertRaises(Empty, self.hold_queue.get_nowait)
 
 
@@ -130,7 +132,8 @@ class TestAMQPListener(unittest.TestCase):
     def test_receieve_message_eta(self):
     def test_receieve_message_eta(self):
         l = AMQPListener(self.bucket_queue, self.hold_queue, self.logger)
         l = AMQPListener(self.bucket_queue, self.hold_queue, self.logger)
         backend = MockBackend()
         backend = MockBackend()
-        m = create_message(backend, task="c.u.foo", args=[2, 4, 8], kwargs={},
+        m = create_message(backend, task=foo_task.name,
+                           args=[2, 4, 8], kwargs={},
                            eta=datetime.now() + timedelta(days=1))
                            eta=datetime.now() + timedelta(days=1))
 
 
         l.receive_message(m.decode(), m)
         l.receive_message(m.decode(), m)
@@ -141,7 +144,7 @@ class TestAMQPListener(unittest.TestCase):
         self.assertTrue(isinstance(task, TaskWrapper))
         self.assertTrue(isinstance(task, TaskWrapper))
         self.assertTrue(isinstance(eta, datetime))
         self.assertTrue(isinstance(eta, datetime))
         self.assertTrue(callable(on_accept))
         self.assertTrue(callable(on_accept))
-        self.assertEquals(task.task_name, "c.u.foo")
+        self.assertEquals(task.task_name, foo_task.name)
         self.assertEquals(task.execute(), 2 * 4 * 8)
         self.assertEquals(task.execute(), 2 * 4 * 8)
         self.assertRaises(Empty, self.bucket_queue.get_nowait)
         self.assertRaises(Empty, self.bucket_queue.get_nowait)
 
 
@@ -167,7 +170,7 @@ class TestWorkController(unittest.TestCase):
         worker = self.worker
         worker = self.worker
         worker.pool = MockPool()
         worker.pool = MockPool()
         backend = MockBackend()
         backend = MockBackend()
-        m = create_message(backend, task="c.u.foo", args=[4, 8, 10],
+        m = create_message(backend, task=foo_task.name, args=[4, 8, 10],
                            kwargs={})
                            kwargs={})
         task = TaskWrapper.from_message(m, m.decode())
         task = TaskWrapper.from_message(m, m.decode())
         worker.safe_process_task(task)
         worker.safe_process_task(task)
@@ -177,7 +180,7 @@ class TestWorkController(unittest.TestCase):
         worker = self.worker
         worker = self.worker
         worker.pool = MockPool(raise_base=True)
         worker.pool = MockPool(raise_base=True)
         backend = MockBackend()
         backend = MockBackend()
-        m = create_message(backend, task="c.u.foo", args=[4, 8, 10],
+        m = create_message(backend, task=foo_task.name, args=[4, 8, 10],
                            kwargs={})
                            kwargs={})
         task = TaskWrapper.from_message(m, m.decode())
         task = TaskWrapper.from_message(m, m.decode())
         worker.safe_process_task(task)
         worker.safe_process_task(task)
@@ -187,7 +190,7 @@ class TestWorkController(unittest.TestCase):
         worker = self.worker
         worker = self.worker
         worker.pool = MockPool(raise_regular=True)
         worker.pool = MockPool(raise_regular=True)
         backend = MockBackend()
         backend = MockBackend()
-        m = create_message(backend, task="c.u.foo", args=[4, 8, 10],
+        m = create_message(backend, task=foo_task.name, args=[4, 8, 10],
                            kwargs={})
                            kwargs={})
         task = TaskWrapper.from_message(m, m.decode())
         task = TaskWrapper.from_message(m, m.decode())
         worker.safe_process_task(task)
         worker.safe_process_task(task)

+ 28 - 35
celery/tests/test_worker_job.py

@@ -12,6 +12,7 @@ from carrot.backends.base import BaseMessage
 from StringIO import StringIO
 from StringIO import StringIO
 from celery.log import setup_logger
 from celery.log import setup_logger
 from django.core import cache
 from django.core import cache
+from celery.decorators import task as task_dec
 import simplejson
 import simplejson
 import logging
 import logging
 
 
@@ -19,35 +20,37 @@ scratch = {"ACK": False}
 some_kwargs_scratchpad = {}
 some_kwargs_scratchpad = {}
 
 
 
 
-def jail(task_id, task_name, fun, args, kwargs):
-    return ExecuteWrapper(fun, task_id, task_name, args, kwargs)()
+def jail(task_id, task_name, args, kwargs):
+    return ExecuteWrapper(task_name, task_id, args, kwargs)()
 
 
 
 
 def on_ack():
 def on_ack():
     scratch["ACK"] = True
     scratch["ACK"] = True
 
 
 
 
+@task_dec()
 def mytask(i, **kwargs):
 def mytask(i, **kwargs):
     return i ** i
     return i ** i
-tasks.register(mytask, name="cu.mytask")
 
 
 
 
+@task_dec()
 def mytask_no_kwargs(i):
 def mytask_no_kwargs(i):
     return i ** i
     return i ** i
-tasks.register(mytask_no_kwargs, name="mytask_no_kwargs")
 
 
 
 
+
+@task_dec()
 def mytask_some_kwargs(i, logfile):
 def mytask_some_kwargs(i, logfile):
     some_kwargs_scratchpad["logfile"] = logfile
     some_kwargs_scratchpad["logfile"] = logfile
     return i ** i
     return i ** i
-tasks.register(mytask_some_kwargs, name="mytask_some_kwargs")
 
 
 
 
+@task_dec()
 def mytask_raising(i, **kwargs):
 def mytask_raising(i, **kwargs):
     raise KeyError(i)
     raise KeyError(i)
-tasks.register(mytask_raising, name="cu.mytask-raising")
 
 
 
 
+@task_dec()
 def get_db_connection(i, **kwargs):
 def get_db_connection(i, **kwargs):
     from django.db import connection
     from django.db import connection
     return id(connection)
     return id(connection)
@@ -57,11 +60,12 @@ get_db_connection.ignore_result = True
 class TestJail(unittest.TestCase):
 class TestJail(unittest.TestCase):
 
 
     def test_execute_jail_success(self):
     def test_execute_jail_success(self):
-        ret = jail(gen_unique_id(), gen_unique_id(), mytask, [2], {})
+        ret = jail(gen_unique_id(), mytask.name, [2], {})
         self.assertEquals(ret, 4)
         self.assertEquals(ret, 4)
 
 
     def test_execute_jail_failure(self):
     def test_execute_jail_failure(self):
-        ret = jail(gen_unique_id(), gen_unique_id(), mytask_raising, [4], {})
+        ret = jail(gen_unique_id(), mytask_raising.name,
+                   [4], {})
         self.assertTrue(isinstance(ret, ExceptionInfo))
         self.assertTrue(isinstance(ret, ExceptionInfo))
         self.assertEquals(ret.exception.args, (4, ))
         self.assertEquals(ret.exception.args, (4, ))
 
 
@@ -76,8 +80,8 @@ class TestJail(unittest.TestCase):
 
 
         connection.close = monkeypatched_connection_close
         connection.close = monkeypatched_connection_close
 
 
-        ret = jail(gen_unique_id(), gen_unique_id(),
-                   get_db_connection, [2], {})
+        ret = jail(gen_unique_id(),
+                   get_db_connection.name, [2], {})
         self.assertTrue(connection._was_closed)
         self.assertTrue(connection._was_closed)
 
 
         connection.close = old_connection_close
         connection.close = old_connection_close
@@ -96,7 +100,7 @@ class TestJail(unittest.TestCase):
 
 
         cache.cache.close = monkeypatched_cache_close
         cache.cache.close = monkeypatched_cache_close
 
 
-        jail(gen_unique_id(), gen_unique_id(), mytask, [4], {})
+        jail(gen_unique_id(), mytask.name, [4], {})
         self.assertTrue(cache._was_closed)
         self.assertTrue(cache._was_closed)
         cache.cache.close = old_cache_close
         cache.cache.close = old_cache_close
         cache.settings.CACHE_BACKEND = old_backend
         cache.settings.CACHE_BACKEND = old_backend
@@ -116,7 +120,7 @@ class TestJail(unittest.TestCase):
 
 
         cache.cache.close = monkeypatched_cache_close
         cache.cache.close = monkeypatched_cache_close
 
 
-        jail(gen_unique_id(), gen_unique_id(), mytask, [4], {})
+        jail(gen_unique_id(), mytask.name, [4], {})
         self.assertTrue(cache._was_closed)
         self.assertTrue(cache._was_closed)
         cache.cache.close = old_cache_close
         cache.cache.close = old_cache_close
         cache.settings.CACHE_BACKEND = old_backend
         cache.settings.CACHE_BACKEND = old_backend
@@ -128,19 +132,12 @@ class TestJail(unittest.TestCase):
 
 
 class TestTaskWrapper(unittest.TestCase):
 class TestTaskWrapper(unittest.TestCase):
 
 
-    def test_task_wrapper_attrs(self):
-        tw = TaskWrapper(gen_unique_id(), gen_unique_id(),
-                         mytask, [1], {"f": "x"})
-        for attr in ("task_name", "task_id", "args", "kwargs", "logger"):
-            self.assertTrue(getattr(tw, attr, None))
-
     def test_task_wrapper_repr(self):
     def test_task_wrapper_repr(self):
-        tw = TaskWrapper(gen_unique_id(), gen_unique_id(),
-                         mytask, [1], {"f": "x"})
+        tw = TaskWrapper(mytask.name, gen_unique_id(), [1], {"f": "x"})
         self.assertTrue(repr(tw))
         self.assertTrue(repr(tw))
 
 
     def test_task_wrapper_mail_attrs(self):
     def test_task_wrapper_mail_attrs(self):
-        tw = TaskWrapper(gen_unique_id(), gen_unique_id(), mytask, [], {})
+        tw = TaskWrapper(mytask.name, gen_unique_id(), [], {})
         x = tw.success_msg % {"name": tw.task_name,
         x = tw.success_msg % {"name": tw.task_name,
                               "id": tw.task_id,
                               "id": tw.task_id,
                               "return_value": 10}
                               "return_value": 10}
@@ -157,7 +154,7 @@ class TestTaskWrapper(unittest.TestCase):
         self.assertTrue(x)
         self.assertTrue(x)
 
 
     def test_from_message(self):
     def test_from_message(self):
-        body = {"task": "cu.mytask", "id": gen_unique_id(),
+        body = {"task": mytask.name, "id": gen_unique_id(),
                 "args": [2], "kwargs": {u"æØåveéðƒeæ": "bar"}}
                 "args": [2], "kwargs": {u"æØåveéðƒeæ": "bar"}}
         m = BaseMessage(body=simplejson.dumps(body), backend="foo",
         m = BaseMessage(body=simplejson.dumps(body), backend="foo",
                         content_type="application/json",
                         content_type="application/json",
@@ -170,7 +167,6 @@ class TestTaskWrapper(unittest.TestCase):
         self.assertEquals(tw.kwargs.keys()[0],
         self.assertEquals(tw.kwargs.keys()[0],
                           u"æØåveéðƒeæ".encode("utf-8"))
                           u"æØåveéðƒeæ".encode("utf-8"))
         self.assertFalse(isinstance(tw.kwargs.keys()[0], unicode))
         self.assertFalse(isinstance(tw.kwargs.keys()[0], unicode))
-        self.assertEquals(id(mytask), id(tw.task_func))
         self.assertTrue(tw.logger)
         self.assertTrue(tw.logger)
 
 
     def test_from_message_nonexistant_task(self):
     def test_from_message_nonexistant_task(self):
@@ -184,7 +180,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_execute(self):
     def test_execute(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask", tid, mytask, [4], {"f": "x"})
+        tw = TaskWrapper(mytask.name, tid, [4], {"f": "x"})
         self.assertEquals(tw.execute(), 256)
         self.assertEquals(tw.execute(), 256)
         meta = TaskMeta.objects.get(task_id=tid)
         meta = TaskMeta.objects.get(task_id=tid)
         self.assertEquals(meta.result, 256)
         self.assertEquals(meta.result, 256)
@@ -192,8 +188,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_execute_success_no_kwargs(self):
     def test_execute_success_no_kwargs(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask_no_kwargs", tid, mytask_no_kwargs,
-                         [4], {})
+        tw = TaskWrapper(mytask_no_kwargs.name, tid, [4], {})
         self.assertEquals(tw.execute(), 256)
         self.assertEquals(tw.execute(), 256)
         meta = TaskMeta.objects.get(task_id=tid)
         meta = TaskMeta.objects.get(task_id=tid)
         self.assertEquals(meta.result, 256)
         self.assertEquals(meta.result, 256)
@@ -201,8 +196,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_execute_success_some_kwargs(self):
     def test_execute_success_some_kwargs(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask_some_kwargs", tid, mytask_some_kwargs,
-                         [4], {})
+        tw = TaskWrapper(mytask_some_kwargs.name, tid, [4], {})
         self.assertEquals(tw.execute(logfile="foobaz.log"), 256)
         self.assertEquals(tw.execute(logfile="foobaz.log"), 256)
         meta = TaskMeta.objects.get(task_id=tid)
         meta = TaskMeta.objects.get(task_id=tid)
         self.assertEquals(some_kwargs_scratchpad.get("logfile"), "foobaz.log")
         self.assertEquals(some_kwargs_scratchpad.get("logfile"), "foobaz.log")
@@ -211,7 +205,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_execute_ack(self):
     def test_execute_ack(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask", tid, mytask, [4], {"f": "x"},
+        tw = TaskWrapper(mytask.name, tid, [4], {"f": "x"},
                         on_ack=on_ack)
                         on_ack=on_ack)
         self.assertEquals(tw.execute(), 256)
         self.assertEquals(tw.execute(), 256)
         meta = TaskMeta.objects.get(task_id=tid)
         meta = TaskMeta.objects.get(task_id=tid)
@@ -221,8 +215,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_execute_fail(self):
     def test_execute_fail(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask-raising", tid, mytask_raising, [4],
-                         {"f": "x"})
+        tw = TaskWrapper(mytask_raising.name, tid, [4], {"f": "x"})
         self.assertTrue(isinstance(tw.execute(), ExceptionInfo))
         self.assertTrue(isinstance(tw.execute(), ExceptionInfo))
         meta = TaskMeta.objects.get(task_id=tid)
         meta = TaskMeta.objects.get(task_id=tid)
         self.assertEquals(meta.status, "FAILURE")
         self.assertEquals(meta.status, "FAILURE")
@@ -230,7 +223,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_execute_using_pool(self):
     def test_execute_using_pool(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask", tid, mytask, [4], {"f": "x"})
+        tw = TaskWrapper(mytask.name, tid, [4], {"f": "x"})
         p = TaskPool(2)
         p = TaskPool(2)
         p.start()
         p.start()
         asyncres = tw.execute_using_pool(p)
         asyncres = tw.execute_using_pool(p)
@@ -239,7 +232,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_default_kwargs(self):
     def test_default_kwargs(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask", tid, mytask, [4], {"f": "x"})
+        tw = TaskWrapper(mytask.name, tid, [4], {"f": "x"})
         self.assertEquals(tw.extend_with_default_kwargs(10, "some_logfile"), {
         self.assertEquals(tw.extend_with_default_kwargs(10, "some_logfile"), {
             "f": "x",
             "f": "x",
             "logfile": "some_logfile",
             "logfile": "some_logfile",
@@ -250,7 +243,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
     def test_on_failure(self):
     def test_on_failure(self):
         tid = gen_unique_id()
         tid = gen_unique_id()
-        tw = TaskWrapper("cu.mytask", tid, mytask, [4], {"f": "x"})
+        tw = TaskWrapper(mytask.name, tid, [4], {"f": "x"})
         try:
         try:
             raise Exception("Inside unit tests")
             raise Exception("Inside unit tests")
         except Exception:
         except Exception:
@@ -265,7 +258,7 @@ class TestTaskWrapper(unittest.TestCase):
 
 
         tw.on_failure(exc_info)
         tw.on_failure(exc_info)
         logvalue = logfh.getvalue()
         logvalue = logfh.getvalue()
-        self.assertTrue("cu.mytask" in logvalue)
+        self.assertTrue(mytask.name in logvalue)
         self.assertTrue(tid in logvalue)
         self.assertTrue(tid in logvalue)
         self.assertTrue("ERROR" in logvalue)
         self.assertTrue("ERROR" in logvalue)
 
 

+ 5 - 1
celery/utils.py

@@ -124,6 +124,9 @@ def fun_takes_kwargs(fun, kwlist=[]):
     """With a function, and a list of keyword arguments, returns arguments
     """With a function, and a list of keyword arguments, returns arguments
     in the list which the function takes.
     in the list which the function takes.
 
 
+    If the object has an ``argspec`` attribute that is used instead
+    of using the :meth:`inspect.getargspec`` introspection.
+
     :param fun: The function to inspect arguments of.
     :param fun: The function to inspect arguments of.
     :param kwlist: The list of keyword arguments.
     :param kwlist: The list of keyword arguments.
 
 
@@ -139,7 +142,8 @@ def fun_takes_kwargs(fun, kwlist=[]):
         ["logfile", "loglevel", "task_id"]
         ["logfile", "loglevel", "task_id"]
 
 
     """
     """
-    args, _varargs, keywords, _defaults = getargspec(fun)
+    argspec = getattr(fun, "argspec", getargspec(fun))
+    args, _varargs, keywords, _defaults = argspec
     if keywords != None:
     if keywords != None:
         return kwlist
         return kwlist
     return filter(curry(operator.contains, args), kwlist)
     return filter(curry(operator.contains, args), kwlist)

+ 8 - 14
celery/worker/job.py

@@ -43,8 +43,6 @@ class TaskWrapper(object):
 
 
     :param task_id: see :attr:`task_id`.
     :param task_id: see :attr:`task_id`.
 
 
-    :param task_func: see :attr:`task_func`
-
     :param args: see :attr:`args`
     :param args: see :attr:`args`
 
 
     :param kwargs: see :attr:`kwargs`.
     :param kwargs: see :attr:`kwargs`.
@@ -57,10 +55,6 @@ class TaskWrapper(object):
 
 
         UUID of the task.
         UUID of the task.
 
 
-    .. attribute:: task_func
-
-        The tasks callable object.
-
     .. attribute:: args
     .. attribute:: args
 
 
         List of positional arguments to apply to the task.
         List of positional arguments to apply to the task.
@@ -88,11 +82,10 @@ class TaskWrapper(object):
     """
     """
     fail_email_body = TASK_FAIL_EMAIL_BODY
     fail_email_body = TASK_FAIL_EMAIL_BODY
 
 
-    def __init__(self, task_name, task_id, task_func, args, kwargs,
+    def __init__(self, task_name, task_id, args, kwargs,
             on_ack=noop, retries=0, **opts):
             on_ack=noop, retries=0, **opts):
         self.task_name = task_name
         self.task_name = task_name
         self.task_id = task_id
         self.task_id = task_id
-        self.task_func = task_func
         self.retries = retries
         self.retries = retries
         self.args = args
         self.args = args
         self.kwargs = kwargs
         self.kwargs = kwargs
@@ -104,6 +97,9 @@ class TaskWrapper(object):
             setattr(self, opt, opts.get(opt, getattr(self, opt, None)))
             setattr(self, opt, opts.get(opt, getattr(self, opt, None)))
         if not self.logger:
         if not self.logger:
             self.logger = get_default_logger()
             self.logger = get_default_logger()
+        if self.task_name not in tasks:
+            raise NotRegistered(self.task_name)
+        self.task = tasks[self.task_name]
 
 
     def __repr__(self):
     def __repr__(self):
         return '<%s: {name:"%s", id:"%s", args:"%s", kwargs:"%s"}>' % (
         return '<%s: {name:"%s", id:"%s", args:"%s", kwargs:"%s"}>' % (
@@ -132,10 +128,7 @@ class TaskWrapper(object):
         kwargs = dict((key.encode("utf-8"), value)
         kwargs = dict((key.encode("utf-8"), value)
                         for key, value in kwargs.items())
                         for key, value in kwargs.items())
 
 
-        if task_name not in tasks:
-            raise NotRegistered(task_name)
-        task_func = tasks[task_name]
-        return cls(task_name, task_id, task_func, args, kwargs,
+        return cls(task_name, task_id, args, kwargs,
                     retries=retries, on_ack=message.ack, logger=logger)
                     retries=retries, on_ack=message.ack, logger=logger)
 
 
     def extend_with_default_kwargs(self, loglevel, logfile):
     def extend_with_default_kwargs(self, loglevel, logfile):
@@ -153,8 +146,9 @@ class TaskWrapper(object):
                             "task_id": self.task_id,
                             "task_id": self.task_id,
                             "task_name": self.task_name,
                             "task_name": self.task_name,
                             "task_retries": self.retries}
                             "task_retries": self.retries}
-        fun = getattr(self.task_func, "run", self.task_func)
+        fun = self.task.run
         supported_keys = fun_takes_kwargs(fun, default_kwargs)
         supported_keys = fun_takes_kwargs(fun, default_kwargs)
+        print("TASK_NAME: %s SUP: %s" % (self.task_name, supported_keys))
         extend_with = dict((key, val) for key, val in default_kwargs.items()
         extend_with = dict((key, val) for key, val in default_kwargs.items()
                                 if key in supported_keys)
                                 if key in supported_keys)
         kwargs.update(extend_with)
         kwargs.update(extend_with)
@@ -163,7 +157,7 @@ class TaskWrapper(object):
     def _executeable(self, loglevel=None, logfile=None):
     def _executeable(self, loglevel=None, logfile=None):
         """Get the :class:`celery.execute.ExecuteWrapper` for this task."""
         """Get the :class:`celery.execute.ExecuteWrapper` for this task."""
         task_func_kwargs = self.extend_with_default_kwargs(loglevel, logfile)
         task_func_kwargs = self.extend_with_default_kwargs(loglevel, logfile)
-        return ExecuteWrapper(self.task_func, self.task_id, self.task_name,
+        return ExecuteWrapper(self.task_name, self.task_id,
                               self.args, task_func_kwargs)
                               self.args, task_func_kwargs)
 
 
     def _set_executed_bit(self):
     def _set_executed_bit(self):

+ 5 - 3
docs/configuration.rst

@@ -260,9 +260,10 @@ Task execution settings
 
 
 * CELERY_ALWAYS_EAGER
 * CELERY_ALWAYS_EAGER
     If this is ``True``, all tasks will be executed locally by blocking
     If this is ``True``, all tasks will be executed locally by blocking
-    until it is finished. ``apply_async`` and ``delay_task`` will return
+    until it is finished. ``apply_async`` and ``Task.delay`` will return
     a :class:`celery.result.EagerResult` which emulates the behaviour of
     a :class:`celery.result.EagerResult` which emulates the behaviour of
-    an :class:`celery.result.AsyncResult`.
+    :class:`celery.result.AsyncResult`, except the result has already
+    been evaluated.
 
 
     Tasks will never be sent to the queue, but executed locally
     Tasks will never be sent to the queue, but executed locally
     instead.
     instead.
@@ -272,7 +273,8 @@ Task execution settings
     stored task tombstones are deleted.
     stored task tombstones are deleted.
 
 
     **NOTE**: For the moment this only works for the database and MongoDB
     **NOTE**: For the moment this only works for the database and MongoDB
-    backends.
+    backends., except the result has already
+    been evaluated.
 
 
 * CELERY_TASK_SERIALIZER
 * CELERY_TASK_SERIALIZER
     A string identifying the default serialization
     A string identifying the default serialization