``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):
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()
# 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():
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:
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))
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)
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']()
@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
@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
# 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)
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):
@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)
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.
@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):
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")
"""))
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
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'
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)
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,
@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):
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",
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",
@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)
# 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
# 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
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'):
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'):
@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
@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
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,
# 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
@asynchronous
def get(self):
- from tornado.ioloop import IOLoop
IOLoop.current().add_callback(lambda: 1 / 0)
IOLoop.current().add_callback(lambda: 1 / 0)
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()
@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
# 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))
@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))]
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))]