What’s new in Tornado 6.2.0

Jul 3, 2022

Deprecation notice

  • April 2023 update: Python 3.12 reversed some of the changes described below. In Tornado 6.3, AsyncTestCase, AsyncHTTPTestCase, and the behavior of the IOLoop constructor related to the make_current parameter are no longer deprecated.

  • 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.

  • 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 verification 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.


  • Fixed a bug in which WaitIterator.current_index could be incorrect.

  • tornado.gen.TimeoutError is now an alias for asyncio.TimeoutError.


  • max_body_size may now be set to zero to disallow a non-empty body.

  • Content-Encoding: gzip is now recognized case-insensitively.


  • curl_httpclient now supports non-ASCII (ISO-8859-1) header values, same as simple_httpclient.


  • 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.


  • SSLIOStream now supports reading more than 2GB at a time.

  • IOStream.write now supports typed memoryview objects.



  • 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.



  • bind_unused_port now takes an optional address argument.

  • Wrapped test methods now include the __wrapped__ attribute.