]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
gen: Deprecate Task
authorBen Darnell <ben@bendarnell.com>
Mon, 19 Mar 2018 02:36:38 +0000 (22:36 -0400)
committerBen Darnell <ben@bendarnell.com>
Mon, 19 Mar 2018 03:33:04 +0000 (23:33 -0400)
tornado/gen.py
tornado/platform/twisted.py
tornado/test/asyncio_test.py
tornado/test/concurrent_test.py
tornado/test/gen_test.py
tornado/test/httpserver_test.py
tornado/test/ioloop_test.py
tornado/test/simple_httpclient_test.py
tornado/test/testing_test.py
tornado/test/web_test.py

index 989174264bc2f9cc65cdbe4352e609ddf144ba32..579939a19f19c7b396636cfd8bac69b12a2761ae 100644 (file)
@@ -646,7 +646,12 @@ def Task(func, *args, **kwargs):
        ``gen.Task`` is now a function that returns a `.Future`, instead of
        a subclass of `YieldPoint`.  It still behaves the same way when
        yielded.
+
+    .. deprecated:: 5.1
+       This function is deprecated and will be removed in 6.0.
     """
+    warnings.warn("gen.Task is deprecated, use Futures instead",
+                  DeprecationWarning)
     future = _create_future()
 
     def handle_exception(typ, value, tb):
index d1ab2c795765fda56113c3cfd70d7cd7b2d6d3d8..4ae98be976c94ff944b75ceccbd7a0557c911d00 100644 (file)
@@ -554,7 +554,9 @@ class TwistedResolver(Resolver):
             resolved_family = socket.AF_INET6
         else:
             deferred = self.resolver.getHostByName(utf8(host))
-            resolved = yield gen.Task(deferred.addBoth)
+            fut = Future()
+            deferred.addBoth(fut.set_result)
+            resolved = yield fut
             if isinstance(resolved, failure.Failure):
                 try:
                     resolved.raiseException()
index 41fda20d43fa94fca72065f470aca8cc7ebbdf09..37f2f6e1b4d3e18efa3299c34f5a6dfd8b5af3f7 100644 (file)
@@ -77,7 +77,7 @@ class AsyncIOLoopTest(AsyncTestCase):
         # as demonstrated by other tests in the package.
         @gen.coroutine
         def tornado_coroutine():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             raise gen.Return(42)
         native_coroutine_without_adapter = exec_test(globals(), locals(), """
         async def native_coroutine_without_adapter():
index 5199033a3475c8fa053c378cc8b97b8fffce5bc0..ea147910380ac941bd193f3785695d6ac3ee9982 100644 (file)
@@ -201,7 +201,7 @@ class ReturnFutureTest(AsyncTestCase):
     def test_future_traceback(self):
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             try:
                 1 / 0
             except ZeroDivisionError:
@@ -335,10 +335,10 @@ class GeneratorCapClient(BaseCapClient):
         logging.debug('capitalize')
         stream = IOStream(socket.socket())
         logging.debug('connecting')
-        yield gen.Task(stream.connect, ('127.0.0.1', self.port))
+        yield stream.connect(('127.0.0.1', self.port))
         stream.write(utf8(request_data + '\n'))
         logging.debug('reading')
-        data = yield gen.Task(stream.read_until, b'\n')
+        data = yield stream.read_until(b'\n')
         logging.debug('returning')
         stream.close()
         raise gen.Return(self.process_response(data))
index c831f3bd07d7a7a4f479ff4b70a7a95fab029f18..373fae79a63994c8acadd3513686f6ad5c2f1601 100644 (file)
@@ -714,7 +714,7 @@ class GenCoroutineTest(AsyncTestCase):
     def test_async_gen_return(self):
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             raise gen.Return(42)
         result = yield f()
         self.assertEqual(result, 42)
@@ -735,7 +735,7 @@ class GenCoroutineTest(AsyncTestCase):
         namespace = exec_test(globals(), locals(), """
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             return 42
         """)
         result = yield namespace['f']()
@@ -762,15 +762,20 @@ class GenCoroutineTest(AsyncTestCase):
     @skipBefore35
     @gen_test
     def test_async_await(self):
+        @gen.coroutine
+        def f1():
+            yield gen.moment
+            raise gen.Return(42)
+
         # This test verifies that an async function can await a
         # yield-based gen.coroutine, and that a gen.coroutine
         # (the test method itself) can yield an async function.
         namespace = exec_test(globals(), locals(), """
-        async def f():
-            await gen.Task(self.io_loop.add_callback)
-            return 42
+        async def f2():
+            result = await f1()
+            return result
         """)
-        result = yield namespace['f']()
+        result = yield namespace['f2']()
         self.assertEqual(result, 42)
         self.finished = True
 
@@ -792,18 +797,22 @@ class GenCoroutineTest(AsyncTestCase):
     @skipBefore35
     @gen_test
     def test_async_await_mixed_multi_native_future(self):
+        @gen.coroutine
+        def f1():
+            yield gen.moment
+
         namespace = exec_test(globals(), locals(), """
-        async def f1():
-            await gen.Task(self.io_loop.add_callback)
+        async def f2():
+            await f1()
             return 42
         """)
 
         @gen.coroutine
-        def f2():
-            yield gen.Task(self.io_loop.add_callback)
+        def f3():
+            yield gen.moment
             raise gen.Return(43)
 
-        results = yield [namespace['f1'](), f2()]
+        results = yield [namespace['f2'](), f3()]
         self.assertEqual(results, [42, 43])
         self.finished = True
 
@@ -854,7 +863,7 @@ class GenCoroutineTest(AsyncTestCase):
         # Without a return value we don't need python 3.3.
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             return
         result = yield f()
         self.assertEqual(result, None)
@@ -877,7 +886,7 @@ class GenCoroutineTest(AsyncTestCase):
     def test_async_raise(self):
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             1 / 0
         future = f()
         with self.assertRaises(ZeroDivisionError):
@@ -1145,7 +1154,8 @@ class GenTaskHandler(RequestHandler):
     @gen.coroutine
     def get(self):
         client = AsyncHTTPClient()
-        response = yield gen.Task(client.fetch, self.get_argument('url'))
+        with ignore_deprecation():
+            response = yield gen.Task(client.fetch, self.get_argument('url'))
         response.rethrow()
         self.finish(b"got response: " + response.body)
 
@@ -1175,14 +1185,14 @@ class GenYieldExceptionHandler(RequestHandler):
     def get(self):
         io_loop = self.request.connection.stream.io_loop
         # Test the interaction of the two stack_contexts.
-
-        def fail_task(callback):
-            io_loop.add_callback(lambda: 1 / 0)
-        try:
-            yield gen.Task(fail_task)
-            raise Exception("did not get expected exception")
-        except ZeroDivisionError:
-            self.finish('ok')
+        with ignore_deprecation():
+            def fail_task(callback):
+                io_loop.add_callback(lambda: 1 / 0)
+            try:
+                yield gen.Task(fail_task)
+                raise Exception("did not get expected exception")
+            except ZeroDivisionError:
+                self.finish('ok')
 
 
 # "Undecorated" here refers to the absence of @asynchronous.
@@ -1190,22 +1200,22 @@ class UndecoratedCoroutinesHandler(RequestHandler):
     @gen.coroutine
     def prepare(self):
         self.chunks = []
-        yield gen.Task(IOLoop.current().add_callback)
+        yield gen.moment
         self.chunks.append('1')
 
     @gen.coroutine
     def get(self):
         self.chunks.append('2')
-        yield gen.Task(IOLoop.current().add_callback)
+        yield gen.moment
         self.chunks.append('3')
-        yield gen.Task(IOLoop.current().add_callback)
+        yield gen.moment
         self.write(''.join(self.chunks))
 
 
 class AsyncPrepareErrorHandler(RequestHandler):
     @gen.coroutine
     def prepare(self):
-        yield gen.Task(IOLoop.current().add_callback)
+        yield gen.moment
         raise HTTPError(403)
 
     def get(self):
@@ -1216,7 +1226,8 @@ class NativeCoroutineHandler(RequestHandler):
     if sys.version_info > (3, 5):
         exec(textwrap.dedent("""
         async def get(self):
-            await gen.Task(IOLoop.current().add_callback)
+            import asyncio
+            await asyncio.sleep(0)
             self.write("ok")
         """))
 
index 30696a04a5d3722190c7e6d2362cb7aeca4d09f6..bfac9ab528115b88c437c7056156ce5c3eae283a 100644 (file)
@@ -1,8 +1,8 @@
 from __future__ import absolute_import, division, print_function
 
 from tornado import netutil
+from tornado.concurrent import Future
 from tornado.escape import json_decode, json_encode, utf8, _unicode, recursive_unicode, native_str
-from tornado import gen
 from tornado.http1connection import HTTP1Connection
 from tornado.httpserver import HTTPServer
 from tornado.httputil import HTTPHeaders, HTTPMessageDelegate, HTTPServerConnectionDelegate, ResponseStartLine  # noqa: E501
@@ -1120,7 +1120,9 @@ class BodyLimitsTest(AsyncHTTPTestCase):
             stream.write(b'PUT /streaming?expected_size=10240 HTTP/1.1\r\n'
                          b'Content-Length: 10240\r\n\r\n')
             stream.write(b'a' * 10240)
-            start_line, headers, response = yield gen.Task(read_stream_body, stream)
+            fut = Future()
+            read_stream_body(stream, callback=fut.set_result)
+            start_line, headers, response = yield fut
             self.assertEqual(response, b'10240')
             # Without the ?expected_size parameter, we get the old default value
             stream.write(b'PUT /streaming HTTP/1.1\r\n'
index 1aa3f1e54b168b9540db36092e5a9e57535fa96b..09f71c5d69a473d0a9e990496b328a331545e3a3 100644 (file)
@@ -693,14 +693,14 @@ class TestIOLoopRunSync(unittest.TestCase):
     def test_async_result(self):
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             raise gen.Return(42)
         self.assertEqual(self.io_loop.run_sync(f), 42)
 
     def test_async_exception(self):
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
             1 / 0
         with self.assertRaises(ZeroDivisionError):
             self.io_loop.run_sync(f)
@@ -713,16 +713,20 @@ class TestIOLoopRunSync(unittest.TestCase):
     def test_timeout(self):
         @gen.coroutine
         def f():
-            yield gen.Task(self.io_loop.add_timeout, self.io_loop.time() + 1)
+            yield gen.sleep(1)
         self.assertRaises(TimeoutError, self.io_loop.run_sync, f, timeout=0.01)
 
     @skipBefore35
     def test_native_coroutine(self):
+        @gen.coroutine
+        def f1():
+            yield gen.moment
+
         namespace = exec_test(globals(), locals(), """
-        async def f():
-            await gen.Task(self.io_loop.add_callback)
+        async def f2():
+            await f1()
         """)
-        self.io_loop.run_sync(namespace['f'])
+        self.io_loop.run_sync(namespace['f2'])
 
 
 @unittest.skipIf(asyncio is not None,
index f32319e599eb2fcda1727e92d6665001d5228209..973353e0377d905bda9c4c8dc457ac985cbaa8b3 100644 (file)
@@ -378,7 +378,7 @@ class SimpleHTTPClientTestMixin(object):
     @gen.coroutine
     def async_body_producer(self, write):
         yield write(b'1234')
-        yield gen.Task(IOLoop.current().add_callback)
+        yield gen.moment
         yield write(b'5678')
 
     def test_sync_body_producer_chunked(self):
@@ -412,7 +412,8 @@ class SimpleHTTPClientTestMixin(object):
         namespace = exec_test(globals(), locals(), """
         async def body_producer(write):
             await write(b'1234')
-            await gen.Task(IOLoop.current().add_callback)
+            import asyncio
+            await asyncio.sleep(0)
             await write(b'5678')
         """)
         response = self.fetch("/echo_post", method="POST",
@@ -425,7 +426,8 @@ class SimpleHTTPClientTestMixin(object):
         namespace = exec_test(globals(), locals(), """
         async def body_producer(write):
             await write(b'1234')
-            await gen.Task(IOLoop.current().add_callback)
+            import asyncio
+            await asyncio.sleep(0)
             await write(b'5678')
         """)
         response = self.fetch("/echo_post", method="POST",
index 796530ff85cb7611af995b8645914098aa418250..9905c9272f742ce139c218855aa9291c392cdfe3 100644 (file)
@@ -208,14 +208,14 @@ class GenTest(AsyncTestCase):
 
     @gen_test
     def test_async(self):
-        yield gen.Task(self.io_loop.add_callback)
+        yield gen.moment
         self.finished = True
 
     def test_timeout(self):
         # Set a short timeout and exceed it.
         @gen_test(timeout=0.1)
         def test(self):
-            yield gen.Task(self.io_loop.add_timeout, self.io_loop.time() + 1)
+            yield gen.sleep(1)
 
         # This can't use assertRaises because we need to inspect the
         # exc_info triple (and not just the exception object)
@@ -226,7 +226,7 @@ class GenTest(AsyncTestCase):
             # The stack trace should blame the add_timeout line, not just
             # unrelated IOLoop/testing internals.
             self.assertIn(
-                "gen.Task(self.io_loop.add_timeout, self.io_loop.time() + 1)",
+                "gen.sleep(1)",
                 traceback.format_exc())
 
         self.finished = True
@@ -235,8 +235,7 @@ class GenTest(AsyncTestCase):
         # A test that does not exceed its timeout should succeed.
         @gen_test(timeout=1)
         def test(self):
-            time = self.io_loop.time
-            yield gen.Task(self.io_loop.add_timeout, time() + 0.1)
+            yield gen.sleep(0.1)
 
         test(self)
         self.finished = True
@@ -244,8 +243,7 @@ class GenTest(AsyncTestCase):
     def test_timeout_environment_variable(self):
         @gen_test(timeout=0.5)
         def test_long_timeout(self):
-            time = self.io_loop.time
-            yield gen.Task(self.io_loop.add_timeout, time() + 0.25)
+            yield gen.sleep(0.25)
 
         # Uses provided timeout of 0.5 seconds, doesn't time out.
         with set_environ('ASYNC_TEST_TIMEOUT', '0.1'):
@@ -256,8 +254,7 @@ class GenTest(AsyncTestCase):
     def test_no_timeout_environment_variable(self):
         @gen_test(timeout=0.01)
         def test_short_timeout(self):
-            time = self.io_loop.time
-            yield gen.Task(self.io_loop.add_timeout, time() + 1)
+            yield gen.sleep(1)
 
         # Uses environment-variable timeout of 0.1, times out.
         with set_environ('ASYNC_TEST_TIMEOUT', '0.1'):
@@ -270,7 +267,7 @@ class GenTest(AsyncTestCase):
         @gen_test
         def test_with_args(self, *args):
             self.assertEqual(args, ('test',))
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
 
         test_with_args(self, 'test')
         self.finished = True
@@ -279,7 +276,7 @@ class GenTest(AsyncTestCase):
         @gen_test
         def test_with_kwargs(self, **kwargs):
             self.assertDictEqual(kwargs, {'test': 'test'})
-            yield gen.Task(self.io_loop.add_callback)
+            yield gen.moment
 
         test_with_kwargs(self, test='test')
         self.finished = True
index 6aa06266efe68b6d36bcb490b4364091f8e51b54..6673a4f26f99e9965b612547d7a105d28bee6b26 100644 (file)
@@ -11,7 +11,7 @@ from tornado.log import app_log, gen_log
 from tornado.simple_httpclient import SimpleAsyncHTTPClient
 from tornado.template import DictLoader
 from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, ExpectLog, gen_test
-from tornado.test.util import unittest, skipBefore35, exec_test
+from tornado.test.util import unittest, skipBefore35, exec_test, ignore_deprecation
 from tornado.util import ObjectDict, unicode_type, timedelta_to_seconds, PY3
 from tornado.web import (
     Application, RequestHandler, StaticFileHandler, RedirectHandler as WebRedirectHandler,
@@ -587,8 +587,9 @@ class EmptyFlushCallbackHandler(RequestHandler):
         # Ensure that the flush callback is run whether or not there
         # was any output.  The gen.Task and direct yield forms are
         # equivalent.
-        yield gen.Task(self.flush)  # "empty" flush, but writes headers
-        yield gen.Task(self.flush)  # empty flush
+        with ignore_deprecation():
+            yield gen.Task(self.flush)  # "empty" flush, but writes headers
+            yield gen.Task(self.flush)  # empty flush
         self.write("o")
         yield self.flush()  # flushes the "o"
         yield self.flush()  # empty flush
@@ -1807,7 +1808,6 @@ class MultipleExceptionTest(SimpleHandlerTestCase):
 
         @asynchronous
         def get(self):
-            from tornado.ioloop import IOLoop
             IOLoop.current().add_callback(lambda: 1 / 0)
             IOLoop.current().add_callback(lambda: 1 / 0)
 
@@ -2159,7 +2159,7 @@ class StreamingRequestBodyTest(WebTestCase):
         self.assertEquals(data, b"qwer")
         stream.write(b"0\r\n\r\n")
         yield self.finished
-        data = yield gen.Task(stream.read_until_close)
+        data = yield stream.read_until_close()
         # This would ideally use an HTTP1Connection to read the response.
         self.assertTrue(data.endswith(b"{}"))
         stream.close()
@@ -2167,14 +2167,14 @@ class StreamingRequestBodyTest(WebTestCase):
     @gen_test
     def test_early_return(self):
         stream = self.connect(b"/early_return", connection_close=False)
-        data = yield gen.Task(stream.read_until_close)
+        data = yield stream.read_until_close()
         self.assertTrue(data.startswith(b"HTTP/1.1 401"))
 
     @gen_test
     def test_early_return_with_data(self):
         stream = self.connect(b"/early_return", connection_close=False)
         stream.write(b"4\r\nasdf\r\n")
-        data = yield gen.Task(stream.read_until_close)
+        data = yield stream.read_until_close()
         self.assertTrue(data.startswith(b"HTTP/1.1 401"))
 
     @gen_test
@@ -2213,12 +2213,12 @@ class BaseFlowControlHandler(RequestHandler):
         # Note that asynchronous prepare() does not block data_received,
         # so we don't use in_method here.
         self.methods.append('prepare')
-        yield gen.Task(IOLoop.current().add_callback)
+        yield gen.moment
 
     @gen.coroutine
     def post(self):
         with self.in_method('post'):
-            yield gen.Task(IOLoop.current().add_callback)
+            yield gen.moment
         self.write(dict(methods=self.methods))
 
 
@@ -2279,7 +2279,7 @@ class DecoratedStreamingRequestFlowControlTest(
             @gen.coroutine
             def data_received(self, data):
                 with self.in_method('data_received'):
-                    yield gen.Task(IOLoop.current().add_callback)
+                    yield gen.moment
         return [('/', DecoratedFlowControlHandler, dict(test=self))]
 
 
@@ -2292,7 +2292,8 @@ class NativeStreamingRequestFlowControlTest(
             data_received = exec_test(globals(), locals(), """
             async def data_received(self, data):
                 with self.in_method('data_received'):
-                    await gen.Task(IOLoop.current().add_callback)
+                    import asyncio
+                    await asyncio.sleep(0)
             """)["data_received"]
         return [('/', NativeFlowControlHandler, dict(test=self))]