From: Ben Darnell Date: Sat, 7 Jul 2018 21:06:20 +0000 (-0400) Subject: web: Delete asynchronous decorator X-Git-Tag: v6.0.0b1~48^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=920ce30d249db60bf7844487eb3759f38d673cbe;p=thirdparty%2Ftornado.git web: Delete asynchronous decorator --- diff --git a/tornado/test/gen_test.py b/tornado/test/gen_test.py index 784aa9c72..5ea5e0b79 100644 --- a/tornado/test/gen_test.py +++ b/tornado/test/gen_test.py @@ -1,38 +1,24 @@ from __future__ import absolute_import, division, print_function +import asyncio +from concurrent import futures import gc -import contextlib import datetime -import functools import platform import sys import textwrap import time import weakref -import warnings from tornado.concurrent import Future -from tornado.escape import url_escape -from tornado.httpclient import AsyncHTTPClient from tornado.ioloop import IOLoop from tornado.log import app_log -from tornado import stack_context from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, ExpectLog, gen_test -from tornado.test.util import unittest, skipOnTravis, skipBefore33, skipBefore35, skipNotCPython, exec_test, ignore_deprecation # noqa: E501 -from tornado.web import Application, RequestHandler, asynchronous, HTTPError +from tornado.test.util import unittest, skipOnTravis, skipBefore33, skipBefore35, skipNotCPython, exec_test +from tornado.web import Application, RequestHandler, HTTPError from tornado import gen -try: - from concurrent import futures -except ImportError: - futures = None - -try: - import asyncio -except ImportError: - asyncio = None - class GenBasicTest(AsyncTestCase): @gen.coroutine diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index b9cacff9b..d3126ab3a 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -17,7 +17,7 @@ from tornado.test.util import unittest, skipBefore35, exec_test, ignore_deprecat from tornado.util import ObjectDict, unicode_type, PY3 from tornado.web import ( Application, RequestHandler, StaticFileHandler, RedirectHandler as WebRedirectHandler, - HTTPError, MissingArgumentError, ErrorHandler, authenticated, asynchronous, url, + HTTPError, MissingArgumentError, ErrorHandler, authenticated, url, _create_signature_v1, create_signed_value, decode_signed_value, get_signature_key_version, UIModule, Finish, stream_request_body, removeslash, addslash, GZipContentEncoding, ) @@ -1816,35 +1816,6 @@ class GetArgumentErrorTest(SimpleHandlerTestCase): 'log_message': 'Missing argument foo'}) -class MultipleExceptionTest(SimpleHandlerTestCase): - class Handler(RequestHandler): - exc_count = 0 - - with ignore_deprecation(): - @asynchronous - def get(self): - IOLoop.current().add_callback(lambda: 1 / 0) - IOLoop.current().add_callback(lambda: 1 / 0) - - def log_exception(self, typ, value, tb): - MultipleExceptionTest.Handler.exc_count += 1 - - def test_multi_exception(self): - with ignore_deprecation(): - # This test verifies that multiple exceptions raised into the same - # ExceptionStackContext do not generate extraneous log entries - # due to "Cannot send error response after headers written". - # log_exception is called, but it does not proceed to send_error. - response = self.fetch('/') - self.assertEqual(response.code, 500) - response = self.fetch('/') - self.assertEqual(response.code, 500) - # Each of our two requests generated two exceptions, we should have - # seen at least three of them by now (the fourth may still be - # in the queue). - self.assertGreater(MultipleExceptionTest.Handler.exc_count, 2) - - @wsgi_safe class SetLazyPropertiesTest(SimpleHandlerTestCase): class Handler(RequestHandler): diff --git a/tornado/web.py b/tornado/web.py index a0488f6b9..b483796a3 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1693,90 +1693,6 @@ class RequestHandler(object): self.clear_header(h) -def asynchronous(method): - """Wrap request handler methods with this if they are asynchronous. - - This decorator is for callback-style asynchronous methods; for - coroutines, use the ``@gen.coroutine`` decorator without - ``@asynchronous``. (It is legal for legacy reasons to use the two - decorators together provided ``@asynchronous`` is first, but - ``@asynchronous`` will be ignored in this case) - - This decorator should only be applied to the :ref:`HTTP verb - methods `; its behavior is undefined for any other method. - This decorator does not *make* a method asynchronous; it tells - the framework that the method *is* asynchronous. For this decorator - to be useful the method must (at least sometimes) do something - asynchronous. - - If this decorator is given, the response is not finished when the - method returns. It is up to the request handler to call - `self.finish() ` to finish the HTTP - request. Without this decorator, the request is automatically - finished when the ``get()`` or ``post()`` method returns. Example: - - .. testcode:: - - class MyRequestHandler(RequestHandler): - @asynchronous - def get(self): - http = httpclient.AsyncHTTPClient() - http.fetch("http://friendfeed.com/", self._on_download) - - def _on_download(self, response): - self.write("Downloaded!") - self.finish() - - .. testoutput:: - :hide: - - .. versionchanged:: 3.1 - The ability to use ``@gen.coroutine`` without ``@asynchronous``. - - .. versionchanged:: 4.3 Returning anything but ``None`` or a - yieldable object from a method decorated with ``@asynchronous`` - is an error. Such return values were previously ignored silently. - - .. deprecated:: 5.1 - - This decorator is deprecated and will be removed in Tornado 6.0. - Use coroutines instead. - """ - warnings.warn("@asynchronous is deprecated, use coroutines instead", - DeprecationWarning) - # Delay the IOLoop import because it's not available on app engine. - from tornado.ioloop import IOLoop - - @functools.wraps(method) - def wrapper(self, *args, **kwargs): - self._auto_finish = False - with stack_context.ExceptionStackContext( - self._stack_context_handle_exception, delay_warning=True): - result = method(self, *args, **kwargs) - if result is not None: - result = gen.convert_yielded(result) - - # If @asynchronous is used with @gen.coroutine, (but - # not @gen.engine), we can automatically finish the - # request when the future resolves. Additionally, - # the Future will swallow any exceptions so we need - # to throw them back out to the stack context to finish - # the request. - def future_complete(f): - f.result() - if not self._finished: - self.finish() - IOLoop.current().add_future(result, future_complete) - # Once we have done this, hide the Future from our - # caller (i.e. RequestHandler._when_complete), which - # would otherwise set up its own callback and - # exception handler (resulting in exceptions being - # logged twice). - return None - return result - return wrapper - - def stream_request_body(cls): """Apply to `RequestHandler` subclasses to enable streaming body support.