### Navigation
- [index](# "General Index")
- [modules](# "Python Module Index") |
- [next](# "What鈥檚 new in Tornado 2.4.1") |
- [previous](# "What鈥檚 new in Tornado 3.0.1") |
- [Tornado 4.4.dev1 documentation](#) »
- [Release notes](#) »
# What's new in Tornado 3.0
### Mar 29, 2013
### Highlights
- The `callback` argument to many asynchronous methods is nowoptional, and these methods return a [`Future`](# "tornado.concurrent.Future"). The [`tornado.gen`](# "tornado.gen")module now understands `Futures`, and these methods can be useddirectly without a [`gen.Task`](# "tornado.gen.Task") wrapper.
- New function [`IOLoop.current`](# "tornado.ioloop.IOLoop.current") returns the [`IOLoop`](# "tornado.ioloop.IOLoop") that is runningon the current thread (as opposed to [`IOLoop.instance`](# "tornado.ioloop.IOLoop.instance"), whichreturns a specific thread's (usually the main thread's) IOLoop.
- New class [`tornado.netutil.Resolver`](# "tornado.netutil.Resolver") provides an asynchronousinterface to DNS resolution. The default implementation is stillblocking, but non-blocking implementations are available using oneof three optional dependencies: [`ThreadedResolver`](# "tornado.netutil.ThreadedResolver")using the [`concurrent.futures`](https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures "(in Python v3.4)") [https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures] thread pool,`tornado.platform.caresresolver.CaresResolver` using the `pycares`library, or `tornado.platform.twisted.TwistedResolver` using `twisted`
- Tornado's logging is now less noisy, and it no longer goes directlyto the root logger, allowing for finer-grained configuration.
- New class [`tornado.process.Subprocess`](# "tornado.process.Subprocess") wraps [`subprocess.Popen`](https://docs.python.org/3.4/library/subprocess.html#subprocess.Popen "(in Python v3.4)") [https://docs.python.org/3.4/library/subprocess.html#subprocess.Popen] with[`PipeIOStream`](# "tornado.iostream.PipeIOStream") access to the child's file descriptors.
- [`IOLoop`](# "tornado.ioloop.IOLoop") now has a static [`configure`](# "tornado.util.Configurable.configure")method like the one on [`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient"), which can be used toselect an [`IOLoop`](# "tornado.ioloop.IOLoop") implementation other than the default.
- [`IOLoop`](# "tornado.ioloop.IOLoop") can now optionally use a monotonic clock if available(see below for more details).
### Backwards-incompatible changes
- Python 2.5 is no longer supported. Python 3 is now supported in a singlecodebase instead of using `2to3`
- The `tornado.database` module has been removed. It is now availableas a separate package, [torndb](https://github.com/bdarnell/torndb) [https://github.com/bdarnell/torndb]
- Functions that take an `io_loop` parameter now default to[`IOLoop.current()`](# "tornado.ioloop.IOLoop.current") instead of [`IOLoop.instance()`](# "tornado.ioloop.IOLoop.instance").
- Empty HTTP request arguments are no longer ignored. This applies to`HTTPRequest.arguments` and `RequestHandler.get_argument[s]`in WSGI and non-WSGI modes.
- On Python 3, [`tornado.escape.json_encode`](# "tornado.escape.json_encode") no longer accepts byte strings.
- On Python 3, the `get_authenticated_user` methods in [`tornado.auth`](# "tornado.auth")now return character strings instead of byte strings.
- `tornado.netutil.TCPServer` has moved to its own module,[`tornado.tcpserver`](# "tornado.tcpserver").
- The Tornado test suite now requires `unittest2` when run on Python 2.6.
- [`tornado.options.options`](# "tornado.options.options") is no longer a subclass of [`dict`](https://docs.python.org/3.4/library/stdtypes.html#dict "(in Python v3.4)") [https://docs.python.org/3.4/library/stdtypes.html#dict]; attribute-styleaccess is now required.
### Detailed changes by module
#### Multiple modules
- Tornado no longer logs to the root logger. Details on the new loggingscheme can be found under the [`tornado.log`](# "tornado.log") module. Note that in somecases this will require that you add an explicit logging configurationin order to see any output (perhaps just calling `logging.basicConfig()`),although both [`IOLoop.start()`](# "tornado.ioloop.IOLoop.start") and [`tornado.options.parse_command_line`](# "tornado.options.parse_command_line")will do this for you.
- On python 3.2+, methods that take an `ssl_options` argument (on[`SSLIOStream`](# "tornado.iostream.SSLIOStream"), [`TCPServer`](# "tornado.tcpserver.TCPServer"), and [`HTTPServer`](# "tornado.httpserver.HTTPServer")) now accept either adictionary of options or an [`ssl.SSLContext`](https://docs.python.org/3.4/library/ssl.html#ssl.SSLContext "(in Python v3.4)") [https://docs.python.org/3.4/library/ssl.html#ssl.SSLContext] object.
- New optional dependency on [`concurrent.futures`](https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures "(in Python v3.4)") [https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures] to provide better supportfor working with threads. [`concurrent.futures`](https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures "(in Python v3.4)") [https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures] is in the standard libraryfor Python 3.2+, and can be installed on older versions with`pip install futures`.
#### [`tornado.autoreload`](# "tornado.autoreload")
- [`tornado.autoreload`](# "tornado.autoreload") is now more reliable when there are errors at importtime.
- Calling [`tornado.autoreload.start`](# "tornado.autoreload.start") (or creating an [`Application`](# "tornado.web.Application") with`debug=True`) twice on the same [`IOLoop`](# "tornado.ioloop.IOLoop") now does nothing (instead ofcreating multiple periodic callbacks). Starting autoreload onmore than one [`IOLoop`](# "tornado.ioloop.IOLoop") in the same process now logs a warning.
- Scripts run by autoreload no longer inherit `__future__` importsused by Tornado.
#### [`tornado.auth`](# "tornado.auth")
- On Python 3, the `get_authenticated_user` method family now returnscharacter strings instead of byte strings.
- Asynchronous methods defined in [`tornado.auth`](# "tornado.auth") now return a[`Future`](# "tornado.concurrent.Future"), and their `callback` argument is optional. The`Future` interface is preferred as it offers better error handling(the previous interface just logged a warning and returned None).
- The [`tornado.auth`](# "tornado.auth") mixin classes now define a method`get_auth_http_client`, which can be overridden to use a non-default[`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient") instance (e.g. to use a different [`IOLoop`](# "tornado.ioloop.IOLoop"))
- Subclasses of [`OAuthMixin`](# "tornado.auth.OAuthMixin") are encouraged to override[`OAuthMixin._oauth_get_user_future`](# "tornado.auth.OAuthMixin._oauth_get_user_future") instead of `_oauth_get_user`,although both methods are still supported.
#### [`tornado.concurrent`](# "tornado.concurrent")
- New module [`tornado.concurrent`](# "tornado.concurrent") contains code to support working with[`concurrent.futures`](https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures "(in Python v3.4)") [https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures], or to emulate future-based interface when that moduleis not available.
#### `tornado.curl_httpclient`
- Preliminary support for `tornado.curl_httpclient` on Python 3. The latestofficial release of pycurl only supports Python 2, but Ubuntu has aport available in 12.10 (`apt-get install python3-pycurl`). This portcurrently has bugs that prevent it from handling arbitrary binary databut it should work for textual (utf8) resources.
- Fix a crash with libcurl 7.29.0 if a curl object is created and closedwithout being used.
#### [`tornado.escape`](# "tornado.escape")
- On Python 3, [`json_encode`](# "tornado.escape.json_encode") no longer accepts byte strings.This mirrors the behavior of the underlying json module. Python 2 behavioris unchanged but should be faster.
#### [`tornado.gen`](# "tornado.gen")
- New decorator `@gen.coroutine` is available as an alternative to`@gen.engine`. It automatically returns a[`Future`](# "tornado.concurrent.Future"), and within the function instead ofcalling a callback you return a value with `raisegen.Return(value)` (or simply `return value` in Python 3.3).
- Generators may now yield [`Future`](# "tornado.concurrent.Future") objects.
- Callbacks produced by [`gen.Callback`](# "tornado.gen.Callback") and [`gen.Task`](# "tornado.gen.Task") are now automaticallystack-context-wrapped, to minimize the risk of context leaks when usedwith asynchronous functions that don't do their own wrapping.
- Fixed a memory leak involving generators, [`RequestHandler.flush`](# "tornado.web.RequestHandler.flush"),and clients closing connections while output is being written.
- Yielding a large list no longer has quadratic performance.
#### [`tornado.httpclient`](# "tornado.httpclient")
- [`AsyncHTTPClient.fetch`](# "tornado.httpclient.AsyncHTTPClient.fetch") now returns a [`Future`](# "tornado.concurrent.Future") and its callback argumentis optional. When the future interface is used, any error will be raisedautomatically, as if [`HTTPResponse.rethrow`](# "tornado.httpclient.HTTPResponse.rethrow") was called.
- [`AsyncHTTPClient.configure`](# "tornado.httpclient.AsyncHTTPClient.configure") and all [`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient") constructorsnow take a `defaults` keyword argument. This argument should be adictionary, and its values will be used in place of correspondingattributes of [`HTTPRequest`](# "tornado.httpclient.HTTPRequest") that are not set.
- All unset attributes of [`tornado.httpclient.HTTPRequest`](# "tornado.httpclient.HTTPRequest") are now`None`. The default values of some attributes(`connect_timeout`, `request_timeout`, `follow_redirects`,`max_redirects`, `use_gzip`, `proxy_password`,`allow_nonstandard_methods`, and `validate_cert` have been movedfrom [`HTTPRequest`](# "tornado.httpclient.HTTPRequest") to the clientimplementations.
- The `max_clients` argument to [`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient") is now a keyword-onlyargument.
- Keyword arguments to [`AsyncHTTPClient.configure`](# "tornado.httpclient.AsyncHTTPClient.configure") are no longer usedwhen instantiating an implementation subclass directly.
- Secondary [`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient") callbacks (`streaming_callback`,`header_callback`, and `prepare_curl_callback`) now respect[`StackContext`](# "tornado.stack_context.StackContext").
#### [`tornado.httpserver`](# "tornado.httpserver")
- [`HTTPServer`](# "tornado.httpserver.HTTPServer") no longer logs an error when it is unable to read a secondrequest from an HTTP 1.1 keep-alive connection.
- [`HTTPServer`](# "tornado.httpserver.HTTPServer") now takes a `protocol` keyword argument which can be setto `https` if the server is behind an SSL-decoding proxy that does notset any supported X-headers.
- `tornado.httpserver.HTTPConnection` now has a `set_close_callback`method that should be used instead of reaching into its `stream`attribute.
- Empty HTTP request arguments are no longer ignored. This applies to`HTTPRequest.arguments` and `RequestHandler.get_argument[s]`in WSGI and non-WSGI modes.
#### [`tornado.ioloop`](# "tornado.ioloop")
- New function [`IOLoop.current`](# "tornado.ioloop.IOLoop.current") returns the `IOLoop` that is runningon the current thread (as opposed to [`IOLoop.instance`](# "tornado.ioloop.IOLoop.instance"), which returns aspecific thread's (usually the main thread's) IOLoop).
- New method [`IOLoop.add_future`](# "tornado.ioloop.IOLoop.add_future") to run a callback on the IOLoop whenan asynchronous [`Future`](# "tornado.concurrent.Future") finishes.
- [`IOLoop`](# "tornado.ioloop.IOLoop") now has a static [`configure`](# "tornado.util.Configurable.configure")method like the one on [`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient"), which can be used toselect an [`IOLoop`](# "tornado.ioloop.IOLoop") implementation other than the default.
- The [`IOLoop`](# "tornado.ioloop.IOLoop") poller implementations (`select`, `epoll`, `kqueue`)are now available as distinct subclasses of [`IOLoop`](# "tornado.ioloop.IOLoop"). Instantiating[`IOLoop`](# "tornado.ioloop.IOLoop") will continue to automatically choose the best availableimplementation.
- The [`IOLoop`](# "tornado.ioloop.IOLoop") constructor has a new keyword argument `time_func`,which can be used to set the time function used when scheduling callbacks.This is most useful with the [`time.monotonic`](https://docs.python.org/3.4/library/time.html#time.monotonic "(in Python v3.4)") [https://docs.python.org/3.4/library/time.html#time.monotonic] function, introducedin Python 3.3 and backported to older versions via the `monotime`module. Using a monotonic clock here avoids problems when the systemclock is changed.
- New function [`IOLoop.time`](# "tornado.ioloop.IOLoop.time") returns the current time according to theIOLoop. To use the new monotonic clock functionality, all calls to[`IOLoop.add_timeout`](# "tornado.ioloop.IOLoop.add_timeout") must be either pass a [`datetime.timedelta`](https://docs.python.org/3.4/library/datetime.html#datetime.timedelta "(in Python v3.4)") [https://docs.python.org/3.4/library/datetime.html#datetime.timedelta] ora time relative to [`IOLoop.time`](# "tornado.ioloop.IOLoop.time"), not [`time.time`](https://docs.python.org/3.4/library/time.html#time.time "(in Python v3.4)") [https://docs.python.org/3.4/library/time.html#time.time]. ([`time.time`](https://docs.python.org/3.4/library/time.html#time.time "(in Python v3.4)") [https://docs.python.org/3.4/library/time.html#time.time] willcontinue to work only as long as the IOLoop's `time_func` argumentis not used).
- New convenience method [`IOLoop.run_sync`](# "tornado.ioloop.IOLoop.run_sync") can be used to start an IOLoopjust long enough to run a single coroutine.
- New method [`IOLoop.add_callback_from_signal`](# "tornado.ioloop.IOLoop.add_callback_from_signal") is safe to use in a signalhandler (the regular [`add_callback`](# "tornado.ioloop.IOLoop.add_callback") method may deadlock).
- [`IOLoop`](# "tornado.ioloop.IOLoop") now uses [`signal.set_wakeup_fd`](https://docs.python.org/3.4/library/signal.html#signal.set_wakeup_fd "(in Python v3.4)") [https://docs.python.org/3.4/library/signal.html#signal.set_wakeup_fd] where available (Python 2.6+on Unix) to avoid a race condition that could result in Python signalhandlers being delayed.
- Method `IOLoop.running()` has been removed.
- [`IOLoop`](# "tornado.ioloop.IOLoop") has been refactored to better support subclassing.
- [`IOLoop.add_callback`](# "tornado.ioloop.IOLoop.add_callback") and [`add_callback_from_signal`](# "tornado.ioloop.IOLoop.add_callback_from_signal") now take`*args, **kwargs` to pass along to the callback.
#### [`tornado.iostream`](# "tornado.iostream")
- [`IOStream.connect`](# "tornado.iostream.IOStream.connect") now has an optional `server_hostname` argumentwhich will be used for SSL certificate validation when applicable.Additionally, when supported (on Python 3.2+), this hostnamewill be sent via SNI (and this is supported by `tornado.simple_httpclient`)
- Much of [`IOStream`](# "tornado.iostream.IOStream") has been refactored into a separate class[`BaseIOStream`](# "tornado.iostream.BaseIOStream").
- New class [`tornado.iostream.PipeIOStream`](# "tornado.iostream.PipeIOStream") provides the IOStreaminterface on pipe file descriptors.
- [`IOStream`](# "tornado.iostream.IOStream") now raises a new exception`tornado.iostream.StreamClosedError` when you attempt to read orwrite after the stream has been closed (by either side).
- [`IOStream`](# "tornado.iostream.IOStream") now simply closes the connection when it gets an`ECONNRESET` error, rather than logging it as an error.
- `IOStream.error` no longer picks up unrelated exceptions.
- [`BaseIOStream.close`](# "tornado.iostream.BaseIOStream.close") now has an `exc_info` argument (similar to theone used in the [`logging`](https://docs.python.org/3.4/library/logging.html#module-logging "(in Python v3.4)") [https://docs.python.org/3.4/library/logging.html#module-logging] module) that can be used to set the stream's`error` attribute when closing it.
- [`BaseIOStream.read_until_close`](# "tornado.iostream.BaseIOStream.read_until_close") now works correctly when it is calledwhile there is buffered data.
- Fixed a major performance regression when run on PyPy (introduced inTornado 2.3).
#### [`tornado.log`](# "tornado.log")
- New module containing [`enable_pretty_logging`](# "tornado.log.enable_pretty_logging") and [`LogFormatter`](# "tornado.log.LogFormatter"),moved from the options module.
- [`LogFormatter`](# "tornado.log.LogFormatter") now handles non-ascii data in messages and tracebacks better.
#### [`tornado.netutil`](# "tornado.netutil")
- New class [`tornado.netutil.Resolver`](# "tornado.netutil.Resolver") provides an asynchronousinterface to DNS resolution. The default implementation is stillblocking, but non-blocking implementations are available using oneof three optional dependencies: [`ThreadedResolver`](# "tornado.netutil.ThreadedResolver")using the [`concurrent.futures`](https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures "(in Python v3.4)") [https://docs.python.org/3.4/library/concurrent.futures.html#module-concurrent.futures] thread pool,[`tornado.platform.caresresolver.CaresResolver`](# "tornado.platform.caresresolver.CaresResolver") using the `pycares`library, or [`tornado.platform.twisted.TwistedResolver`](# "tornado.platform.twisted.TwistedResolver") using `twisted`
- New function [`tornado.netutil.is_valid_ip`](# "tornado.netutil.is_valid_ip") returns true if a given stringis a valid IP (v4 or v6) address.
- [`tornado.netutil.bind_sockets`](# "tornado.netutil.bind_sockets") has a new `flags` argument that canbe used to pass additional flags to `getaddrinfo`.
- [`tornado.netutil.bind_sockets`](# "tornado.netutil.bind_sockets") no longer sets `AI_ADDRCONFIG`; this willcause it to bind to both ipv4 and ipv6 more often than before.
- [`tornado.netutil.bind_sockets`](# "tornado.netutil.bind_sockets") now works when Python was compiledwith `--disable-ipv6` but IPv6 DNS resolution is available on thesystem.
- `tornado.netutil.TCPServer` has moved to its own module, [`tornado.tcpserver`](# "tornado.tcpserver").
#### [`tornado.options`](# "tornado.options")
- The class underlying the functions in [`tornado.options`](# "tornado.options") is now public([`tornado.options.OptionParser`](# "tornado.options.OptionParser")). This can be used to create multipleindependent option sets, such as for subcommands.
- [`tornado.options.parse_config_file`](# "tornado.options.parse_config_file") now configures logging automaticallyby default, in the same way that [`parse_command_line`](# "tornado.options.parse_command_line") does.
- New function [`tornado.options.add_parse_callback`](# "tornado.options.add_parse_callback") schedules a callbackto be run after the command line or config file has been parsed. Thekeyword argument `final=False` can be used on either parsing functionto supress these callbacks.
- [`tornado.options.define`](# "tornado.options.define") now takes a `callback` argument. This callbackwill be run with the new value whenever the option is changed. This isespecially useful for options that set other options, such as by readingfrom a config file.
- [`tornado.options.parse_command_line`](# "tornado.options.parse_command_line")`--help` output now goes to `stderr`rather than `stdout`.
- [`tornado.options.options`](# "tornado.options.options") is no longer a subclass of [`dict`](https://docs.python.org/3.4/library/stdtypes.html#dict "(in Python v3.4)") [https://docs.python.org/3.4/library/stdtypes.html#dict]; attribute-styleaccess is now required.
- [`tornado.options.options`](# "tornado.options.options") (and [`OptionParser`](# "tornado.options.OptionParser") instances generally) nowhave a [`mockable()`](# "tornado.options.OptionParser.mockable") method that returns a wrapper object compatible with[`mock.patch`](https://docs.python.org/3.4/library/unittest.mock.html#unittest.mock.patch "(in Python v3.4)") [https://docs.python.org/3.4/library/unittest.mock.html#unittest.mock.patch].
- Function `tornado.options.enable_pretty_logging` has been moved to the[`tornado.log`](# "tornado.log") module.
#### [`tornado.platform.caresresolver`](# "tornado.platform.caresresolver")
- New module containing an asynchronous implementation of the [`Resolver`](# "tornado.netutil.Resolver")interface, using the `pycares` library.
#### [`tornado.platform.twisted`](# "tornado.platform.twisted")
- New class [`tornado.platform.twisted.TwistedIOLoop`](# "tornado.platform.twisted.TwistedIOLoop") allows Tornadocode to be run on the Twisted reactor (as opposed to the existing[`TornadoReactor`](# "tornado.platform.twisted.TornadoReactor"), which bridges the gap in the other direction).
- New class [`tornado.platform.twisted.TwistedResolver`](# "tornado.platform.twisted.TwistedResolver") is an asynchronousimplementation of the [`Resolver`](# "tornado.netutil.Resolver") interface.
#### [`tornado.process`](# "tornado.process")
- New class [`tornado.process.Subprocess`](# "tornado.process.Subprocess") wraps [`subprocess.Popen`](https://docs.python.org/3.4/library/subprocess.html#subprocess.Popen "(in Python v3.4)") [https://docs.python.org/3.4/library/subprocess.html#subprocess.Popen] with[`PipeIOStream`](# "tornado.iostream.PipeIOStream") access to the child's file descriptors.
#### `tornado.simple_httpclient`
- `SimpleAsyncHTTPClient` now takes a `resolver` keyword argument(which may be passed to either the constructor or [`configure`](# "tornado.util.Configurable.configure")), to allow it to use the new non-blocking[`tornado.netutil.Resolver`](# "tornado.netutil.Resolver").
- When following redirects, `SimpleAsyncHTTPClient` now treats a 302response code the same as a 303. This is contrary to the HTTP specbut consistent with all browsers and other major HTTP clients(including `CurlAsyncHTTPClient`).
- The behavior of `header_callback` with `SimpleAsyncHTTPClient` haschanged and is now the same as that of `CurlAsyncHTTPClient`. Theheader callback now receives the first line of the response (e.g.`HTTP/1.0 200 OK`) and the final empty line.
- `tornado.simple_httpclient` now accepts responses with a 304status code that include a `Content-Length` header.
- Fixed a bug in which `SimpleAsyncHTTPClient` callbacks were being run in theclient's `stack_context`.
#### [`tornado.stack_context`](# "tornado.stack_context")
- [`stack_context.wrap`](# "tornado.stack_context.wrap") now runs the wrapped callback in a more consistentenvironment by recreating contexts even if they already exist on thestack.
- Fixed a bug in which stack contexts could leak from one callbackchain to another.
- Yield statements inside a `with` statement can cause stackcontexts to become inconsistent; an exception will now be raisedwhen this case is detected.
#### [`tornado.template`](# "tornado.template")
- Errors while rendering templates no longer log the generated code,since the enhanced stack traces (from version 2.1) should make thisunnecessary.
- The `{% apply %}` directive now works properly with functions that returnboth unicode strings and byte strings (previously only byte strings weresupported).
- Code in templates is no longer affected by Tornado's `__future__` imports(which previously included `absolute_import` and `division`).
#### [`tornado.testing`](# "tornado.testing")
- New function [`tornado.testing.bind_unused_port`](# "tornado.testing.bind_unused_port") both chooses a portand binds a socket to it, so there is no risk of another processusing the same port. `get_unused_port` is now deprecated.
- New decorator [`tornado.testing.gen_test`](# "tornado.testing.gen_test") can be used to allow foryielding [`tornado.gen`](# "tornado.gen") objects in tests, as an alternative to the`stop` and `wait` methods of [`AsyncTestCase`](# "tornado.testing.AsyncTestCase").
- [`tornado.testing.AsyncTestCase`](# "tornado.testing.AsyncTestCase") and friends now extend `unittest2.TestCase`when it is available (and continue to use the standard `unittest` modulewhen `unittest2` is not available)
- [`tornado.testing.ExpectLog`](# "tornado.testing.ExpectLog") can be used as a finer-grained alternativeto [`tornado.testing.LogTrapTestCase`](# "tornado.testing.LogTrapTestCase")
- The command-line interface to [`tornado.testing.main`](# "tornado.testing.main") now supportsadditional arguments from the underlying [`unittest`](https://docs.python.org/3.4/library/unittest.html#module-unittest "(in Python v3.4)") [https://docs.python.org/3.4/library/unittest.html#module-unittest] module:`verbose`, `quiet`, `failfast`, `catch`, `buffer`.
- The deprecated `--autoreload` option of [`tornado.testing.main`](# "tornado.testing.main") hasbeen removed. Use `python -m tornado.autoreload` as a prefix commandinstead.
- The `--httpclient` option of [`tornado.testing.main`](# "tornado.testing.main") has been movedto `tornado.test.runtests` so as not to pollute the applicationoption namespace. The [`tornado.options`](# "tornado.options") module's new callbacksupport now makes it easy to add options from a wrapper scriptinstead of putting all possible options in [`tornado.testing.main`](# "tornado.testing.main").
- [`AsyncHTTPTestCase`](# "tornado.testing.AsyncHTTPTestCase") no longer calls [`AsyncHTTPClient.close`](# "tornado.httpclient.AsyncHTTPClient.close") for teststhat use the singleton [`IOLoop.instance`](# "tornado.ioloop.IOLoop.instance").
- [`LogTrapTestCase`](# "tornado.testing.LogTrapTestCase") no longer fails when run in unknown loggingconfigurations. This allows tests to be run under nose, which does itsown log buffering ([`LogTrapTestCase`](# "tornado.testing.LogTrapTestCase") doesn't do anything useful in thiscase, but at least it doesn't break things any more).
#### `tornado.util`
- `tornado.util.b` (which was only intended for internal use) is gone.
#### [`tornado.web`](# "tornado.web")
- [`RequestHandler.set_header`](# "tornado.web.RequestHandler.set_header") now overwrites previous header valuescase-insensitively.
- [`tornado.web.RequestHandler`](# "tornado.web.RequestHandler") has new attributes `path_args` and`path_kwargs`, which contain the positional and keyword argumentsthat are passed to the `get`/`post`/etc method. These attributesare set before those methods are called, so they are available during`prepare()`
- [`tornado.web.ErrorHandler`](# "tornado.web.ErrorHandler") no longer requires XSRF tokens on `POST`requests, so posts to an unknown url will always return 404 instead ofcomplaining about XSRF tokens.
- Several methods related to HTTP status codes now take a `reason` keywordargument to specify an alternate “reason” string (i.e. the “Not Found” in“HTTP/1.1 404 Not Found”). It is now possible to set status codes otherthan those defined in the spec, as long as a reason string is given.
- The `Date` HTTP header is now set by default on all responses.
- `Etag`/`If-None-Match` requests now work with [`StaticFileHandler`](# "tornado.web.StaticFileHandler").
- [`StaticFileHandler`](# "tornado.web.StaticFileHandler") no longer sets `Cache-Control: public` unnecessarily.
- When gzip is enabled in a [`tornado.web.Application`](# "tornado.web.Application"), appropriate`Vary: Accept-Encoding` headers are now sent.
- It is no longer necessary to pass all handlers for a host in a single[`Application.add_handlers`](# "tornado.web.Application.add_handlers") call. Now the request will be matchedagainst the handlers for any `host_pattern` that includes the request's`Host` header.
#### [`tornado.websocket`](# "tornado.websocket")
- Client-side WebSocket support is now available:[`tornado.websocket.websocket_connect`](# "tornado.websocket.websocket_connect")
- [`WebSocketHandler`](# "tornado.websocket.WebSocketHandler") has new methods [`ping`](# "tornado.websocket.WebSocketHandler.ping") and[`on_pong`](# "tornado.websocket.WebSocketHandler.on_pong") to send pings to the browser (notsupported on the `draft76` protocol)
© Copyright 2009-2016, The Tornado Authors. Created using [Sphinx](http://sphinx-doc.org/) 1.3.5.
- User's guide
- Introduction
- Asynchronous and non-Blocking I/O
- Coroutines
- Queue example - a concurrent web spider
- Structure of a Tornado web application
- Templates and UI
- Authentication and security
- Running and deploying
- Web framework
- tornado.web — RequestHandler and Application classes
- tornado.template — Flexible output generation
- tornado.escape — Escaping and string manipulation
- tornado.locale — Internationalization support
- tornado.websocket — Bidirectional communication to the browser
- HTTP servers and clients
- tornado.httpserver — Non-blocking HTTP server
- tornado.httpclient — Asynchronous HTTP client
- tornado.httputil — Manipulate HTTP headers and URLs
- tornado.http1connection – HTTP/1.x client/server implementation
- Asynchronous networking
- tornado.ioloop — Main event loop
- tornado.iostream — Convenient wrappers for non-blocking sockets
- tornado.netutil — Miscellaneous network utilities
- tornado.tcpclient — IOStream connection factory
- tornado.tcpserver — Basic IOStream-based TCP server
- Coroutines and concurrency
- tornado.gen — Simplify asynchronous code
- tornado.concurrent — Work with threads and futures
- tornado.locks – Synchronization primitives
- tornado.queues – Queues for coroutines
- tornado.process — Utilities for multiple processes
- Integration with other services
- tornado.auth — Third-party login with OpenID and OAuth
- tornado.wsgi — Interoperability with other Python frameworks and servers
- tornado.platform.asyncio — Bridge between asyncio and Tornado
- tornado.platform.caresresolver — Asynchronous DNS Resolver using C-Ares
- tornado.platform.twisted — Bridges between Twisted and Tornado
- Utilities
- tornado.autoreload — Automatically detect code changes in development
- tornado.log — Logging support
- tornado.options — Command-line parsing
- tornado.stack_context — Exception handling across asynchronous callbacks
- tornado.testing — Unit testing support for asynchronous code
- tornado.util — General-purpose utilities
- Frequently Asked Questions
- Release notes
- What's new in Tornado 4.3
- What's new in Tornado 4.2.1
- What's new in Tornado 4.2
- What's new in Tornado 4.1
- What's new in Tornado 4.0.2
- What's new in Tornado 4.0.1
- What's new in Tornado 4.0
- What's new in Tornado 3.2.2
- What's new in Tornado 3.2.1
- What's new in Tornado 3.2
- What's new in Tornado 3.1.1
- What's new in Tornado 3.1
- What's new in Tornado 3.0.2
- What's new in Tornado 3.0.1
- What's new in Tornado 3.0
- What's new in Tornado 2.4.1
- What's new in Tornado 2.4
- What's new in Tornado 2.3
- What's new in Tornado 2.2.1
- What's new in Tornado 2.2
- What's new in Tornado 2.1.1
- What's new in Tornado 2.1
- What's new in Tornado 2.0
- What's new in Tornado 1.2.1
- What's new in Tornado 1.2
- What's new in Tornado 1.1.1
- What's new in Tornado 1.1
- What's new in Tornado 1.0.1
- What's new in Tornado 1.0