What’s new in Tornado 3.0¶
Mar 29, 2013¶
Highlights¶
- The
callbackargument to many asynchronous methods is now optional, and these methods return aFuture. Thetornado.genmodule now understandsFutures, and these methods can be used directly without agen.Taskwrapper. - New function
IOLoop.currentreturns theIOLoopthat is running on the current thread (as opposed toIOLoop.instance, which returns a specific thread’s (usually the main thread’s) IOLoop. - New class
tornado.netutil.Resolverprovides an asynchronous interface to DNS resolution. The default implementation is still blocking, but non-blocking implementations are available using one of three optional dependencies:ThreadedResolverusing theconcurrent.futuresthread pool,tornado.platform.caresresolver.CaresResolverusing thepycareslibrary, ortornado.platform.twisted.TwistedResolverusingtwisted - Tornado’s logging is now less noisy, and it no longer goes directly to the root logger, allowing for finer-grained configuration.
- New class
tornado.process.Subprocesswrapssubprocess.PopenwithPipeIOStreamaccess to the child’s file descriptors. IOLoopnow has a staticconfiguremethod like the one onAsyncHTTPClient, which can be used to select anIOLoopimplementation other than the default.IOLoopcan 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 single
codebase instead of using
2to3 - The
tornado.databasemodule has been removed. It is now available as a separate package, torndb - Functions that take an
io_loopparameter now default toIOLoop.current()instead ofIOLoop.instance(). - Empty HTTP request arguments are no longer ignored. This applies to
HTTPRequest.argumentsandRequestHandler.get_argument[s]in WSGI and non-WSGI modes. - On Python 3,
tornado.escape.json_encodeno longer accepts byte strings. - On Python 3, the
get_authenticated_usermethods intornado.authnow return character strings instead of byte strings. tornado.netutil.TCPServerhas moved to its own module,tornado.tcpserver.- The Tornado test suite now requires
unittest2when run on Python 2.6. tornado.options.optionsis no longer a subclass ofdict; attribute-style access is now required.
Detailed changes by module¶
Multiple modules¶
- Tornado no longer logs to the root logger. Details on the new logging
scheme can be found under the
tornado.logmodule. Note that in some cases this will require that you add an explicit logging configuration in order to see any output (perhaps just callinglogging.basicConfig()), although bothIOLoop.start()andtornado.options.parse_command_linewill do this for you. - On python 3.2+, methods that take an
ssl_optionsargument (onSSLIOStream,TCPServer, andHTTPServer) now accept either a dictionary of options or anssl.SSLContextobject. - New optional dependency on
concurrent.futuresto provide better support for working with threads.concurrent.futuresis in the standard library for Python 3.2+, and can be installed on older versions withpip install futures.
tornado.autoreload¶
tornado.autoreloadis now more reliable when there are errors at import time.- Calling
tornado.autoreload.start(or creating anApplicationwithdebug=True) twice on the sameIOLoopnow does nothing (instead of creating multiple periodic callbacks). Starting autoreload on more than oneIOLoopin the same process now logs a warning. - Scripts run by autoreload no longer inherit
__future__imports used by Tornado.
tornado.auth¶
- On Python 3, the
get_authenticated_usermethod family now returns character strings instead of byte strings. - Asynchronous methods defined in
tornado.authnow return aFuture, and theircallbackargument is optional. TheFutureinterface is preferred as it offers better error handling (the previous interface just logged a warning and returned None). - The
tornado.authmixin classes now define a methodget_auth_http_client, which can be overridden to use a non-defaultAsyncHTTPClientinstance (e.g. to use a differentIOLoop) - Subclasses of
OAuthMixinare encouraged to overrideOAuthMixin._oauth_get_user_futureinstead of_oauth_get_user, although both methods are still supported.
tornado.concurrent¶
- New module
tornado.concurrentcontains code to support working withconcurrent.futures, or to emulate future-based interface when that module is not available.
tornado.curl_httpclient¶
- Preliminary support for
tornado.curl_httpclienton Python 3. The latest official release of pycurl only supports Python 2, but Ubuntu has a port available in 12.10 (apt-get install python3-pycurl). This port currently has bugs that prevent it from handling arbitrary binary data but it should work for textual (utf8) resources. - Fix a crash with libcurl 7.29.0 if a curl object is created and closed without being used.
tornado.escape¶
- On Python 3,
json_encodeno longer accepts byte strings. This mirrors the behavior of the underlying json module. Python 2 behavior is unchanged but should be faster.
tornado.gen¶
- New decorator
@gen.coroutineis available as an alternative to@gen.engine. It automatically returns aFuture, and within the function instead of calling a callback you return a value withraise gen.Return(value)(or simplyreturn valuein Python 3.3). - Generators may now yield
Futureobjects. - Callbacks produced by
gen.Callbackandgen.Taskare now automatically stack-context-wrapped, to minimize the risk of context leaks when used with asynchronous functions that don’t do their own wrapping. - Fixed a memory leak involving generators,
RequestHandler.flush, and clients closing connections while output is being written. - Yielding a large list no longer has quadratic performance.
tornado.httpclient¶
AsyncHTTPClient.fetchnow returns aFutureand its callback argument is optional. When the future interface is used, any error will be raised automatically, as ifHTTPResponse.rethrowwas called.AsyncHTTPClient.configureand allAsyncHTTPClientconstructors now take adefaultskeyword argument. This argument should be a dictionary, and its values will be used in place of corresponding attributes ofHTTPRequestthat are not set.- All unset attributes of
tornado.httpclient.HTTPRequestare nowNone. The default values of some attributes (connect_timeout,request_timeout,follow_redirects,max_redirects,use_gzip,proxy_password,allow_nonstandard_methods, andvalidate_certhave been moved fromHTTPRequestto the client implementations. - The
max_clientsargument toAsyncHTTPClientis now a keyword-only argument. - Keyword arguments to
AsyncHTTPClient.configureare no longer used when instantiating an implementation subclass directly. - Secondary
AsyncHTTPClientcallbacks (streaming_callback,header_callback, andprepare_curl_callback) now respectStackContext.
tornado.httpserver¶
HTTPServerno longer logs an error when it is unable to read a second request from an HTTP 1.1 keep-alive connection.HTTPServernow takes aprotocolkeyword argument which can be set tohttpsif the server is behind an SSL-decoding proxy that does not set any supported X-headers.tornado.httpserver.HTTPConnectionnow has aset_close_callbackmethod that should be used instead of reaching into itsstreamattribute.- Empty HTTP request arguments are no longer ignored. This applies to
HTTPRequest.argumentsandRequestHandler.get_argument[s]in WSGI and non-WSGI modes.
tornado.ioloop¶
- New function
IOLoop.currentreturns theIOLoopthat is running on the current thread (as opposed toIOLoop.instance, which returns a specific thread’s (usually the main thread’s) IOLoop). - New method
IOLoop.add_futureto run a callback on the IOLoop when an asynchronousFuturefinishes. IOLoopnow has a staticconfiguremethod like the one onAsyncHTTPClient, which can be used to select anIOLoopimplementation other than the default.- The
IOLooppoller implementations (select,epoll,kqueue) are now available as distinct subclasses ofIOLoop. InstantiatingIOLoopwill continue to automatically choose the best available implementation. - The
IOLoopconstructor has a new keyword argumenttime_func, which can be used to set the time function used when scheduling callbacks. This is most useful with thetime.monotonicfunction, introduced in Python 3.3 and backported to older versions via themonotimemodule. Using a monotonic clock here avoids problems when the system clock is changed. - New function
IOLoop.timereturns the current time according to the IOLoop. To use the new monotonic clock functionality, all calls toIOLoop.add_timeoutmust be either pass adatetime.timedeltaor a time relative toIOLoop.time, nottime.time. (time.timewill continue to work only as long as the IOLoop’stime_funcargument is not used). - New convenience method
IOLoop.run_synccan be used to start an IOLoop just long enough to run a single coroutine. - New method
IOLoop.add_callback_from_signalis safe to use in a signal handler (the regularadd_callbackmethod may deadlock). IOLoopnow usessignal.set_wakeup_fdwhere available (Python 2.6+ on Unix) to avoid a race condition that could result in Python signal handlers being delayed.- Method
IOLoop.running()has been removed. IOLoophas been refactored to better support subclassing.IOLoop.add_callbackandadd_callback_from_signalnow take*args, **kwargsto pass along to the callback.
tornado.iostream¶
IOStream.connectnow has an optionalserver_hostnameargument which will be used for SSL certificate validation when applicable. Additionally, when supported (on Python 3.2+), this hostname will be sent via SNI (and this is supported bytornado.simple_httpclient)- Much of
IOStreamhas been refactored into a separate classBaseIOStream. - New class
tornado.iostream.PipeIOStreamprovides the IOStream interface on pipe file descriptors. IOStreamnow raises a new exceptiontornado.iostream.StreamClosedErrorwhen you attempt to read or write after the stream has been closed (by either side).IOStreamnow simply closes the connection when it gets anECONNRESETerror, rather than logging it as an error.IOStream.errorno longer picks up unrelated exceptions.BaseIOStream.closenow has anexc_infoargument (similar to the one used in theloggingmodule) that can be used to set the stream’serrorattribute when closing it.BaseIOStream.read_until_closenow works correctly when it is called while there is buffered data.- Fixed a major performance regression when run on PyPy (introduced in Tornado 2.3).
tornado.log¶
- New module containing
enable_pretty_loggingandLogFormatter, moved from the options module. LogFormatternow handles non-ascii data in messages and tracebacks better.
tornado.netutil¶
- New class
tornado.netutil.Resolverprovides an asynchronous interface to DNS resolution. The default implementation is still blocking, but non-blocking implementations are available using one of three optional dependencies:ThreadedResolverusing theconcurrent.futuresthread pool,tornado.platform.caresresolver.CaresResolverusing thepycareslibrary, ortornado.platform.twisted.TwistedResolverusingtwisted - New function
tornado.netutil.is_valid_ipreturns true if a given string is a valid IP (v4 or v6) address. tornado.netutil.bind_socketshas a newflagsargument that can be used to pass additional flags togetaddrinfo.tornado.netutil.bind_socketsno longer setsAI_ADDRCONFIG; this will cause it to bind to both ipv4 and ipv6 more often than before.tornado.netutil.bind_socketsnow works when Python was compiled with--disable-ipv6but IPv6 DNS resolution is available on the system.tornado.netutil.TCPServerhas moved to its own module,tornado.tcpserver.
tornado.options¶
- The class underlying the functions in
tornado.optionsis now public (tornado.options.OptionParser). This can be used to create multiple independent option sets, such as for subcommands. tornado.options.parse_config_filenow configures logging automatically by default, in the same way thatparse_command_linedoes.- New function
tornado.options.add_parse_callbackschedules a callback to be run after the command line or config file has been parsed. The keyword argumentfinal=Falsecan be used on either parsing function to supress these callbacks. tornado.options.definenow takes acallbackargument. This callback will be run with the new value whenever the option is changed. This is especially useful for options that set other options, such as by reading from a config file.tornado.options.parse_command_line--helpoutput now goes tostderrrather thanstdout.tornado.options.optionsis no longer a subclass ofdict; attribute-style access is now required.tornado.options.options(andOptionParserinstances generally) now have amockable()method that returns a wrapper object compatible withmock.patch.- Function
tornado.options.enable_pretty_logginghas been moved to thetornado.logmodule.
tornado.platform.caresresolver¶
- New module containing an asynchronous implementation of the
Resolverinterface, using thepycareslibrary.
tornado.platform.twisted¶
- New class
tornado.platform.twisted.TwistedIOLoopallows Tornado code to be run on the Twisted reactor (as opposed to the existingTornadoReactor, which bridges the gap in the other direction). - New class
tornado.platform.twisted.TwistedResolveris an asynchronous implementation of theResolverinterface.
tornado.process¶
- New class
tornado.process.Subprocesswrapssubprocess.PopenwithPipeIOStreamaccess to the child’s file descriptors.
tornado.simple_httpclient¶
SimpleAsyncHTTPClientnow takes aresolverkeyword argument (which may be passed to either the constructor orconfigure), to allow it to use the new non-blockingtornado.netutil.Resolver.- When following redirects,
SimpleAsyncHTTPClientnow treats a 302 response code the same as a 303. This is contrary to the HTTP spec but consistent with all browsers and other major HTTP clients (includingCurlAsyncHTTPClient). - The behavior of
header_callbackwithSimpleAsyncHTTPClienthas changed and is now the same as that ofCurlAsyncHTTPClient. The header callback now receives the first line of the response (e.g.HTTP/1.0 200 OK) and the final empty line. tornado.simple_httpclientnow accepts responses with a 304 status code that include aContent-Lengthheader.- Fixed a bug in which
SimpleAsyncHTTPClientcallbacks were being run in the client’sstack_context.
tornado.stack_context¶
stack_context.wrapnow runs the wrapped callback in a more consistent environment by recreating contexts even if they already exist on the stack.- Fixed a bug in which stack contexts could leak from one callback chain to another.
- Yield statements inside a
withstatement can cause stack contexts to become inconsistent; an exception will now be raised when this case is detected.
tornado.template¶
- Errors while rendering templates no longer log the generated code, since the enhanced stack traces (from version 2.1) should make this unnecessary.
- The
{% apply %}directive now works properly with functions that return both unicode strings and byte strings (previously only byte strings were supported). - Code in templates is no longer affected by Tornado’s
__future__imports (which previously includedabsolute_importanddivision).
tornado.testing¶
- New function
tornado.testing.bind_unused_portboth chooses a port and binds a socket to it, so there is no risk of another process using the same port.get_unused_portis now deprecated. - New decorator
tornado.testing.gen_testcan be used to allow for yieldingtornado.genobjects in tests, as an alternative to thestopandwaitmethods ofAsyncTestCase. tornado.testing.AsyncTestCaseand friends now extendunittest2.TestCasewhen it is available (and continue to use the standardunittestmodule whenunittest2is not available)tornado.testing.ExpectLogcan be used as a finer-grained alternative totornado.testing.LogTrapTestCase- The command-line interface to
tornado.testing.mainnow supports additional arguments from the underlyingunittestmodule:verbose,quiet,failfast,catch,buffer. - The deprecated
--autoreloadoption oftornado.testing.mainhas been removed. Usepython -m tornado.autoreloadas a prefix command instead. - The
--httpclientoption oftornado.testing.mainhas been moved totornado.test.runtestsso as not to pollute the application option namespace. Thetornado.optionsmodule’s new callback support now makes it easy to add options from a wrapper script instead of putting all possible options intornado.testing.main. AsyncHTTPTestCaseno longer callsAsyncHTTPClient.closefor tests that use the singletonIOLoop.instance.LogTrapTestCaseno longer fails when run in unknown logging configurations. This allows tests to be run under nose, which does its own log buffering (LogTrapTestCasedoesn’t do anything useful in this case, 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¶
RequestHandler.set_headernow overwrites previous header values case-insensitively.tornado.web.RequestHandlerhas new attributespath_argsandpath_kwargs, which contain the positional and keyword arguments that are passed to theget/post/etc method. These attributes are set before those methods are called, so they are available duringprepare()tornado.web.ErrorHandlerno longer requires XSRF tokens onPOSTrequests, so posts to an unknown url will always return 404 instead of complaining about XSRF tokens.- Several methods related to HTTP status codes now take a
reasonkeyword argument 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 other than those defined in the spec, as long as a reason string is given. - The
DateHTTP header is now set by default on all responses. Etag/If-None-Matchrequests now work withStaticFileHandler.StaticFileHandlerno longer setsCache-Control: publicunnecessarily.- When gzip is enabled in a
tornado.web.Application, appropriateVary: Accept-Encodingheaders are now sent. - It is no longer necessary to pass all handlers for a host in a single
Application.add_handlerscall. Now the request will be matched against the handlers for anyhost_patternthat includes the request’sHostheader.
tornado.websocket¶
- Client-side WebSocket support is now available:
tornado.websocket.websocket_connect WebSocketHandlerhas new methodspingandon_pongto send pings to the browser (not supported on thedraft76protocol)