From: Ben Darnell Date: Mon, 18 Dec 2017 02:47:58 +0000 (-0500) Subject: docs: Start release notes for 5.0. X-Git-Tag: v5.0.0~32^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e758ad5aac22dbacc3f51f9d18ac39a11ae3517;p=thirdparty%2Ftornado.git docs: Start release notes for 5.0. Update versionadded/versionchanged tags. Misc other doc updates --- diff --git a/docs/concurrent.rst b/docs/concurrent.rst index 80d6f02e9..5904a60b8 100644 --- a/docs/concurrent.rst +++ b/docs/concurrent.rst @@ -1,5 +1,5 @@ -``tornado.concurrent`` --- Work with threads and futures -======================================================== +``tornado.concurrent`` --- Work with ``Future`` objects +======================================================= .. testsetup:: @@ -8,22 +8,28 @@ .. automodule:: tornado.concurrent :members: - :exclude-members: Future - .. autoclass:: Future + .. class:: Future - Consumer methods - ^^^^^^^^^^^^^^^^ + ``tornado.concurrent.Future`` is an alias for `asyncio.Future` + on Python 3. On Python 2, it provides an equivalent + implementation. - .. automethod:: Future.result - .. automethod:: Future.exception - .. automethod:: Future.add_done_callback - .. automethod:: Future.done - .. automethod:: Future.cancel - .. automethod:: Future.cancelled + In Tornado, the main way in which applications interact with + ``Future`` objects is by ``awaiting`` or ``yielding`` them in + coroutines, instead of calling methods on the ``Future`` objects + themselves. For more information on the available methods, see + the `asyncio.Future` docs. - Producer methods - ^^^^^^^^^^^^^^^^ + .. versionchanged:: 5.0 - .. automethod:: Future.set_result - .. automethod:: Future.set_exception + Tornado's implementation of ``Future`` has been replaced by + the version from `asyncio` when available. + + - ``Future`` objects can only be created while there is a + current `.IOLoop` + - The timing of callbacks scheduled with + ``Future.add_done_callback`` has changed. + - Cancellation is now partially supported (only on Python 3) + - The ``exc_info`` and ``set_exc_info`` methods are no longer + available on Python 3. diff --git a/docs/conf.py b/docs/conf.py index e64eb8667..8b7cdf626 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -79,7 +79,7 @@ latex_documents = [ ] intersphinx_mapping = { - 'python': ('https://docs.python.org/3.5/', None), + 'python': ('https://docs.python.org/3.6/', None), } on_rtd = os.environ.get('READTHEDOCS', None) == 'True' diff --git a/docs/guide/async.rst b/docs/guide/async.rst index 53e58e5d4..5082f3fba 100644 --- a/docs/guide/async.rst +++ b/docs/guide/async.rst @@ -110,7 +110,7 @@ And again with a `.Future` instead of a callback: The raw `.Future` version is more complex, but ``Futures`` are nonetheless recommended practice in Tornado because they have two major advantages. Error handling is more consistent since the -`.Future.result` method can simply raise an exception (as opposed to +``Future.result`` method can simply raise an exception (as opposed to the ad-hoc error handling common in callback-oriented interfaces), and ``Futures`` lend themselves well to use with coroutines. Coroutines will be discussed in depth in the next section of this guide. Here is diff --git a/docs/integration.rst b/docs/integration.rst index 8ecfae383..c2074195c 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -5,6 +5,6 @@ Integration with other services auth wsgi - asyncio caresresolver twisted + asyncio diff --git a/docs/ioloop.rst b/docs/ioloop.rst index f4897d644..fb41f2d65 100644 --- a/docs/ioloop.rst +++ b/docs/ioloop.rst @@ -41,6 +41,8 @@ .. automethod:: IOLoop.call_later .. automethod:: IOLoop.remove_timeout .. automethod:: IOLoop.spawn_callback + .. automethod:: IOLoop.run_in_executor + .. automethod:: IOLoop.set_default_executor .. automethod:: IOLoop.time .. autoclass:: PeriodicCallback :members: diff --git a/docs/releases.rst b/docs/releases.rst index 8fb67c8e1..ac45cdbd5 100644 --- a/docs/releases.rst +++ b/docs/releases.rst @@ -4,6 +4,7 @@ Release notes .. toctree:: :maxdepth: 2 + releases/v5.0.0 releases/v4.5.1 releases/v4.5.0 releases/v4.4.3 diff --git a/docs/releases/v5.0.0.rst b/docs/releases/v5.0.0.rst new file mode 100644 index 000000000..6456090d8 --- /dev/null +++ b/docs/releases/v5.0.0.rst @@ -0,0 +1,309 @@ +What's new in Tornado 5.0 +========================= + +In progress +----------- + +Highlights +~~~~~~~~~~ + +- The focus of this release is improving integration with `asyncio`. + On Python 3, the `.IOLoop` is always a wrapper around the `asyncio` + event loop, and `asyncio.Future` and `asyncio.Task` are used instead + of their Tornado counterparts. This means that libraries based on + `asyncio` can be mixed relatively seamlessly with those using + Tornado. While care has been taken to minimize the disruption from + this change, code changes may be required for compatibility with + Tornado 5.0, as detailed in the following section. +- Support for Python 2.7 and 3.4 are deprecated; Tornado 6.0 will + require Python 3.5+. TODO(bdarnell): decide whether to drop py2 in 5.0 + +Backwards-compatibility notes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Python 3.3 is no longer supported. +- Versions of Python 2.7 that predate the `ssl` module update are no + longer supported. (The `ssl` module was updated in version 2.7.9, + although in some distributions the updates are present in builds + with a lower version number. Tornado requires `ssl.SSLContext`, + `ssl.create_default_context`, and `ssl.match_hostname`) +- Versions of Python 3.5 prior to 3.5.2 are no longer supported due to + a change in the async iterator protocol in that version. +- The ``trollius`` project (`asyncio` backported to Python 2) is no + longer supported. +- `tornado.concurrent.Future` is now an alias for `asyncio.Future` + when running on Python 3. This results in a number of minor + behavioral changes: + + - `.Future` objects can only be created while there is a current + `.IOLoop` + - The timing of callbacks scheduled with + ``Future.add_done_callback`` has changed. + `tornado.concurrent.future_add_done_callback` can be used to + make the behavior more like older versions of Tornado (but not + identical). Some of these changes are also present in the Python + 2 version of `tornado.concurrent.Future` to minimize the + difference between Python 2 and 3. + - Cancellation is now partially supported, via + `asyncio.Future.cancel`. A canceled `.Future` can no longer have + its result set. Applications that handle `~asyncio.Future` + objects directly may want to use + `tornado.concurrent.future_set_result_unless_cancelled`. In + native coroutines, cancellation will cause an exception to be + raised in the coroutine. + - The ``exc_info`` and ``set_exc_info`` methods are no longer + present. Use `tornado.concurrent.future_set_exc_info` to replace + the latter, and raise the exception with + `~asyncio.Future.result` to replace the former. +- ``io_loop`` arguments to many Tornado functions have been removed. + Use `.IOLoop.current()` instead of passing `.IOLoop` objects + explicitly. +- On Python 3, `.IOLoop` is always a wrapper around the `asyncio` + event loop. ``IOLoop.configure`` is effectively removed on Python 3 + (for compatibility, it may be called to redundantly specify the + `asyncio`-backed `.IOLoop`) +- `.IOLoop.instance` is now a deprecated alias for `.IOLoop.current`. + Applications that need the cross-thread communication behavior + facilitated by `.IOLoop.instance` should use their own global variable + instead. + + +Other notes +~~~~~~~~~~~ + +- The ``certifi`` and ``backports.ssl-match-hostname`` packages are no + longer required on Python 2.7. +- Python 3.6 or higher is recommended, because it features more + efficient garbage collection of `asyncio.Future` objects. + +`tornado.autoreload` +~~~~~~~~~~~~~~~~~~~~ + +- On Python 3, uses ``__main__.__spec`` to more reliably reconstruct + the original command line and avoid modifying ``PYTHONPATH``. +- The ``io_loop`` argument to `tornado.autoreload.start` has been removed. + +`tornado.concurrent` +~~~~~~~~~~~~~~~~~~~~ + +- `tornado.concurrent.Future` is now an alias for `asyncio.Future` + when running on Python 3. See "Backwards-compatibility notes" for + more. +- Setting the result of a ``Future`` no longer blocks while callbacks + are being run. Instead, the callbacks are scheduled on the next + `.IOLoop` iteration. +- The deprecated alias ``tornado.concurrent.TracebackFuture`` has been + removed. +- `tornado.concurrent.chain_future` now works with all three kinds of + ``Futures`` (Tornado, `asyncio`, and `concurrent.futures`) +- The ``io_loop`` argument to `tornado.concurrent.run_on_executor` has + been removed. +- New functions `.future_set_result_unless_cancelled`, + `.future_set_exc_info`, and `.future_add_done_callback` help mask + the difference between `asyncio.Future` and Tornado's previous + ``Future`` implementation. + +`tornado.curl_httpclient` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Improved debug logging on Python 3. +- The ``time_info`` response attribute now includes ``appconnect`` in + addition to other measurements. +- Closing a `.CurlAsyncHTTPClient` now breaks circular references that + could delay garbage collection. +- The ``io_loop`` argument to the `.CurlAsyncHTTPClient` constructor + has been removed. + +`tornado.gen` +~~~~~~~~~~~~~ + +- ``tornado.gen.TimeoutError`` is now an alias for + `tornado.util.TimeoutError`. +- Leak detection for ``Futures`` created by this module now attributes + them to their proper caller instead of the coroutine machinery. +- Several circular references that could delay garbage collection have + been broken up. +- On Python 3, `asyncio.Task` is used instead of the Tornado coroutine + runner. This improves compatibility with some `asyncio` libraries + and adds support for cancellation. +- The ``io_loop`` arguments to ``YieldFuture`` and `.with_timeout` have + been removed. + +`tornado.httpclient` +~~~~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` argument to all `.AsyncHTTPClient` constructors has + been removed. + +`tornado.httpserver` +~~~~~~~~~~~~~~~~~~~~ + +- If a client sends a malformed request, the server now responds with + a 400 error instead of simply closing the connection. +- ``Content-Length`` and ``Transfer-Encoding`` headers are no longer + sent with 1xx or 204 responses (this was already true of 304 + responses). +- When closing a connection to a HTTP/1.1 client, the ``Connection: + close`` header is sent with the response. +- The ``io_loop`` argument to the `.HTTPServer` constructor has been + removed. +- If more than one ``X-Scheme`` or ``X-Forwarded-Proto`` header is + present, only the last is used. + +`tornado.httputil` +~~~~~~~~~~~~~~~~~~ + +- The string representation of `.HTTPServerRequest` objects (which are + sometimes used in log messages) no longer includes the request + headers. +- New function `.qs_to_qsl` converts the result of + `urllib.parse.parse_qs` to name-value pairs. + +`tornado.ioloop` +~~~~~~~~~~~~~~~~ + +- ``tornado.ioloop.TimeoutError`` is now an alias for + `tornado.util.TimeoutError`. +- `.IOLoop.instance` is now a deprecated alias for `.IOLoop.current`. +- `.IOLoop.initialized`, `.IOLoop.install`, and + `.IOLoop.clear_instance` are all deprecated. +- On Python 3, the `asyncio`-backed `.IOLoop` is always used and + alternative `.IOLoop` implementations cannot be configured. +- `~.IOLoop.run_sync` cancels its argument on a timeout. This + results in better stack traces (and avoids log messages about leaks) + in native coroutines. +- New methods `.IOLoop.run_in_executor` and + `.IOLoop.set_default_executor` make it easier to run functions in + other threads from native coroutines (since + `concurrent.futures.Future` does not support ``await``). +- ``PollIOLoop`` (the default on Python 2) attempts to detect misuse + of `.IOLoop` instances across `os.fork`. +- The ``io_loop`` argument to `.PeriodicCallback` has been removed. +- It is now possible to create a `.PeriodicCallback` in one thread + and start it in another without passing an explicit event loop. +- The `.IOLoop.set_blocking_signal_threshold` and + `.IOLoop.set_blocking_log_threshold` methods are deprecated because + they are not implemented for the `asyncio` event loop`. Use the + ``PYTHONASYNCIODEBUG=1`` environment variable instead. + +`tornado.iostream` +~~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` argument to the `.IOStream` constructor has been removed. +- `.BaseIOStream.write` is now much more efficient for very large amounts of data. +- Fixed some cases in which ``IOStream.error`` could be inaccurate. +- Writing a `memoryview` can no longer result in "BufferError: + Existing exports of data: object cannot be re-sized". + +`tornado.locks` +~~~~~~~~~~~~~~~ + +- As a side effect of the ``Future`` changes, waiters are always + notified asynchronously with respect to `.Condition.notify`. + +`tornado.netutil` +~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` arguments to `.add_accept_handler`, + `.ExecutorResolver`, and `.ThreadedResolver` have been removed. +- `.add_accept_handler` returns a callable which can be used to remove + all handlers that were added. + +`tornado.options` +~~~~~~~~~~~~~~~~~ + +- Duplicate option names are now detected properly whether they use + hyphens or underscores. + +`tornado.platform.asyncio` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `.AsyncIOLoop` and `.AsyncIOMainLoop` are now used automatically + when appropriate; referencing them explicitly is no longer + recommended. +- Starting an `.IOLoop` or making it current now also sets the + `asyncio` event loop for the current thread. +- `.to_tornado_future` and `.to_asyncio_future` are deprecated since + they are now no-ops. + +`tornado.platform.caresresolver` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` argument to `.CaresResolver` has been removed. + +`tornado.platform.twisted` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` arguments to `.TornadoReactor`, `.TwistedResolver`, + and `tornado.platform.twisted.install` have been removed. + +`tornado.process` +~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` argument to the `.Subprocess` constructor and + `.Subprocess.initialize` has been removed. + +`tornado.routing` +~~~~~~~~~~~~~~~~~ + +- A default 404 response is now generated if no delegate is found for + a request. + +`tornado.simple_httpclient` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` argument to `.SimpleAsyncHTTPClient` has been removed. +- TLS is now configured according to `ssl.create_default_context` by + default. + +`tornado.tcpclient` +~~~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` argument to the `.TCPClient` constructor has been + removed. +- `.TCPClient.connect` has a new ``timeout`` argument. + +`tornado.tcpserver` +~~~~~~~~~~~~~~~~~~~ + +- The ``io_loop`` argument to the `.TCPServer` constructor has been + removed. +- `.TCPServer` no longer logs ``EBADF`` errors during shutdown. + +`tornado.testing` +~~~~~~~~~~~~~~~~~ + +- The deprecated ``tornado.testing.get_unused_port`` and + ``tornado.testing.LogTrapTestCase`` have been removed. +- `.AsyncHTTPTestCase.fetch` now supports absolute URLs. + +`tornado.util` +~~~~~~~~~~~~~~ + +- `tornado.util.TimeoutError` replaces ``tornado.gen.TimeoutError`` + and ``tornado.ioloop.TimeoutError``. +- `.Configurable` now supports configuration at multiple levels of an + inheritance hierarchy. + +`tornado.web` +~~~~~~~~~~~~~ + +- `.RequestHandler.set_status` no longer requires that the given + status code appear in `http.client.responses`. +- It is no longer allowed to send a body with 1xx or 204 responses. +- Exception handling now breaks up reference cycles that could delay + garbage collection. +- `.RedirectHandler` now copies any query arguments from the request + to the redirect location. + +`tornado.websocket` +~~~~~~~~~~~~~~~~~~~ + +- The C accelerator now operates on multiple bytes at a time to + improve performance. +- Requests with invalid websocket headers now get a response with + status code 400 instead of a closed connection. +- `.WebSocketHandler.write_message` now raises `.StreamClosedError` if + called after the connection is closed. + TODO(bdarnell): fix this up with WebSocketClosedError +- The ``io_loop`` argument to `.websocket_connect` has been removed. diff --git a/tornado/concurrent.py b/tornado/concurrent.py index bb1fb9480..dd0d46593 100644 --- a/tornado/concurrent.py +++ b/tornado/concurrent.py @@ -403,6 +403,9 @@ def run_on_executor(*args, **kwargs): def foo(self): pass + This decorator should not be confused with the similarly-named + `.IOLoop.run_in_executor`. + .. versionchanged:: 4.2 Added keyword arguments to use alternative attributes. @@ -445,7 +448,7 @@ def return_future(f): From the caller's perspective, the callback argument is optional. If one is given, it will be invoked when the function is complete - with `Future.result()` as an argument. If the function fails, the + with ``Future.result()`` as an argument. If the function fails, the callback will not be run and an exception will be raised into the surrounding `.StackContext`. @@ -526,7 +529,11 @@ def chain_future(a, b): The result (success or failure) of ``a`` will be copied to ``b``, unless ``b`` has already been completed or cancelled by the time ``a`` finishes. - Accepts both Tornado/asyncio `Future` objects and `concurrent.futures.Future`. + .. versionchanged:: 5.0 + + Now accepts both Tornado/asyncio `Future` objects and + `concurrent.futures.Future`. + """ def copy(future): assert future is a @@ -581,8 +588,10 @@ def future_add_done_callback(future, callback): ``callback`` is invoked with one argument, the ``future``. If ``future`` is already done, ``callback`` is invoked immediately. - This may differ from the behavior of `.Future.add_done_callback`, + This may differ from the behavior of ``Future.add_done_callback``, which makes no such guarantee. + + .. versionadded:: 5.0 """ if future.done(): callback(future) diff --git a/tornado/gen.py b/tornado/gen.py index 5deffb4b2..ed76bc317 100644 --- a/tornado/gen.py +++ b/tornado/gen.py @@ -37,7 +37,7 @@ could be written with ``gen`` as: :hide: Most asynchronous functions in Tornado return a `.Future`; -yielding this object returns its `~.Future.result`. +yielding this object returns its ``Future.result``. You can also yield a list or dict of ``Futures``, which will be started at the same time and run in parallel; a list or dict of results will diff --git a/tornado/httputil.py b/tornado/httputil.py index f2b289b32..05fc7d6db 100755 --- a/tornado/httputil.py +++ b/tornado/httputil.py @@ -942,7 +942,9 @@ def split_host_and_port(netloc): def qs_to_qsl(qs): - """Generator rewinding a result of ``parse_qs`` back to name-value pairs. + """Generator converting a result of ``parse_qs`` back to name-value pairs. + + .. versionadded:: 5.0 """ for k, vs in qs.items(): for v in vs: diff --git a/tornado/ioloop.py b/tornado/ioloop.py index 0a1056fb0..6311dda5f 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -16,14 +16,19 @@ """An I/O event loop for non-blocking sockets. -Typical applications will use a single `IOLoop` object, in the -`IOLoop.instance` singleton. The `IOLoop.start` method should usually -be called at the end of the ``main()`` function. Atypical applications may -use more than one `IOLoop`, such as one `IOLoop` per thread, or per `unittest` -case. - -In addition to I/O events, the `IOLoop` can also schedule time-based events. -`IOLoop.add_timeout` is a non-blocking alternative to `time.sleep`. +On Python 3, `.IOLoop` is a wrapper around the `asyncio` event loop. + +Typical applications will use a single `IOLoop` object, accessed via +`IOLoop.current` class method. The `IOLoop.start` method (or +equivalently, `asyncio.AbstractEventLoop.run_forever`) should usually +be called at the end of the ``main()`` function. Atypical applications +may use more than one `IOLoop`, such as one `IOLoop` per thread, or +per `unittest` case. + +In addition to I/O events, the `IOLoop` can also schedule time-based +events. `IOLoop.add_timeout` is a non-blocking alternative to +`time.sleep`. + """ from __future__ import absolute_import, division, print_function @@ -77,11 +82,12 @@ _POLL_TIMEOUT = 3600.0 class IOLoop(Configurable): """A level-triggered I/O loop. - We use ``epoll`` (Linux) or ``kqueue`` (BSD and Mac OS X) if they - are available, or else we fall back on select(). If you are - implementing a system that needs to handle thousands of - simultaneous connections, you should use a system that supports - either ``epoll`` or ``kqueue``. + On Python 3, `IOLoop` is a wrapper around the `asyncio` event + loop. On Python 2, it uses ``epoll`` (Linux) or ``kqueue`` (BSD + and Mac OS X) if they are available, or else we fall back on + select(). If you are implementing a system that needs to handle + thousands of simultaneous connections, you should use a system + that supports either ``epoll`` or ``kqueue``. Example usage for a simple TCP server: @@ -148,6 +154,13 @@ class IOLoop(Configurable): .. versionchanged:: 4.2 Added the ``make_current`` keyword argument to the `IOLoop` constructor. + + .. versionchanged:: 5.0 + + Uses the `asyncio` event loop by default. The + ``IOLoop.configure`` method cannot be used on Python 3 except + to redundantly specify the `asyncio` event loop. + """ # Constants from the epoll module _EPOLLIN = 0x001 @@ -291,6 +304,9 @@ class IOLoop(Configurable): .. versionchanged:: 4.1 An `IOLoop` created while there is no current `IOLoop` will automatically become current. + + .. versionchanged:: 5.0 + This method also sets the current `asyncio` event loop. """ IOLoop._current.instance = self @@ -299,6 +315,9 @@ class IOLoop(Configurable): """Clears the `IOLoop` for the current thread. Intended primarily for use by test frameworks in between tests. + + .. versionchanged:: 5.0 + This method also clears the current `asyncio` event loop. """ old = IOLoop._current.instance if old is not None: @@ -407,6 +426,11 @@ class IOLoop(Configurable): documentation for the `signal` module for more information. If ``action`` is None, the process will be killed if it is blocked for too long. + + .. deprecated:: 5.0 + + Not implemented on the `asyncio` event loop. Use the environment + variable ``PYTHONASYNCIODEBUG=1`` instead. """ raise NotImplementedError() @@ -416,6 +440,11 @@ class IOLoop(Configurable): Equivalent to ``set_blocking_signal_threshold(seconds, self.log_stack)`` + + .. deprecated:: 5.0 + + Not implemented on the `asyncio` event loop. Use the environment + variable ``PYTHONASYNCIODEBUG=1`` instead. """ self.set_blocking_signal_threshold(seconds, self.log_stack) @@ -502,6 +531,9 @@ class IOLoop(Configurable): .. versionchanged:: 4.3 Returning a non-``None``, non-yieldable value is now an error. + + .. versionchanged:: 5.0 + If a timeout occurs, the ``func`` coroutine will be cancelled. """ future_cell = [None] @@ -681,8 +713,9 @@ class IOLoop(Configurable): """Runs a function in a ``concurrent.futures.Executor``. If ``executor`` is ``None``, the IO loop's default executor will be used. - Use `functools.partial` to pass keyword arguments to `func`. + Use `functools.partial` to pass keyword arguments to ``func``. + .. versionadded:: 5.0 """ if ThreadPoolExecutor is None: raise RuntimeError( @@ -701,7 +734,10 @@ class IOLoop(Configurable): return t_future def set_default_executor(self, executor): - """Sets the default executor to use with :meth:`run_in_executor`.""" + """Sets the default executor to use with :meth:`run_in_executor`. + + .. versionadded:: 5.0 + """ self._executor = executor def _run_callback(self, callback): diff --git a/tornado/platform/asyncio.py b/tornado/platform/asyncio.py index 2a90099e4..0e81277c5 100644 --- a/tornado/platform/asyncio.py +++ b/tornado/platform/asyncio.py @@ -6,10 +6,11 @@ This module integrates Tornado with the ``asyncio`` module introduced in Python 3.4. This makes it possible to combine the two libraries on the same event loop. -Most applications should use `AsyncIOMainLoop` to run Tornado on the -default ``asyncio`` event loop. Applications that need to run event -loops on multiple threads may use `AsyncIOLoop` to create multiple -loops. +.. deprecated:: 5.0 + + While the code in this module is still used, it is now enabled + automatically when `asyncio` is available, so applications should + no longer need to refer to this module directly. .. note:: @@ -143,15 +144,12 @@ class BaseAsyncIOLoop(IOLoop): class AsyncIOMainLoop(BaseAsyncIOLoop): """``AsyncIOMainLoop`` creates an `.IOLoop` that corresponds to the current ``asyncio`` event loop (i.e. the one returned by - ``asyncio.get_event_loop()``). Recommended usage:: + ``asyncio.get_event_loop()``). - from tornado.platform.asyncio import AsyncIOMainLoop - import asyncio - AsyncIOMainLoop().install() - asyncio.get_event_loop().run_forever() + .. deprecated:: 5.0 - See also :meth:`tornado.ioloop.IOLoop.install` for general notes on - installing alternative IOLoops. + Now used automatically when appropriate; it is no longer necessary + to refer to this class directly. """ def initialize(self, **kwargs): super(AsyncIOMainLoop, self).initialize(asyncio.get_event_loop(), @@ -162,14 +160,20 @@ class AsyncIOLoop(BaseAsyncIOLoop): """``AsyncIOLoop`` is an `.IOLoop` that runs on an ``asyncio`` event loop. This class follows the usual Tornado semantics for creating new ``IOLoops``; these loops are not necessarily related to the - ``asyncio`` default event loop. Recommended usage:: - - from tornado.ioloop import IOLoop - IOLoop.configure('tornado.platform.asyncio.AsyncIOLoop') - IOLoop.current().start() + ``asyncio`` default event loop. Each ``AsyncIOLoop`` creates a new ``asyncio.EventLoop``; this object can be accessed with the ``asyncio_loop`` attribute. + + .. versionchanged:: 5.0 + + When an ``AsyncIOLoop`` becomes the current `.IOLoop`, it also sets + the current `asyncio` event loop. + + .. deprecated:: 5.0 + + Now used automatically when appropriate; it is no longer necessary + to refer to this class directly. """ def initialize(self, **kwargs): loop = asyncio.new_event_loop() diff --git a/tornado/tcpclient.py b/tornado/tcpclient.py index 2aa6ccf04..91a3705d0 100644 --- a/tornado/tcpclient.py +++ b/tornado/tcpclient.py @@ -210,6 +210,9 @@ class TCPClient(object): .. versionchanged:: 4.5 Added the ``source_ip`` and ``source_port`` arguments. + + .. versionchanged:: 5.0 + Added the ``timeout`` argument. """ if timeout is not None: if isinstance(timeout, numbers.Real): diff --git a/tornado/testing.py b/tornado/testing.py index 95f0ec538..b7bf3c6df 100644 --- a/tornado/testing.py +++ b/tornado/testing.py @@ -388,6 +388,9 @@ class AsyncHTTPTestCase(AsyncTestCase): If the path begins with http:// or https://, it will be treated as a full URL and will be fetched as-is. + + .. versionchanged:: 5.0 + Added support for absolute URLs. """ if path.lower().startswith(('http://', 'https://')): self.http_client.fetch(path, self.stop, **kwargs) diff --git a/tornado/util.py b/tornado/util.py index aee718aee..a42ebebe3 100644 --- a/tornado/util.py +++ b/tornado/util.py @@ -282,6 +282,12 @@ class Configurable(object): Configurable subclasses must define the class methods `configurable_base` and `configurable_default`, and use the instance method `initialize` instead of ``__init__``. + + .. versionchanged:: 5.0 + + It is now possible for configuration to be specified at + multiple levels of a class hierarchy. + """ __impl_class = None # type: type __impl_kwargs = None # type: Dict[str, Any] diff --git a/tornado/web.py b/tornado/web.py index c7510a140..5cca00629 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -309,11 +309,15 @@ class RequestHandler(object): def set_status(self, status_code, reason=None): """Sets the status code for our response. - :arg int status_code: Response status code. If ``reason`` is ``None``, - it must be present in `httplib.responses `. + :arg int status_code: Response status code. :arg string reason: Human-readable reason phrase describing the status code. If ``None``, it will be filled in from - `httplib.responses `. + `http.client.responses` or "Unknown". + + .. versionchanged:: 5.0 + + No longer validates that the response code is in + `http.client.responses`. """ self._status_code = status_code if reason is not None: @@ -2276,6 +2280,10 @@ class RedirectHandler(RequestHandler): .. versionchanged:: 4.5 Added support for substitutions into the destination URL. + + .. versionchanged:: 5.0 + If any query arguments are present, they will be copied to the + destination URL. """ def initialize(self, url, permanent=True): self._url = url