From: Ben Darnell Date: Mon, 22 May 2017 05:03:46 +0000 (-0400) Subject: concurrent: Remove use of self.io_loop from run_on_executor X-Git-Tag: v5.0.0~80^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2052%2Fhead;p=thirdparty%2Ftornado.git concurrent: Remove use of self.io_loop from run_on_executor --- diff --git a/tornado/concurrent.py b/tornado/concurrent.py index 667e6b178..b1bcc56e2 100644 --- a/tornado/concurrent.py +++ b/tornado/concurrent.py @@ -378,9 +378,9 @@ def run_on_executor(*args, **kwargs): The decorated method may be called with a ``callback`` keyword argument and returns a future. - The `.IOLoop` and executor to be used are determined by the ``io_loop`` - and ``executor`` attributes of ``self``. To use different attributes, - pass keyword arguments to the decorator:: + The executor to be used is determined by the ``executor`` + attributes of ``self``. To use a different attribute name, pass a + keyword argument to the decorator:: @run_on_executor(executor='_thread_pool') def foo(self): @@ -388,17 +388,20 @@ def run_on_executor(*args, **kwargs): .. versionchanged:: 4.2 Added keyword arguments to use alternative attributes. + + .. versionchanged:: 5.0 + Always uses the current IOLoop instead of ``self.io_loop``. """ def run_on_executor_decorator(fn): executor = kwargs.get("executor", "executor") - io_loop = kwargs.get("io_loop", "io_loop") @functools.wraps(fn) def wrapper(self, *args, **kwargs): callback = kwargs.pop("callback", None) future = getattr(self, executor).submit(fn, self, *args, **kwargs) if callback: - getattr(self, io_loop).add_future( + from tornado.ioloop import IOLoop + IOLoop.current().add_future( future, lambda future: callback(future.result())) return future return wrapper diff --git a/tornado/test/concurrent_test.py b/tornado/test/concurrent_test.py index e20281fc3..d1e266ff0 100644 --- a/tornado/test/concurrent_test.py +++ b/tornado/test/concurrent_test.py @@ -362,74 +362,41 @@ class RunOnExecutorTest(AsyncTestCase): @gen_test def test_no_calling(self): class Object(object): - def __init__(self, io_loop): - self.io_loop = io_loop + def __init__(self): self.executor = futures.thread.ThreadPoolExecutor(1) @run_on_executor def f(self): return 42 - o = Object(io_loop=self.io_loop) + o = Object() answer = yield o.f() self.assertEqual(answer, 42) @gen_test def test_call_with_no_args(self): class Object(object): - def __init__(self, io_loop): - self.io_loop = io_loop + def __init__(self): self.executor = futures.thread.ThreadPoolExecutor(1) @run_on_executor() def f(self): return 42 - o = Object(io_loop=self.io_loop) - answer = yield o.f() - self.assertEqual(answer, 42) - - @gen_test - def test_call_with_io_loop(self): - class Object(object): - def __init__(self, io_loop): - self._io_loop = io_loop - self.executor = futures.thread.ThreadPoolExecutor(1) - - @run_on_executor(io_loop='_io_loop') - def f(self): - return 42 - - o = Object(io_loop=self.io_loop) + o = Object() answer = yield o.f() self.assertEqual(answer, 42) @gen_test def test_call_with_executor(self): class Object(object): - def __init__(self, io_loop): - self.io_loop = io_loop + def __init__(self): self.__executor = futures.thread.ThreadPoolExecutor(1) @run_on_executor(executor='_Object__executor') def f(self): return 42 - o = Object(io_loop=self.io_loop) - answer = yield o.f() - self.assertEqual(answer, 42) - - @gen_test - def test_call_with_both(self): - class Object(object): - def __init__(self, io_loop): - self._io_loop = io_loop - self.__executor = futures.thread.ThreadPoolExecutor(1) - - @run_on_executor(io_loop='_io_loop', executor='_Object__executor') - def f(self): - return 42 - - o = Object(io_loop=self.io_loop) + o = Object() answer = yield o.f() self.assertEqual(answer, 42)