Wiki

Clone wiki

CherryPy / UpgradeTo32

How to upgrade to CherryPy 3.2

This page discusses changes between CherryPy 3.1 (June 2008) and 3.2 (October 2009) which might require you to modify your code when you upgrade. Bugfixes aren't listed here. See also [wiki:WhatsNewIn32 WhatsNewIn32].

Response encoding

CherryPy 3.1 allowed the `response.body` to be either bytes or unicode (or a list/file/generator of such). If you returned unicode from your page handler, you could use `tools.encode` (during the `before_finalize` hook point) to convert it to bytes before yielding it to WSGI middleware and eventually the server. This left a "limbo period" of time between the page handler and the encode Tool during which `response.body` could be either bytes or unicode.

CherryPy 3.2 includes support for Python 3, which makes the distinction between byte strings and unicode strings much more pronounced, so much so that we felt continuing to handle both types of output would be too difficult. In order to remove the "limbo period" between page handler output and the `finalize` step, '''we now require `response.body` to be bytes, not unicode'''. And rather than maintain radically different semantics between the Python 2 and Python 3 versions of CherryPy, we decided to follow this requirement in both versions.

However, we'd still like to be able to return unicode from page handlers. Therefore, the `encode` tool has moved from the `before_finalize` hook to the `before_handler` hook, and now wraps the page handler, encoding the output before it is stored as `response.body`.

'''Any scheme which expects page handler output to be anything other than a bytestring, list of bytestrings, file, or generator MUST follow suit.''' There will be no more "limbo period" before finalize where `response.body` can be a dict, template object, or any other value. It should always have been this way; doing otherwise can break Tools which do not understand the custom type. If your code does this sort of thing, move that logic from the `before_finalize` hookpoint to `before_handler` (or even earlier, if you like), wrap the page handler, and do the transformation there before returning control to the core. That is, given an arbitrary `transform` step that ran at `before_finalize`, change it from:

def transform(...):
    cherrypy.response.body = munge(cherrypy.response.body)
cherrypy.tools.transform = cherrypy.Tool('before_finalize', transform)

to:

def transform(...):
    old_handler = cherrypy.request.handler
    def wrapper(*args, **kwargs):
        return munge(old_handler(*args, **kwargs))
    cherrypy.request.handler = wrapper
cherrypy.tools.transform = cherrypy.Tool('before_handler', transform)

lib.http

`lib.http` has been renamed to `lib.httputil` to avoid colliding with the new `http` module in Python 3. In the Python 2 version of CherryPy, you can still use the old module name until CherryPy 3.3.

Uploaded file Content-Type

Previous versions of CherryPy passed uploaded files to page handlers like so:

    def upload(self, myFile):
        save(myFile, somewhere, type=myFile.type)
    upload.exposed = True

That approach is still valid; however, the "type" attribute is deprecated, and will be removed in CherryPy 3.3. The new attribute name is "content_type", which you can start to use in CherryPy 3.2.

Logging

As discussed in #866, the log.screen handler for the access log has been directed to stdout again. The error log remains on stderr.

Also, the error log has been adjusted from the `DEBUG` level to the `INFO` level, which should cut down on some extraneous messages for most systems. If you depend on logging DEBUG messages, you will need to set the level back to DEBUG.

cherrypy._cpwsgi_server

The constructor for _cpwsgi_server.CPWSGIServer now takes a 'server_adapter' argument. If you have a custom subclass of this class, you should follow suit.

Test suite

We've switched from using unittest exclusively, and are now using `nose` throughout. Just `easy_install nose` and run `nosetests -s -v cherrypy/test`.

The test suite has also been reworked to start `cherrypy.engine` once per module, and only for modules that have a 'setup_server' function. This allows us to exercise modules which do not need to start a server at every full run. For example, test_bus and test_states are now included. If you had been re-using CherryPy's test suite for your own applications, you may need to alter your test code to match. See [2112].

Engine/Bus

When errors occur during bus.publish (which includes engine.start/stop, etc), CherryPy 3.1 would re-raise the last such error after calling all subscribed listeners. In CherryPy 3.2, the bus raises a new `ChannelFailures` exception instead, with references to each failure.

Server

`cherrypy.server.quickstart` was deprecated in 3.1, and has been removed in 3.2.

Tools

The `wsgiapp` Tool was deprecated in 3.1, and has been removed in 3.2. In addition, the `tidy` and `nsgmls` Tools have been removed from the standard distribution to http://tools.cherrypy.org/browser

wsgiserver

The `wsgiserver` subpackage has been substantially reworked to be more extensible. Specifically, SSL support is no longer contained within `init.py`, since we now distribute modules for both builtin Python SSL and pyOpenSSL.

In addition, much of the internals of `CherryPyWSGIServer`, `HTTPConnection`, and `HTTPRequest` has changed from WSGI 1.0 data types to a new, internal format which is closer to HTTP; these data structures are now transformed to WSGI via new `wsgiserver.Gateway` classes.

If you monkeypatched or subclassed nearly anything in wsgiserver, you will most likely have to re-analyze/re-implement those changes for CherryPy 3.2.

Updated