summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Crooks <allan@amcone.net>2014-04-16 14:25:24 -0400
committerAllan Crooks <allan@amcone.net>2014-04-16 14:25:24 -0400
commit100f8c38910cf72f90a6078559bed35ee38413df (patch)
treedcd35f47c23841726c258ea9aa42ed26e4e3a6c8
parent6ab8f5e77f3ed262c20677ef10c085f6b71d7ac4 (diff)
downloadcherrypy-100f8c38910cf72f90a6078559bed35ee38413df.tar.gz
Fix for recent commits which were causing a number of tests to fail in Python 3.
-rw-r--r--cherrypy/_cperror.py17
-rw-r--r--cherrypy/lib/encoding.py21
-rw-r--r--cherrypy/test/helper.py9
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)