What's new in Tornado 6.4.0
In Progress
-----------
General Changes
~~~~~~~~~~~~~~~
- Python 3.12 is now supported. Older versions of Tornado will work on Python 3.12 but may log
deprecation warnings.
Deprecation Notices
~~~~~~~~~~~~~~~~~~~
- `.IOLoop.add_callback_from_signal` is suspected to have been broken since Tornado 5.0 and will be
removed in version 7.0. Use `asyncio.loop.add_signal_handler` instead.
- The ``client_secret`` argument to `.OAuth2Mixin.authorize_redirect` is deprecated and will be
removed in Tornado 7.0. This argument has never been used and other similar methods in this module
don't have it.
- `.TwitterMixin` is deprecated and will be removed in the future.
``tornado.auth``
~~~~~~~~~~~~~~~~
- The ``client_secret`` argument to `.OAuth2Mixin.authorize_redirect` is deprecated and will be
removed in Tornado 7.0. This argument has never been used and other similar methods in this module
don't have it.
- `.TwitterMixin` is deprecated and will be removed in the future.
``tornado.autoreload``
~~~~~~~~~~~~~~~~~~~~~~
- Autoreload can now be used when the program is run as a directory rather than a file or module.
- New CLI flag ``--until-success`` re-runs the program on any failure but stops after the first
successful run.
``tornado.concurrent``
~~~~~~~~~~~~~~~~~~~~~~
- Fixed reference cycles that could lead to increased memory usage.
``tornado.escape``
~~~~~~~~~~~~~~~~~~
- Several methods in this module now simply pass through to their equivalents in the standard
library.
``tornado.gen``
~~~~~~~~~~~~~~~
- This module now holds a strong reference to all running `asyncio.Task` objects it creates. This
prevents premature garbage collection which could cause warnings like "Task was destroyed but it
is pending!".
``tornado.ioloop``
~~~~~~~~~~~~~~~~~~
- `.IOLoop.add_callback_from_signal` is suspected to have been broken since Tornado 5.0 and will be
removed in version 7.0. Use `asyncio.loop.add_signal_handler` instead.
- The type annotation for `.IOLoop.run_in_executor` has been updated to match the updated signature
of `asyncio.loop.run_in_executor`.
- Fixed reference cycles that could lead to increased memory usage.
``tornado.locale``
~~~~~~~~~~~~~~~~~~
- `.format_timestamp` now supports "aware" datetime objects.
``tornado.platform.asyncio``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The shutdown protocol for `.AddThreadSelectorEventLoop` now requires the use of `asyncio.run` or
`asyncio.loop.shutdown_asyncgens` to avoid leaking the thread.
- Introduced `.SelectorThread` class containing the core functionality of
`.AddThreadSelectorEventLoop`.
- The ``close()`` method of `.AddThreadSelectorEventLoop` is now idempotent.
``tornado.web``
~~~~~~~~~~~~~~~
- `.StaticFileHandler.get_modified_time` now supports "aware" datetime objects and the default
implementation now returns aware objects.
``tornado.websocket``
~~~~~~~~~~~~~~~~~~~~~
- Unclosed client connections now reliably log a warning. Previously the warning was dependent on
garbage collection and whether the ``ping_interval`` option was used.
- The ``subprotocols`` argument to `.WebSocketClientConnection` now defaults to None instead of an
empty list (which was mutable and reused)
What's new in Tornado 6.4.1
Jun 6, 2024
-----------
Security Improvements
~~~~~~~~~~~~~~~~~~~~~
- Parsing of the ``Transfer-Encoding`` header is now stricter. Unexpected transfer-encoding values
were previously ignored and treated as the HTTP/1.0 default of read-until-close. This can lead to
framing issues with certain proxies. We now treat any unexpected value as an error.
- Handling of whitespace in headers now matches the RFC more closely. Only space and tab characters
are treated as whitespace and stripped from the beginning and end of header values. Other unicode
whitespace characters are now left alone. This could also lead to framing issues with certain
proxies.
- ``tornado.curl_httpclient`` now prohibits carriage return and linefeed headers in HTTP headers
(matching the behavior of ``simple_httpclient``). These characters could be used for header
injection or request smuggling if untrusted data were used in headers.
General Changes
~~~~~~~~~~~~~~~
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- `.SSLIOStream` now understands changes to error codes from OpenSSL 3.2. The main result of this
change is to reduce the noise in the logs for certain errors.
``tornado.simple_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``simple_httpclient`` now prohibits carriage return characters in HTTP headers. It had previously
prohibited only linefeed characters.
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.AsyncTestCase` subclasses can now be instantiated without being associated with a test
method. This improves compatibility with test discovery in Pytest 8.2.
What's new in Tornado 6.4.0
Nov 28, 2023
------------
General Changes
~~~~~~~~~~~~~~~
- Python 3.12 is now supported. Older versions of Tornado will work on Python 3.12 but may log
deprecation warnings.
Deprecation Notices
~~~~~~~~~~~~~~~~~~~
- `.IOLoop.add_callback_from_signal` is suspected to have been broken since Tornado 5.0 and will be
removed in version 7.0. Use `asyncio.loop.add_signal_handler` instead.
- The ``client_secret`` argument to `.OAuth2Mixin.authorize_redirect` is deprecated and will be
removed in Tornado 7.0. This argument has never been used and other similar methods in this module
don't have it.
- `.TwitterMixin` is deprecated and will be removed in the future.
``tornado.auth``
~~~~~~~~~~~~~~~~
- The ``client_secret`` argument to `.OAuth2Mixin.authorize_redirect` is deprecated and will be
removed in Tornado 7.0. This argument has never been used and other similar methods in this module
don't have it.
- `.TwitterMixin` is deprecated and will be removed in the future.
``tornado.autoreload``
~~~~~~~~~~~~~~~~~~~~~~
- Autoreload can now be used when the program is run as a directory rather than a file or module.
- New CLI flag ``--until-success`` re-runs the program on any failure but stops after the first
successful run.
``tornado.concurrent``
~~~~~~~~~~~~~~~~~~~~~~
- Fixed reference cycles that could lead to increased memory usage.
``tornado.escape``
~~~~~~~~~~~~~~~~~~
- Several methods in this module now simply pass through to their equivalents in the standard
library.
``tornado.gen``
~~~~~~~~~~~~~~~
- This module now holds a strong reference to all running `asyncio.Task` objects it creates. This
prevents premature garbage collection which could cause warnings like "Task was destroyed but it
is pending!".
``tornado.ioloop``
~~~~~~~~~~~~~~~~~~
- `.IOLoop.add_callback_from_signal` is suspected to have been broken since Tornado 5.0 and will be
removed in version 7.0. Use `asyncio.loop.add_signal_handler` instead.
- The type annotation for `.IOLoop.run_in_executor` has been updated to match the updated signature
of `asyncio.loop.run_in_executor`.
- Fixed reference cycles that could lead to increased memory usage.
``tornado.locale``
~~~~~~~~~~~~~~~~~~
- `.format_timestamp` now supports "aware" datetime objects.
``tornado.platform.asyncio``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The shutdown protocol for `.AddThreadSelectorEventLoop` now requires the use of `asyncio.run` or
`asyncio.loop.shutdown_asyncgens` to avoid leaking the thread.
- Introduced `.SelectorThread` class containing the core functionality of
`.AddThreadSelectorEventLoop`.
- The ``close()`` method of `.AddThreadSelectorEventLoop` is now idempotent.
``tornado.web``
~~~~~~~~~~~~~~~
- `.StaticFileHandler.get_modified_time` now supports "aware" datetime objects and the default
implementation now returns aware objects.
``tornado.websocket``
~~~~~~~~~~~~~~~~~~~~~
- Unclosed client connections now reliably log a warning. Previously the warning was dependent on
garbage collection and whether the ``ping_interval`` option was used.
- The ``subprotocols`` argument to `.WebSocketClientConnection` now defaults to None instead of an
empty list (which was mutable and reused)
What's new in Tornado 6.2.0
Jun XX, 2022
------------
Deprecation notice
~~~~~~~~~~~~~~~~~~
- Python 3.10 has begun the process of significant changes to the APIs for
managing the event loop. Calls to methods such as `asyncio.get_event_loop` may
now raise `DeprecationWarning` if no event loop is running. This has
significant impact on the patterns for initializing applications, and in
particular invalidates patterns that have long been the norm in Tornado's
documentation and actual usage. In the future (with some as-yet-unspecified
future version of Python), the old APIs will be removed. The new recommended
pattern is to start the event loop with `asyncio.run`. More detailed migration
guides will be coming in the future.
- The `.IOLoop` constructor is deprecated. Use `.IOLoop.current` when the loop
is already running instead.
- `.AsyncTestCase` (and `.AsyncHTTPTestCase`) are deprecated. Use
`unittest.IsolatedAsyncioTestCase` instead.
- Multi-process `.TCPServer.bind`/`.TCPServer.start` is deprecated. See
`.TCPServer` docs for supported alternatives.
- `.AnyThreadEventLoopPolicy` is deprecated. This class controls the creation of
the "current" event loop so it will be removed when that concept is no longer
supported.
- `.IOLoop.make_current` and `.IOLoop.clear_current` are deprecated. In the
future the concept of a "current" event loop as distinct from one that is
currently running will be removed.
- ``TwistedResolver`` and ``CaresResolver`` are deprecated and will be
removed in Tornado 7.0.
General changes
~~~~~~~~~~~~~~~
- The minimum supported Python version is now 3.7.
- SSL certificate verfication and hostname checks are now enabled by default in
more places (primarily in client-side usage of `.SSLIOStream`).
- Various improvements to type hints throughout the package.
- CI has moved from Travis and Appveyor to Github Actions.
`tornado.gen`
~~~~~~~~~~~~~
- Fixed a bug in which ``WaitIterator.current_index`` could be incorrect.
- ``tornado.gen.TimeoutError``` is now an alias for `asyncio.TimeoutError`.
`tornado.http1connection`
~~~~~~~~~~~~~~~~~~~~~~~~~
- ``max_body_size`` may now be set to zero to disallow a non-empty body.
- ``Content-Encoding: gzip`` is now recognized case-insensitively.
`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~
- ``curl_httpclient`` now supports non-ASCII (ISO-8859-1) header values, same as
``simple_httpclient``.
`tornado.ioloop`
~~~~~~~~~~~~~~~~
- `.PeriodicCallback` now understands coroutines and will not start multiple
copies if a previous invocation runs too long.
- `.PeriodicCallback` now accepts `datetime.timedelta` objects in addition to
numbers of milliseconds.
- Avoid logging "Event loop is closed" during shutdown-related race conditions.
- Tornado no longer calls `logging.basicConfig` when starting an IOLoop; this
has been unnecessary since Python 3.2 added a logger of last resort.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- `.SSLIOStream` now supports reading more than 2GB at a time.
- ``IOStream.write`` now supports typed `memoryview` objects.
`tornado.locale`
~~~~~~~~~~~~~~~~
- `.load_gettext_translations` no longer logs errors when language directories
exist but do not contain the expected file.
`tornado.netutil`
~~~~~~~~~~~~~~~~~
- `.is_valid_ip` no longer raises exceptions when the input is too long.
- The default resolver now uses the same methods (and thread pool) as `asyncio`.
`tornado.tcpserver`
~~~~~~~~~~~~~~~~~~~
- `.TCPServer.listen` now supports more arguments to pass through to
`.netutil.bind_sockets`.
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.bind_unused_port` now takes an optional ``address`` argument.
- Wrapped test methods now include the ``__wrapped__`` attribute.
`tornado.web`
~~~~~~~~~~~~~
- When using a custom `.StaticFileHandler` subclass, the ``reset()`` method is
now called on this subclass instead of the base class.
- Improved handling of the ``Accept-Language`` header.
- `.Application.listen` now supports more arguments to pass through to
`.netutil.bind_sockets`.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
- `.WebSocketClientConnection.write_message` now accepts `dict` arguments for
consistency with `.WebSocketHandler.write_message`.
- `.WebSocketClientConnection.write_message` now raises an exception as
documented if the connection is already closed.
What's new in Tornado 6.3.0
Apr 17, 2023
------------
Highlights
~~~~~~~~~~
- The new `.Application` setting ``xsrf_cookie_name`` can now be used to
take advantage of the ``__Host`` cookie prefix for improved security.
To use it, add ``{"xsrf_cookie_name": "__Host-xsrf", "xsrf_cookie_kwargs":
{"secure": True}}`` to your `.Application` settings. Note that this feature
currently only works when HTTPS is used.
- `.WSGIContainer` now supports running the application in a ``ThreadPoolExecutor`` so
the event loop is no longer blocked.
- `.AsyncTestCase` and `.AsyncHTTPTestCase`, which were deprecated in Tornado 6.2,
are no longer deprecated.
- WebSockets are now much faster at receiving large messages split into many
fragments.
General changes
~~~~~~~~~~~~~~~
- Python 3.7 is no longer supported; the minimum supported Python version is 3.8.
Python 3.12 is now supported.
- To avoid spurious deprecation warnings, users of Python 3.10 should upgrade
to at least version 3.10.9, and users of Python 3.11 should upgrade to at least
version 3.11.1.
- Tornado submodules are now imported automatically on demand. This means it is
now possible to use a single ``import tornado`` statement and refer to objects
in submodules such as `tornado.web.RequestHandler`.
Deprecation notices
~~~~~~~~~~~~~~~~~~~
- In Tornado 7.0, `tornado.testing.ExpectLog` will match ``WARNING``
and above regardless of the current logging configuration, unless the
``level`` argument is used.
- `.RequestHandler.get_secure_cookie` is now a deprecated alias for
`.RequestHandler.get_signed_cookie`. `.RequestHandler.set_secure_cookie`
is now a deprecated alias for `.RequestHandler.set_signed_cookie`.
- `.RequestHandler.clear_all_cookies` is deprecated. No direct replacement
is provided; `.RequestHandler.clear_cookie` should be used on individual
cookies.
- Calling the `.IOLoop` constructor without a ``make_current`` argument, which was
deprecated in Tornado 6.2, is no longer deprecated.
- `.AsyncTestCase` and `.AsyncHTTPTestCase`, which were deprecated in Tornado 6.2,
are no longer deprecated.
- `.AsyncTestCase.get_new_ioloop` is deprecated.
``tornado.auth``
~~~~~~~~~~~~~~~~
- New method `.GoogleOAuth2Mixin.get_google_oauth_settings` can now be overridden
to get credentials from a source other than the `.Application` settings.
``tornado.gen``
~~~~~~~~~~~~~~~
- `contextvars` now work properly when a ``@gen.coroutine`` calls a native coroutine.
``tornado.options``
~~~~~~~~~~~~~~~~~~~
- `~.OptionParser.parse_config_file` now recognizes single comma-separated strings (in addition to
lists of strings) for options with ``multiple=True``.
``tornado.web``
~~~~~~~~~~~~~~~
- New `.Application` setting ``xsrf_cookie_name`` can be used to change the
name of the XSRF cookie. This is most useful to take advantage of the
``__Host-`` cookie prefix.
- `.RequestHandler.get_secure_cookie` and `.RequestHandler.set_secure_cookie`
(and related methods and attributes) have been renamed to
`~.RequestHandler.get_signed_cookie` and `~.RequestHandler.set_signed_cookie`.
This makes it more explicit what kind of security is provided, and avoids
confusion with the ``Secure`` cookie attribute and ``__Secure-`` cookie prefix.
The old names remain supported as deprecated aliases.
- `.RequestHandler.clear_cookie` now accepts all keyword arguments accepted by
`~.RequestHandler.set_cookie`. In some cases clearing a cookie requires certain
arguments to be passed the same way in which it was set.
- `.RequestHandler.clear_all_cookies` now accepts additional keyword arguments
for the same reason as ``clear_cookie``. However, since the requirements
for additional arguments mean that it cannot reliably clear all cookies,
this method is now deprecated.
``tornado.websocket``
~~~~~~~~~~~~~~~~~~~~~
- It is now much faster (no longer quadratic) to receive large messages that
have been split into many fragments.
- `.websocket_connect` now accepts a ``resolver`` parameter.
``tornado.wsgi``
~~~~~~~~~~~~~~~~
- `.WSGIContainer` now accepts an ``executor`` parameter which can be used
to run the WSGI application on a thread pool.
What's new in Tornado 6.3.1
Apr 21, 2023
------------
``tornado.web``
~~~~~~~~~~~~~~~
- `.RequestHandler.set_cookie` once again accepts capitalized keyword arguments
for backwards compatibility. This is deprecated and in Tornado 7.0 only lowercase
arguments will be accepted.
What's new in Tornado 6.1.0
Oct X, 2020
-----------
General changes
~~~~~~~~~~~~~~~
- Windows support has been improved. Tornado is now compatible with the proactor
event loop (which became the default in Python 3.8) by automatically falling
back to running a selector in a second thread. This means that it is no longer
necessary to explicitly configure a selector event loop, although doing so may
improve performance. This does not change the fact that Tornado is significantly
less scalable on Windows than on other platforms.
- Binary wheels are now provided for Windows, MacOS, and Linux (amd64 and arm64).
`tornado.http1connection`
~~~~~~~~~~~~~~~~~~~~~~~~~
- ``HEAD`` requests to handlers that used chunked encoding no longer produce malformed output.
- Certain kinds of malformed ``gzip`` data no longer cause an infinite loop.
`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~
- Setting ``decompress_response=False`` now works correctly with
``curl_httpclient``.
- Mixing requests with and without proxies works correctly in ``curl_httpclient``
(assuming the version of pycurl is recent enough).
- A default ``User-Agent`` of ``Tornado/$VERSION`` is now used if the
``user_agent`` parameter is not specified.
- After a 303 redirect, ``tornado.simple_httpclient`` always uses ``GET``.
Previously this would use ``GET`` if the original request was a ``POST`` and
would otherwise reuse the original request method. For ``curl_httpclient``, the
behavior depends on the version of ``libcurl`` (with the most recent versions
using ``GET`` after 303 regardless of the original method).
- Setting ``request_timeout`` and/or ``connect_timeout`` to zero is now supported
to disable the timeout.
`tornado.httputil`
~~~~~~~~~~~~~~~~~~
- Header parsing is now faster.
- `.parse_body_arguments` now accepts incompletely-escaped non-ASCII inputs.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- `ssl.CertificateError` during the SSL handshake is now handled correctly.
- Reads that are resolved while the stream is closing are now handled correctly.
`tornado.log`
~~~~~~~~~~~~~
- When colored logging is enabled, ``logging.CRITICAL`` messages are now
recognized and colored magenta.
`tornado.netutil`
~~~~~~~~~~~~~~~~~
- ``EADDRNOTAVAIL`` is now ignored when binding to ``localhost`` with IPv6. This
error is common in docker.
`tornado.platform.asyncio`
~~~~~~~~~~~~~~~~~~~~~~~~~~
- `.AnyThreadEventLoopPolicy` now also configures a selector event loop for
these threads (the proactor event loop only works on the main thread)
``tornado.platform.auto``
~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``set_close_exec`` function has been removed.
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.ExpectLog` now has a ``level`` argument to ensure that the given log level
is enabled.
`tornado.web`
~~~~~~~~~~~~~
- ``RedirectHandler.get`` now accepts keyword arguments.
- When sending 304 responses, more headers (including ``Allow``) are now preserved.
- ``reverse_url`` correctly handles escaped characters in the regex route.
- Default ``Etag`` headers are now generated with SHA-512 instead of MD5.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
- The ``ping_interval`` timer is now stopped when the connection is closed.
- `.websocket_connect` now raises an error when it encounters a redirect instead of hanging.
What's new in Tornado 6.2.0
Jul 3, 2022
-----------
Deprecation notice
~~~~~~~~~~~~~~~~~~
- Python 3.10 has begun the process of significant changes to the APIs for
managing the event loop. Calls to methods such as `asyncio.get_event_loop` may
now raise `DeprecationWarning` if no event loop is running. This has
significant impact on the patterns for initializing applications, and in
particular invalidates patterns that have long been the norm in Tornado's
documentation and actual usage. In the future (with some as-yet-unspecified
future version of Python), the old APIs will be removed. The new recommended
pattern is to start the event loop with `asyncio.run`. More detailed migration
guides will be coming in the future.
- The `.IOLoop` constructor is deprecated unless the ``make_current=False``
argument is used. Use `.IOLoop.current` when the loop is already running
instead.
- `.AsyncTestCase` (and `.AsyncHTTPTestCase`) are deprecated. Use
`unittest.IsolatedAsyncioTestCase` instead.
- Multi-process `.TCPServer.bind`/`.TCPServer.start` is deprecated. See
`.TCPServer` docs for supported alternatives.
- `.AnyThreadEventLoopPolicy` is deprecated. This class controls the creation of
the "current" event loop so it will be removed when that concept is no longer
supported.
- `.IOLoop.make_current` and `.IOLoop.clear_current` are deprecated. In the
future the concept of a "current" event loop as distinct from one that is
currently running will be removed.
- ``TwistedResolver`` and ``CaresResolver`` are deprecated and will be
removed in Tornado 7.0.
General changes
~~~~~~~~~~~~~~~
- The minimum supported Python version is now 3.7.
- Wheels are now published with the Python stable ABI (``abi3``) for
compatibility across versions of Python.
- SSL certificate verfication and hostname checks are now enabled by default in
more places (primarily in client-side usage of `.SSLIOStream`).
- Various improvements to type hints throughout the package.
- CI has moved from Travis and Appveyor to Github Actions.
`tornado.gen`
~~~~~~~~~~~~~
- Fixed a bug in which ``WaitIterator.current_index`` could be incorrect.
- ``tornado.gen.TimeoutError``` is now an alias for `asyncio.TimeoutError`.
`tornado.http1connection`
~~~~~~~~~~~~~~~~~~~~~~~~~
- ``max_body_size`` may now be set to zero to disallow a non-empty body.
- ``Content-Encoding: gzip`` is now recognized case-insensitively.
`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~
- ``curl_httpclient`` now supports non-ASCII (ISO-8859-1) header values, same as
``simple_httpclient``.
`tornado.ioloop`
~~~~~~~~~~~~~~~~
- `.PeriodicCallback` now understands coroutines and will not start multiple
copies if a previous invocation runs too long.
- `.PeriodicCallback` now accepts `datetime.timedelta` objects in addition to
numbers of milliseconds.
- Avoid logging "Event loop is closed" during shutdown-related race conditions.
- Tornado no longer calls `logging.basicConfig` when starting an IOLoop; this
has been unnecessary since Python 3.2 added a logger of last resort.
- The `.IOLoop` constructor now accepts an ``asyncio_loop`` keyword argument to
initialize with a specfied asyncio event loop.
- It is now possible to construct an `.IOLoop` on one thread (with
``make_current=False``) and start it on a different thread.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- `.SSLIOStream` now supports reading more than 2GB at a time.
- ``IOStream.write`` now supports typed `memoryview` objects.
`tornado.locale`
~~~~~~~~~~~~~~~~
- `.load_gettext_translations` no longer logs errors when language directories
exist but do not contain the expected file.
`tornado.netutil`
~~~~~~~~~~~~~~~~~
- `.is_valid_ip` no longer raises exceptions when the input is too long.
- The default resolver now uses the same methods (and thread pool) as `asyncio`.
`tornado.tcpserver`
~~~~~~~~~~~~~~~~~~~
- `.TCPServer.listen` now supports more arguments to pass through to
`.netutil.bind_sockets`.
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.bind_unused_port` now takes an optional ``address`` argument.
- Wrapped test methods now include the ``__wrapped__`` attribute.
`tornado.web`
~~~~~~~~~~~~~
- When using a custom `.StaticFileHandler` subclass, the ``reset()`` method is
now called on this subclass instead of the base class.
- Improved handling of the ``Accept-Language`` header.
- `.Application.listen` now supports more arguments to pass through to
`.netutil.bind_sockets`.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
- `.WebSocketClientConnection.write_message` now accepts `dict` arguments for
consistency with `.WebSocketHandler.write_message`.
- `.WebSocketClientConnection.write_message` now raises an exception as
documented if the connection is already closed.
What's new in Tornado 6.1.0
Oct 30, 2020
------------
Deprecation notice
~~~~~~~~~~~~~~~~~~
- This is the last release of Tornado to support Python 3.5. Future versions
will require Python 3.6 or newer.
General changes
~~~~~~~~~~~~~~~
- Windows support has been improved. Tornado is now compatible with the proactor
event loop (which became the default in Python 3.8) by automatically falling
back to running a selector in a second thread. This means that it is no longer
necessary to explicitly configure a selector event loop, although doing so may
improve performance. This does not change the fact that Tornado is significantly
less scalable on Windows than on other platforms.
- Binary wheels are now provided for Windows, MacOS, and Linux (amd64 and arm64).
`tornado.gen`
~~~~~~~~~~~~~
- `.coroutine` now has better support for the Python 3.7+ ``contextvars`` module.
In particular, the ``ContextVar.reset`` method is now supported.
`tornado.http1connection`
~~~~~~~~~~~~~~~~~~~~~~~~~
- ``HEAD`` requests to handlers that used chunked encoding no longer produce malformed output.
- Certain kinds of malformed ``gzip`` data no longer cause an infinite loop.
`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~
- Setting ``decompress_response=False`` now works correctly with
``curl_httpclient``.
- Mixing requests with and without proxies works correctly in ``curl_httpclient``
(assuming the version of pycurl is recent enough).
- A default ``User-Agent`` of ``Tornado/$VERSION`` is now used if the
``user_agent`` parameter is not specified.
- After a 303 redirect, ``tornado.simple_httpclient`` always uses ``GET``.
Previously this would use ``GET`` if the original request was a ``POST`` and
would otherwise reuse the original request method. For ``curl_httpclient``, the
behavior depends on the version of ``libcurl`` (with the most recent versions
using ``GET`` after 303 regardless of the original method).
- Setting ``request_timeout`` and/or ``connect_timeout`` to zero is now supported
to disable the timeout.
`tornado.httputil`
~~~~~~~~~~~~~~~~~~
- Header parsing is now faster.
- `.parse_body_arguments` now accepts incompletely-escaped non-ASCII inputs.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- `ssl.CertificateError` during the SSL handshake is now handled correctly.
- Reads that are resolved while the stream is closing are now handled correctly.
`tornado.log`
~~~~~~~~~~~~~
- When colored logging is enabled, ``logging.CRITICAL`` messages are now
recognized and colored magenta.
`tornado.netutil`
~~~~~~~~~~~~~~~~~
- ``EADDRNOTAVAIL`` is now ignored when binding to ``localhost`` with IPv6. This
error is common in docker.
`tornado.platform.asyncio`
~~~~~~~~~~~~~~~~~~~~~~~~~~
- `.AnyThreadEventLoopPolicy` now also configures a selector event loop for
these threads (the proactor event loop only works on the main thread)
``tornado.platform.auto``
~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``set_close_exec`` function has been removed.
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.ExpectLog` now has a ``level`` argument to ensure that the given log level
is enabled.
`tornado.web`
~~~~~~~~~~~~~
- ``RedirectHandler.get`` now accepts keyword arguments.
- When sending 304 responses, more headers (including ``Allow``) are now preserved.
- ``reverse_url`` correctly handles escaped characters in the regex route.
- Default ``Etag`` headers are now generated with SHA-512 instead of MD5.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
- The ``ping_interval`` timer is now stopped when the connection is closed.
- `.websocket_connect` now raises an error when it encounters a redirect instead of hanging.
What's new in Tornado 5.1
July 12, 2018
-------------
Deprecation notice
~~~~~~~~~~~~~~~~~~
- Tornado 6.0 will drop support for Python 2.7 and 3.4. The minimum
supported Python version will be 3.5.2.
- The `tornado.stack_context` module is deprecated and will be removed
in Tornado 6.0. The reason for this is that it is not feasible to
provide this module's semantics in the presence of ``async def``
native coroutines. `.ExceptionStackContext` is mainly obsolete
thanks to coroutines. `.StackContext` lacks a direct replacement
although the new ``contextvars`` package (in the Python standard
library beginning in Python 3.7) may be an alternative.
- Callback-oriented code often relies on `.ExceptionStackContext` to
handle errors and prevent leaked connections. In order to avoid the
risk of silently introducing subtle leaks (and to consolidate all of
Tornado's interfaces behind the coroutine pattern), ``callback``
arguments throughout the package are deprecated and will be removed
in version 6.0. All functions that had a ``callback`` argument
removed now return a `.Future` which should be used instead.
- Where possible, deprecation warnings are emitted when any of these
deprecated interfaces is used. However, Python does not display
deprecation warnings by default. To prepare your application for
Tornado 6.0, run Python with the ``-Wd`` argument or set the
environment variable ``PYTHONWARNINGS`` to ``d``. If your
application runs on Python 3 without deprecation warnings, it should
be able to move to Tornado 6.0 without disruption.
`tornado.auth`
~~~~~~~~~~~~~~
- `.OAuthMixin._oauth_get_user_future` may now be a native coroutine.
- All ``callback`` arguments in this package are deprecated and will
be removed in 6.0. Use the coroutine interfaces instead.
- The ``OAuthMixin._oauth_get_user`` method is deprecated and will be removed in
6.0. Override `~.OAuthMixin._oauth_get_user_future` instead.
`tornado.autoreload`
~~~~~~~~~~~~~~~~~~~~
- The command-line autoreload wrapper is now preserved if an internal
autoreload fires.
- The command-line wrapper no longer starts duplicated processes on windows
when combined with internal autoreload.
`tornado.concurrent`
~~~~~~~~~~~~~~~~~~~~
- `.run_on_executor` now returns `.Future` objects that are compatible
with ``await``.
- The ``callback`` argument to `.run_on_executor` is deprecated and will
be removed in 6.0.
- `.return_future` is deprecated and will be removed in 6.0.
`tornado.gen`
~~~~~~~~~~~~~
- Some older portions of this module are deprecated and will be removed
in 6.0. This includes `.engine`, `.YieldPoint`, `.Callback`,
`.Wait`, `.WaitAll`, `.MultiYieldPoint`, and `.Task`.
- Functions decorated with ``@gen.coroutine`` will no longer accept
``callback`` arguments in 6.0.
`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~
- The behavior of ``raise_error=False`` is changing in 6.0. Currently
it suppresses all errors; in 6.0 it will only suppress the errors
raised due to completed responses with non-200 status codes.
- The ``callback`` argument to `.AsyncHTTPClient.fetch` is deprecated
and will be removed in 6.0.
- `tornado.httpclient.HTTPError` has been renamed to
`.HTTPClientError` to avoid ambiguity in code that also has to deal
with `tornado.web.HTTPError`. The old name remains as an alias.
- ``tornado.curl_httpclient`` now supports non-ASCII characters in
username and password arguments.
- ``.HTTPResponse.request_time`` now behaves consistently across
``simple_httpclient`` and ``curl_httpclient``, excluding time spent
in the ``max_clients`` queue in both cases (previously this time was
included in ``simple_httpclient`` but excluded in
``curl_httpclient``). In both cases the time is now computed using
a monotonic clock where available.
- `.HTTPResponse` now has a ``start_time`` attribute recording a
wall-clock (`time.time`) timestamp at which the request started
(after leaving the ``max_clients`` queue if applicable).
`tornado.httputil`
~~~~~~~~~~~~~~~~~~
- `.parse_multipart_form_data` now recognizes non-ASCII filenames in
RFC 2231/5987 (``filename*=``) format.
- `.HTTPServerRequest.write` is deprecated and will be removed in 6.0. Use
the methods of ``request.connection`` instead.
- Malformed HTTP headers are now logged less noisily.
`tornado.ioloop`
~~~~~~~~~~~~~~~~
- `.PeriodicCallback` now supports a ``jitter`` argument to randomly
vary the timeout.
- `.IOLoop.set_blocking_signal_threshold`,
`~.IOLoop.set_blocking_log_threshold`, `~.IOLoop.log_stack`,
and `.IOLoop.handle_callback_exception` are deprecated and will
be removed in 6.0.
- Fixed a `KeyError` in `.IOLoop.close` when `.IOLoop` objects are
being opened and closed in multiple threads.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- All ``callback`` arguments in this module are deprecated except for
`.BaseIOStream.set_close_callback`. They will be removed in 6.0.
- ``streaming_callback`` arguments to `.BaseIOStream.read_bytes` and
`.BaseIOStream.read_until_close` are deprecated and will be removed
in 6.0.
`tornado.netutil`
~~~~~~~~~~~~~~~~~
- Improved compatibility with GNU Hurd.
`tornado.options`
~~~~~~~~~~~~~~~~~
- `tornado.options.parse_config_file` now allows setting options to
strings (which will be parsed the same way as
`tornado.options.parse_command_line`) in addition to the specified
type for the option.
`tornado.platform.twisted`
~~~~~~~~~~~~~~~~~~~~~~~~~~
- `.TornadoReactor` and `.TwistedIOLoop` are deprecated and will be
removed in 6.0. Instead, Tornado will always use the asyncio event loop
and twisted can be configured to do so as well.
`tornado.stack_context`
~~~~~~~~~~~~~~~~~~~~~~~
- The `tornado.stack_context` module is deprecated and will be removed
in 6.0.
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.AsyncHTTPTestCase.fetch` now takes a ``raise_error`` argument.
This argument has the same semantics as `.AsyncHTTPClient.fetch`,
but defaults to false because tests often need to deal with non-200
responses (and for backwards-compatibility).
- The `.AsyncTestCase.stop` and `.AsyncTestCase.wait` methods are
deprecated.
`tornado.web`
~~~~~~~~~~~~~
- New method `.RequestHandler.detach` can be used from methods
that are not decorated with ``@asynchronous`` (the decorator
was required to use ``self.request.connection.detach()``.
- `.RequestHandler.finish` and `.RequestHandler.render` now return
``Futures`` that can be used to wait for the last part of the
response to be sent to the client.
- `.FallbackHandler` now calls ``on_finish`` for the benefit of
subclasses that may have overridden it.
- The `.asynchronous` decorator is deprecated and will be removed in 6.0.
- The ``callback`` argument to `.RequestHandler.flush` is deprecated
and will be removed in 6.0.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
- When compression is enabled, memory limits now apply to the
post-decompression size of the data, protecting against DoS attacks.
- `.websocket_connect` now supports subprotocols.
- `.WebSocketHandler` and `.WebSocketClientConnection` now have
``selected_subprotocol`` attributes to see the subprotocol in use.
- The `.WebSocketHandler.select_subprotocol` method is now called with
an empty list instead of a list containing an empty string if no
subprotocols were requested by the client.
- `.WebSocketHandler.open` may now be a coroutine.
- The ``data`` argument to `.WebSocketHandler.ping` is now optional.
- Client-side websocket connections no longer buffer more than one
message in memory at a time.
- Exception logging now uses `.RequestHandler.log_exception`.
`tornado.wsgi`
~~~~~~~~~~~~~~
- `.WSGIApplication` and `.WSGIAdapter` are deprecated and will be removed
in Tornado 6.0.
What's new in Tornado 6.0
Mar 1, 2019
-----------
Backwards-incompatible changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Python 2.7 and 3.4 are no longer supported; the minimum supported
Python version is 3.5.2.
- APIs deprecated in Tornado 5.1 have been removed. This includes the
``tornado.stack_context`` module and most ``callback`` arguments
throughout the package. All removed APIs emitted
`DeprecationWarning` when used in Tornado 5.1, so running your
application with the ``-Wd`` Python command-line flag or the
environment variable ``PYTHONWARNINGS=d`` should tell you whether
your application is ready to move to Tornado 6.0.
- ``.WebSocketHandler.get`` is now a coroutine and must be called
accordingly in any subclasses that override this method (but note
that overriding ``get`` is not recommended; either ``prepare`` or
``open`` should be used instead).
General changes
~~~~~~~~~~~~~~~
- Tornado now includes type annotations compatible with ``mypy``.
These annotations will be used when type-checking your application
with ``mypy``, and may be usable in editors and other tools.
- Tornado now uses native coroutines internally, improving performance.
`tornado.auth`
~~~~~~~~~~~~~~
- All ``callback`` arguments in this package have been removed. Use
the coroutine interfaces instead.
- The ``OAuthMixin._oauth_get_user`` method has been removed.
Override `~.OAuthMixin._oauth_get_user_future` instead.
`tornado.concurrent`
~~~~~~~~~~~~~~~~~~~~
- The ``callback`` argument to `.run_on_executor` has been removed.
- ``return_future`` has been removed.
`tornado.gen`
~~~~~~~~~~~~~
- Some older portions of this module have been removed. This includes
``engine``, ``YieldPoint``, ``Callback``, ``Wait``, ``WaitAll``,
``MultiYieldPoint``, and ``Task``.
- Functions decorated with ``@gen.coroutine`` no longer accept
``callback`` arguments.
`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~
- The behavior of ``raise_error=False`` has changed. Now only
suppresses the errors raised due to completed responses with non-200
status codes (previously it suppressed all errors).
- The ``callback`` argument to `.AsyncHTTPClient.fetch` has been removed.
`tornado.httputil`
~~~~~~~~~~~~~~~~~~
- ``HTTPServerRequest.write`` has been removed. Use the methods of
``request.connection`` instead.
- Unrecognized ``Content-Encoding`` values now log warnings only for
content types that we would otherwise attempt to parse.
`tornado.ioloop`
~~~~~~~~~~~~~~~~
- ``IOLoop.set_blocking_signal_threshold``,
``IOLoop.set_blocking_log_threshold``, ``IOLoop.log_stack``,
and ``IOLoop.handle_callback_exception`` have been removed.
- Improved performance of `.IOLoop.add_callback`.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- All ``callback`` arguments in this module have been removed except
for `.BaseIOStream.set_close_callback`.
- ``streaming_callback`` arguments to `.BaseIOStream.read_bytes` and
`.BaseIOStream.read_until_close` have been removed.
- Eliminated unnecessary logging of "Errno 0".
`tornado.log`
~~~~~~~~~~~~~
- Log files opened by this module are now explicitly set to UTF-8 encoding.
`tornado.netutil`
~~~~~~~~~~~~~~~~~
- The results of ``getaddrinfo`` are now sorted by address family to
avoid partial failures and deadlocks.
`tornado.platform.twisted`
~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``TornadoReactor`` and ``TwistedIOLoop`` have been removed.
``tornado.simple_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The default HTTP client now supports the ``network_interface``
request argument to specify the source IP for the connection.
- If a server returns a 3xx response code without a ``Location``
header, the response is raised or returned directly instead of
trying and failing to follow the redirect.
- When following redirects, methods other than ``POST`` will no longer
be transformed into ``GET`` requests. 301 (permanent) redirects are
now treated the same way as 302 (temporary) and 303 (see other)
redirects in this respect.
- Following redirects now works with ``body_producer``.
``tornado.stack_context``
~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``tornado.stack_context`` module has been removed.
`tornado.tcpserver`
~~~~~~~~~~~~~~~~~~~
- `.TCPServer.start` now supports a ``max_restarts`` argument (same as
`.fork_processes`).
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.AsyncHTTPTestCase` now drops all references to the `.Application`
during ``tearDown``, allowing its memory to be reclaimed sooner.
- `.AsyncTestCase` now cancels all pending coroutines in ``tearDown``,
in an effort to reduce warnings from the python runtime about
coroutines that were not awaited. Note that this may cause
``asyncio.CancelledError`` to be logged in other places. Coroutines
that expect to be running at test shutdown may need to catch this
exception.
`tornado.web`
~~~~~~~~~~~~~
- The ``asynchronous`` decorator has been removed.
- The ``callback`` argument to `.RequestHandler.flush` has been removed.
- `.StaticFileHandler` now supports large negative values for the
``Range`` header and returns an appropriate error for ``end >
start``.
- It is now possible to set ``expires_days`` in ``xsrf_cookie_kwargs``.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
- Pings and other messages sent while the connection is closing are
now silently dropped instead of logging exceptions.
- Errors raised by ``open()`` are now caught correctly when this method
is a coroutine.
`tornado.wsgi`
~~~~~~~~~~~~~~
- ``WSGIApplication`` and ``WSGIAdapter`` have been removed.
What's new in Tornado 4.5
Apr 16, 2017
------------
`tornado.log`
~~~~~~~~~~~~~
- Improved detection of libraries for colorized logging.
`tornado.httputil`
~~~~~~~~~~~~~~~~~~
- `.url_concat` once again treats None as equivalent to an empty sequence.
What's new in Tornado 4.5.2
Aug 27, 2017
------------
Bug Fixes
~~~~~~~~~
- Tornado now sets the ``FD_CLOEXEC`` flag on all file descriptors it creates. This prevents hanging client connections and resource leaks when the `tornado.autoreload` module (or ``Application(debug=True)``) is used.
What's new in Tornado 4.5.3
Jan 6, 2018
------------
`tornado.curl_httpclient`
~~~~~~~~~~~~~~~~~~~~~~~~~
- Improved debug logging on Python 3.
`tornado.httpserver`
~~~~~~~~~~~~~~~~~~~~
- ``Content-Length`` and ``Transfer-Encoding`` headers are no longer
sent with 1xx or 204 responses (this was already true of 304
responses).
- Reading chunked requests no longer leaves the connection in a broken
state.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- Writing a `memoryview` can no longer result in "BufferError:
Existing exports of data: object cannot be re-sized".
`tornado.options`
~~~~~~~~~~~~~~~~~
- Duplicate option names are now detected properly whether they use
hyphens or underscores.
`tornado.testing`
~~~~~~~~~~~~~~~~~
- `.AsyncHTTPTestCase.fetch` now uses ``127.0.0.1`` instead of
``localhost``, improving compatibility with systems that have
partially-working ipv6 stacks.
`tornado.web`
~~~~~~~~~~~~~
- It is no longer allowed to send a body with 1xx or 204 responses.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
- Requests with invalid websocket headers now get a response with
status code 400 instead of a closed connection.
What's new in Tornado 5.0
Mar 5, 2018
-----------
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.
- Tornado 5.0 supports Python 2.7.9+ and 3.4+. Python 2.7 and 3.4 are
deprecated and support for them will be removed in Tornado 6.0,
which will require Python 3.5+.
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 ``futures`` (`concurrent.futures` backport) package is now required
on Python 2.7.
- 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.auth`
~~~~~~~~~~~~~~
- `.GoogleOAuth2Mixin` now uses a newer set of URLs.
`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`
~~~~~~~~~~~~~~~~~~~~
- It is now possible for a client to reuse a connection after sending
a chunked request.
- 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.install` and `.IOLoop.clear_instance` are deprecated.
- ``IOLoop.initialized`` has been removed.
- On Python 3, the `asyncio`-backed `.IOLoop` is always used and
alternative `.IOLoop` implementations cannot be configured.
`.IOLoop.current` and related methods pass through to
`asyncio.get_event_loop`.
- `~.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.
- `.IOLoop.clear_current` now works if it is called before any
current loop is established.
- The ``IOLoop.initialized`` method has been removed.
`tornado.iostream`
~~~~~~~~~~~~~~~~~~
- The ``io_loop`` argument to the `.IOStream` constructor has been removed.
- New method `.BaseIOStream.read_into` provides a minimal-copy alternative to
`.BaseIOStream.read_bytes`.
- `.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 default `.Resolver` now uses `.IOLoop.run_in_executor`.
`.ExecutorResolver`, `.BlockingResolver`, and `.ThreadedResolver` are
deprecated.
- 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.
- `.OverrideResolver` now accepts per-family overrides.
`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. Closing an `.IOLoop`
closes the corresponding `asyncio` event loop.
- `.to_tornado_future` and `.to_asyncio_future` are deprecated since
they are now no-ops.
- `~.AnyThreadEventLoopPolicy` can now be used to easily allow the creation
of event loops on any thread (similar to Tornado's prior policy).
`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.
- `.AsyncHTTPTestCase.fetch` now connects to ``127.0.0.1``
instead of ``localhost`` to be more robust against faulty
ipv6 configurations.
`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.
- If both ``If-None-Match`` and ``If-Modified-Since`` headers are present
in a request to `.StaticFileHandler`, the latter is now ignored.
`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 `.WebSocketClosedError` if
the connection closes while the write is in progress.
- The ``io_loop`` argument to `.websocket_connect` has been removed.
What's new in Tornado 5.0.1
Mar 18, 2018
------------
Bug fix
~~~~~~~
- This release restores support for versions of Python 3.4 prior to
3.4.4. This is important for compatibility with Debian Jessie which
has 3.4.2 as its version of Python 3.
What's new in Tornado 4.4.1
===========================
Jul 23, 2016
------------
`tornado.web`
~~~~~~~~~~~~~
* Fixed a regression in Tornado 4.4 which caused URL regexes
containing backslash escapes outside capturing groups to be
rejected.
What's new in Tornado 4.4.2
===========================
Oct 1, 2016
------------
Security fixes
~~~~~~~~~~~~~~
* A difference in cookie parsing between Tornado and web browsers
(especially when combined with Google Analytics) could allow an
attacker to set arbitrary cookies and bypass XSRF protection. The
cookie parser has been rewritten to fix this attack.
Backwards-compatibility notes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Cookies containing certain special characters (in particular semicolon
and square brackets) are now parsed differently.
* If the cookie header contains a combination of valid and invalid cookies,
the valid ones will be returned (older versions of Tornado would reject the
entire header for a single invalid cookie).
What's new in Tornado 4.4.3
Mar 30, 2017
------------
Bug fixes
~~~~~~~~~
* The `tornado.auth` module has been updated for compatibility with `a
change to Facebook's access_token endpoint.
<https://github.com/tornadoweb/tornado/pull/1977>`_
What's new in Tornado 4.4
=========================
Jul 15, 2016
------------
General
~~~~~~~
* Tornado now requires Python 2.7 or 3.3+; versions 2.6 and 3.2 are no
longer supported. Pypy3 is still supported even though its latest
release is mainly based on Python 3.2.
* The `monotonic <https://pypi.python.org/pypi/monotonic>`_ package is
now supported as an alternative to `Monotime
<https://pypi.python.org/pypi/Monotime>`_ for monotonic clock support
on Python 2.
``tornado.curl_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Failures in ``_curl_setup_request`` no longer cause the
``max_clients`` pool to be exhausted.
* Non-ascii header values are now handled correctly.
`tornado.gen`
~~~~~~~~~~~~~
* `.with_timeout` now accepts any yieldable object (except
`.YieldPoint`), not just `tornado.concurrent.Future`.
`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~
* The errors raised by timeouts now indicate what state the request
was in; the error message is no longer simply "599 Timeout".
* Calling `repr` on a `tornado.httpclient.HTTPError` no longer raises
an error.
`tornado.httpserver`
~~~~~~~~~~~~~~~~~~~~
* Int-like enums (including `http.HTTPStatus`) can now be used as
status codes.
* Responses with status code ``204 No Content`` no longer emit a
``Content-Length: 0`` header.
`tornado.ioloop`
~~~~~~~~~~~~~~~~
* Improved performance when there are large numbers of active timeouts.
`tornado.netutil`
~~~~~~~~~~~~~~~~~
* All included `.Resolver` implementations raise `IOError` (or a
subclass) for any resolution failure.
`tornado.options`
~~~~~~~~~~~~~~~~~
* Options can now be modified with subscript syntax in addition to
attribute syntax.
* The special variable ``__file__`` is now available inside config files.
``tornado.simple_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* HTTP/1.0 (not 1.1) responses without a ``Content-Length`` header now
work correctly.
`tornado.tcpserver`
~~~~~~~~~~~~~~~~~~~
* `.TCPServer.bind` now accepts a ``reuse_port`` argument.
`tornado.testing`
~~~~~~~~~~~~~~~~~
* Test sockets now always use ``127.0.0.1`` instead of ``localhost``.
This avoids conflicts when the automatically-assigned port is
available on IPv4 but not IPv6, or in unusual network configurations
when ``localhost`` has multiple IP addresses.
`tornado.web`
~~~~~~~~~~~~~
* ``image/svg+xml`` is now on the list of compressible mime types.
* Fixed an error on Python 3 when compression is used with multiple
``Vary`` headers.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
* ``WebSocketHandler.__init__`` now uses `super`, which improves
support for multiple inheritance.