diff options
author | Allan Crooks <allan@amcone.net> | 2014-04-16 14:25:24 -0400 |
---|---|---|
committer | Allan Crooks <allan@amcone.net> | 2014-04-16 14:25:24 -0400 |
commit | 100f8c38910cf72f90a6078559bed35ee38413df (patch) | |
tree | dcd35f47c23841726c258ea9aa42ed26e4e3a6c8 | |
parent | 6ab8f5e77f3ed262c20677ef10c085f6b71d7ac4 (diff) | |
download | cherrypy-100f8c38910cf72f90a6078559bed35ee38413df.tar.gz |
Fix for recent commits which were causing a number of tests to fail in Python 3.
-rw-r--r-- | cherrypy/_cperror.py | 17 | ||||
-rw-r--r-- | cherrypy/lib/encoding.py | 21 | ||||
-rw-r--r-- | cherrypy/test/helper.py | 9 |
3 files changed, 42 insertions, 5 deletions
diff --git a/cherrypy/_cperror.py b/cherrypy/_cperror.py index bc556ab9..6256595b 100644 --- a/cherrypy/_cperror.py +++ b/cherrypy/_cperror.py @@ -503,7 +503,21 @@ def get_error_page(status, **kwargs): # The caller function may be setting headers manually, # so we delegate to it completely. We may be returning # an iterator as well as a string here. - return error_page(**kwargs) + # + # We *must* make sure any content is not unicode. + result = error_page(**kwargs) + if cherrypy.lib.is_iterator(result): + from cherrypy.lib.encoding import UTF8StreamEncoder + return UTF8StreamEncoder(result) + elif isinstance(result, cherrypy._cpcompat.unicodestr): + return result.encode('utf-8') + else: + if not isinstance(result, cherrypy._cpcompat.bytestr): + raise ValueError('error page function did not ' + 'return a bytestring, unicodestring or an ' + 'iterator - returned object of type %s.' + % (type(result).__name__)) + return result else: # Load the template from this path. template = tonative(open(error_page, 'rb').read()) @@ -521,6 +535,7 @@ def get_error_page(status, **kwargs): return result.encode('utf-8') + _ie_friendly_error_sizes = { 400: 512, 403: 256, 404: 512, 405: 256, 406: 512, 408: 512, 409: 512, 410: 256, diff --git a/cherrypy/lib/encoding.py b/cherrypy/lib/encoding.py index 59ae3b15..6d54ac8c 100644 --- a/cherrypy/lib/encoding.py +++ b/cherrypy/lib/encoding.py @@ -32,6 +32,27 @@ def decode(encoding=None, default_encoding='utf-8'): if not isinstance(default_encoding, list): default_encoding = [default_encoding] body.attempt_charsets = body.attempt_charsets + default_encoding + +class UTF8StreamEncoder: + def __init__(self, iterator): + self._iterator = iterator + + def __iter__(self): + return self + + def next(self): + return self.__next__() + + def __next__(self): + res = next(self._iterator) + if isinstance(res, unicodestr): + res = res.encode('utf-8') + return res + + def __getattr__(self, attr): + if attr.startswith('__'): + raise AttributeError(self, attr) + return getattr(self._iterator, attr) class ResponseEncoder: diff --git a/cherrypy/test/helper.py b/cherrypy/test/helper.py index a76abce3..b6ed3277 100644 --- a/cherrypy/test/helper.py +++ b/cherrypy/test/helper.py @@ -365,12 +365,13 @@ class CPWebCase(webtest.WebCase): # First, test the response body without checking the traceback. # Stick a match-all group (.*) in to grab the traceback. - esc = re.escape - epage = esc(page) + def esc(text): + return re.escape(ntob(text)) + epage = re.escape(page) epage = epage.replace( esc('<pre id="traceback"></pre>'), - esc('<pre id="traceback">') + '(.*)' + esc('</pre>')) - m = re.match(ntob(epage, self.encoding), self.body, re.DOTALL) + esc('<pre id="traceback">') + ntob('(.*)') + esc('</pre>')) + m = re.match(epage, self.body, re.DOTALL) if not m: self._handlewebError( 'Error page does not match; expected:\n' + page) |