Commits

Robert Brewer  committed 16b6649

MOAR sync between py2/py3

  • Participants
  • Parent commits 0dcaff0

Comments (0)

Files changed (26)

File py2/cherrypy/_cpcompat.py

 import sys
 
 if sys.version_info >= (3, 0):
+    py3k = True
     bytestr = bytes
     unicodestr = str
     nativestr = unicodestr
     from io import BytesIO as BytesIO
 else:
     # Python 2
+    py3k = False
     bytestr = str
     unicodestr = unicode
     nativestr = bytestr
     json_decode = json.JSONDecoder().decode
     json_encode = json.JSONEncoder().iterencode
 except ImportError:
-    if sys.version_info >= (3, 0):
+    if py3k:
         # Python 3.0: json is part of the standard library,
         # but outputs unicode. We need bytes.
         import json

File py2/cherrypy/_cplogging.py

 logfmt = logging.Formatter("%(message)s")
 import os
 import sys
-_py3k = (sys.version_info >= (3, 0))
 
 import cherrypy
 from cherrypy import _cperror
-from cherrypy._cpcompat import ntob
+from cherrypy._cpcompat import ntob, py3k
 
 
 class LogManager(object):
     access_log = None
     """The actual :class:`logging.Logger` instance for access messages."""
     
-    if _py3k:
+    if py3k:
         access_log_format = \
             '{h} {l} {u} {t} "{r}" {s} {b} "{f}" "{a}"'
     else:
             status = "-"
         else:
             status = response.output_status.split(ntob(" "), 1)[0]
-            if _py3k:
+            if py3k:
                 status = status.decode('ISO-8859-1')
         
         atoms = {'h': remote.name or remote.ip,
                  'f': dict.get(inheaders, 'Referer', ''),
                  'a': dict.get(inheaders, 'User-Agent', ''),
                  }
-        if _py3k:
+        if py3k:
             for k, v in atoms.items():
                 if not isinstance(v, str):
                     v = str(v)

File py2/cherrypy/_cprequest.py

 
 import cherrypy
 from cherrypy._cpcompat import basestring, copykeys, ntob, unicodestr
-from cherrypy._cpcompat import SimpleCookie, CookieError
+from cherrypy._cpcompat import SimpleCookie, CookieError, py3k
 from cherrypy import _cpreqbody, _cpconfig
 from cherrypy._cperror import format_exc, bare_error
 from cherrypy.lib import httputil, file_generator
                 self.query_string_encoding)
         
         # Python 2 only: keyword arguments must be byte strings (type 'str').
-        if sys.version_info < (3, 0):
+        if not py3k:
             for key, value in p.items():
                 if isinstance(key, unicode):
                     del p[key]
     :attr:`request.body.params<cherrypy._cprequest.RequestBody.params>`.""")
 
 
-_py3k = (sys.version_info >= (3, 0))
-
 class ResponseBody(object):
     """The body of the HTTP response (the response entity)."""
     
-    if _py3k:
+    if py3k:
         unicode_err = ("Page handlers MUST return bytes. Use tools.encode "
                        "if you wish to return unicode.")
     
     
     def __set__(self, obj, value):
         # Convert the given value to an iterable object.
-        if _py3k and isinstance(value, str):
+        if py3k and isinstance(value, str):
             raise ValueError(self.unicode_err)
         
         if isinstance(value, basestring):
             else:
                 # [''] doesn't evaluate to False, so replace it with [].
                 value = []
-        elif _py3k and isinstance(value, list):
+        elif py3k and isinstance(value, list):
             # every item in a list must be bytes... 
             for i, item in enumerate(value):
                 if isinstance(item, str):
         
         newbody = []
         for chunk in self.body:
-            if _py3k and not isinstance(chunk, bytes):
+            if py3k and not isinstance(chunk, bytes):
                 raise TypeError("Chunk %s is not of type 'bytes'." % repr(chunk))
             newbody.append(chunk)
         newbody = ntob('').join(newbody)

File py2/cherrypy/_cpserver.py

 
 import cherrypy
 from cherrypy.lib import attributes
-from cherrypy._cpcompat import basestring
+from cherrypy._cpcompat import basestring, py3k
 
 # We import * because we want to export check_port
 # et al as attributes of this module.
     ssl_private_key = None
     """The filename of the private key to use with SSL."""
     
-    if sys.version_info >= (3, 0):
+    if py3k:
         ssl_module = 'builtin'
         """The name of a registered SSL adaptation module to use with the builtin
         WSGI server. Builtin options are: 'builtin' (to use the SSL library built

File py2/cherrypy/_cptree.py

 import sys
 
 import cherrypy
-from cherrypy._cpcompat import ntou
+from cherrypy._cpcompat import ntou, py3k
 from cherrypy import _cpconfig, _cplogging, _cprequest, _cpwsgi, tools
 from cherrypy.lib import httputil
 
         
         # Correct the SCRIPT_NAME and PATH_INFO environ entries.
         environ = environ.copy()
-        if sys.version_info < (3, 0):
+        if not py3k:
             if environ.get(ntou('wsgi.version')) == (ntou('u'), 0):
                 # Python 2/WSGI u.0: all strings MUST be of type unicode
                 enc = environ[ntou('wsgi.url_encoding')]

File py2/cherrypy/_cpwsgi.py

 import sys as _sys
 
 import cherrypy as _cherrypy
-from cherrypy._cpcompat import BytesIO, ntob, ntou, unicodestr
+from cherrypy._cpcompat import BytesIO, ntob, ntou, py3k, unicodestr
 from cherrypy import _cperror
 from cherrypy.lib import httputil
 
         self.started_response = True
         return self
     
-    if _sys.version_info >= (3, 0):
+    if py3k:
         def __next__(self):
             return self.trap(next, self.iter_response)
     else:
     """WSGI response iterable for CherryPy applications."""
     
     def __init__(self, environ, start_response, cpapp):
-        if _sys.version_info < (3, 0):
+        if not py3k:
             if environ.get(ntou('wsgi.version')) == (ntou('u'), 0):
                 environ = downgrade_wsgi_ux_to_1x(environ)
         self.environ = environ
     def __iter__(self):
         return self
     
-    if _sys.version_info >= (3, 0):
+    if py3k:
         def __next__(self):
             return next(self.iter_response)
     else:
                                 self.environ.get('PATH_INFO', ''))
         qs = self.environ.get('QUERY_STRING', '')
 
-        if _sys.version_info >= (3, 0):
+        if py3k:
             # This isn't perfect; if the given PATH_INFO is in the wrong encoding,
             # it may fail to match the appropriate config section URI. But meh.
             old_enc = self.environ.get('wsgi.url_encoding', 'ISO-8859-1')

File py2/cherrypy/test/test_dynamicobjectmapping.py

 
         def __unicode__(self):
             return unicode(self.name)
+        def __str__(self):
+            return str(self.name)
 
     user_lookup = {
         1: User(1, 'foo'),

File py2/cherrypy/test/test_etags.py

             def unicoded(self):
                 return u'I am a \u1ee4nicode string.'
             unicoded.exposed = True
+            # In Python 3, tools.encode is on by default
             unicoded._cp_config = {'tools.encode.on': True}
-
+        
         conf = {'/': {'tools.etags.on': True,
                       'tools.etags.autotags': True,
                       }}

File py2/cherrypy/test/test_request_obj.py

 localDir = os.path.dirname(__file__)
 import sys
 import types
-from cherrypy._cpcompat import IncompleteRead, ntob, unicodestr
+from cherrypy._cpcompat import IncompleteRead, ntob, ntou, unicodestr
 
 import cherrypy
 from cherrypy import _cptools, tools
                     if isinstance(value, types.FunctionType):
                         value.exposed = True
                 setattr(root, name.lower(), cls())
-        class Test(object):
-            __metaclass__ = TestType
-
+        Test = TestType('Test', (object,), {})
 
         class PathInfo(Test):
 
 
     def testParams(self):
         self.getPage("/params/?thing=a")
-        self.assertBody("u'a'")
+        self.assertBody(repr(ntou("a")))
         
         self.getPage("/params/?thing=a&thing=b&thing=c")
-        self.assertBody("[u'a', u'b', u'c']")
+        self.assertBody(repr([ntou('a'), ntou('b'), ntou('c')]))
 
         # Test friendly error message when given params are not accepted.
         cherrypy.config.update({"request.show_mismatched_params": True})

File py2/cherrypy/test/test_tools.py

 
 import gzip
 import sys
-from cherrypy._cpcompat import BytesIO, copyitems, itervalues, IncompleteRead, ntob, ntou, xrange
+from cherrypy._cpcompat import BytesIO, copyitems, itervalues
+from cherrypy._cpcompat import IncompleteRead, ntob, ntou, py3k, xrange
 import time
 timeout = 0.2
 import types
             def __call__(self, scale):
                 r = cherrypy.response
                 r.collapse_body()
-                r.body = [chr((ord(x) + scale) % 256) for x in r.body[0]]
+                if py3k:
+                    r.body = [bytes([(x + scale) % 256 for x in r.body[0]])]
+                else:
+                    r.body = [chr((ord(x) + scale) % 256) for x in r.body[0]]
         cherrypy.tools.rotator = cherrypy.Tool('before_finalize', Rotator())
         
         def stream_handler(next_handler, *args, **kwargs):
                     if isinstance(value, types.FunctionType):
                         value.exposed = True
                 setattr(root, name.lower(), cls())
-        class Test(object):
-            __metaclass__ = TestType
+        Test = TestType('Test', (object,), {})
         
         
         # METHOD ONE:
         # but it proves the priority was changed.
         self.getPage("/decorated_euro/subpath",
                      headers=[("Accept-Encoding", "gzip")])
-        self.assertInBody(''.join([chr((ord(x) + 3) % 256) for x in zbuf.getvalue()]))
+        if py3k:
+            self.assertInBody(bytes([(x + 3) % 256 for x in zbuf.getvalue()]))
+        else:
+            self.assertInBody(''.join([chr((ord(x) + 3) % 256) for x in zbuf.getvalue()]))
     
     def testBareHooks(self):
         content = "bit of a pain in me gulliver"

File py2/cherrypy/test/test_virtualhost.py

             dom4.exposed = True
             
             def method(self, value):
-                return "You sent %s" % repr(value)
+                return "You sent %s" % value
             method.exposed = True
         
         class VHost:
             index.exposed = True
             
             def vmethod(self, value):
-                return "You sent %s" % repr(value)
+                return "You sent %s" % value
             vmethod.exposed = True
             
             def url(self):
         
         # Test GET, POST, and positional params
         self.getPage("/method?value=root")
-        self.assertBody("You sent u'root'")
+        self.assertBody("You sent root")
         self.getPage("/vmethod?value=dom2+GET", [('Host', 'www.mydom2.com')])
-        self.assertBody("You sent u'dom2 GET'")
+        self.assertBody("You sent dom2 GET")
         self.getPage("/vmethod", [('Host', 'www.mydom3.com')], method="POST",
                      body="value=dom3+POST")
-        self.assertBody("You sent u'dom3 POST'")
+        self.assertBody("You sent dom3 POST")
         self.getPage("/vmethod/pos", [('Host', 'www.mydom3.com')])
-        self.assertBody("You sent 'pos'")
+        self.assertBody("You sent pos")
         
         # Test that cherrypy.url uses the browser url, not the virtual url
         self.getPage("/url", [('Host', 'www.mydom2.com')])

File py2/cherrypy/test/test_wsgiapps.py

+from cherrypy._cpcompat import ntob
 from cherrypy.test import helper
 
 
         import cherrypy
         
         def test_app(environ, start_response):
-            status = '200 OK'
-            response_headers = [('Content-type', 'text/plain')]
+            status = ntob('200 OK')
+            response_headers = [(ntob('Content-type'), ntob('text/plain'))]
             start_response(status, response_headers)
             output = ['Hello, world!\n',
                       'This is a wsgi app running within CherryPy!\n\n']
             keys.sort()
             for k in keys:
                 output.append('%s: %s\n' % (k,environ[k]))
-            return output
+            return [ntob(x, 'utf-8') for x in output]
         
         def test_empty_string_app(environ, start_response):
-            status = '200 OK'
-            response_headers = [('Content-type', 'text/plain')]
+            status = ntob('200 OK')
+            response_headers = [(ntob('Content-type'), ntob('text/plain'))]
             start_response(status, response_headers)
-            return ['Hello', '', ' ', '', 'world']
+            return [ntob('Hello'), ntob(''), ntob(' '), ntob(''), ntob('world')]
         
         
         class WSGIResponse(object):
             
             def next(self):
                 return self.iter.next()
+            def __next__(self):
+                return next(self.iter)
             
             def close(self):
                 if hasattr(self.appresults, "close"):
                         line = list(this.iter.next())
                         line.reverse()
                         return "".join(line)
+                    def __next__(this):
+                        line = list(next(this.iter))
+                        line.reverse()
+                        return bytes(line)
                 return Reverser(results)
         
         class Root:
             def index(self):
-                return "I'm a regular CherryPy page handler!"
+                return ntob("I'm a regular CherryPy page handler!")
             index.exposed = True
         
         

File py2/cherrypy/wsgiserver/ssl_builtin.py

 except ImportError:
     ssl = None
 
+try:
+    from _pyio import DEFAULT_BUFFER_SIZE
+except ImportError:
+    try:
+        from io import DEFAULT_BUFFER_SIZE
+    except ImportError:
+        DEFAULT_BUFFER_SIZE = -1
+
+import sys
+
 from cherrypy import wsgiserver
 
 
             s = ssl.wrap_socket(sock, do_handshake_on_connect=True,
                     server_side=True, certfile=self.certificate,
                     keyfile=self.private_key, ssl_version=ssl.PROTOCOL_SSLv23)
-        except ssl.SSLError, e:
+        except ssl.SSLError:
+            e = sys.exc_info()[1]
             if e.errno == ssl.SSL_ERROR_EOF:
                 # This is almost certainly due to the cherrypy engine
                 # 'pinging' the socket to assert it's connectable;
             }
         return ssl_environ
     
-    def makefile(self, sock, mode='r', bufsize=-1):
-        return wsgiserver.CP_fileobject(sock, mode, bufsize)
+    if sys.version_info >= (3, 0):
+        def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
+            return wsgiserver.CP_makefile(sock, mode, bufsize)
+    else:
+        def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
+            return wsgiserver.CP_fileobject(sock, mode, bufsize)
 

File py3/cherrypy/_cpcompat.py

 import sys
 
 if sys.version_info >= (3, 0):
+    py3k = True
     bytestr = bytes
     unicodestr = str
     nativestr = unicodestr
     from io import BytesIO as BytesIO
 else:
     # Python 2
+    py3k = False
     bytestr = str
     unicodestr = unicode
     nativestr = bytestr
     json_decode = json.JSONDecoder().decode
     json_encode = json.JSONEncoder().iterencode
 except ImportError:
-    if sys.version_info >= (3, 0):
+    if py3k:
         # Python 3.0: json is part of the standard library,
         # but outputs unicode. We need bytes.
         import json

File py3/cherrypy/_cplogging.py

 logfmt = logging.Formatter("%(message)s")
 import os
 import sys
-_py3k = (sys.version_info >= (3, 0))
 
 import cherrypy
 from cherrypy import _cperror
-from cherrypy._cpcompat import ntob
+from cherrypy._cpcompat import ntob, py3k
 
 
 class LogManager(object):
     access_log = None
     """The actual :class:`logging.Logger` instance for access messages."""
     
-    if _py3k:
+    if py3k:
         access_log_format = \
             '{h} {l} {u} {t} "{r}" {s} {b} "{f}" "{a}"'
     else:
             status = "-"
         else:
             status = response.output_status.split(ntob(" "), 1)[0]
-            if _py3k:
+            if py3k:
                 status = status.decode('ISO-8859-1')
         
         atoms = {'h': remote.name or remote.ip,
                  'f': dict.get(inheaders, 'Referer', ''),
                  'a': dict.get(inheaders, 'User-Agent', ''),
                  }
-        if _py3k:
+        if py3k:
             for k, v in atoms.items():
                 if not isinstance(v, str):
                     v = str(v)

File py3/cherrypy/_cprequest.py

 
 import cherrypy
 from cherrypy._cpcompat import basestring, copykeys, ntob, unicodestr
-from cherrypy._cpcompat import SimpleCookie, CookieError
+from cherrypy._cpcompat import SimpleCookie, CookieError, py3k
 from cherrypy import _cpreqbody, _cpconfig
 from cherrypy._cperror import format_exc, bare_error
 from cherrypy.lib import httputil, file_generator
                 self.query_string_encoding)
         
         # Python 2 only: keyword arguments must be byte strings (type 'str').
-        if sys.version_info < (3, 0):
+        if not py3k:
             for key, value in p.items():
                 if isinstance(key, unicode):
                     del p[key]
     :attr:`request.body.params<cherrypy._cprequest.RequestBody.params>`.""")
 
 
-_py3k = (sys.version_info >= (3, 0))
-
 class ResponseBody(object):
     """The body of the HTTP response (the response entity)."""
     
-    if _py3k:
+    if py3k:
         unicode_err = ("Page handlers MUST return bytes. Use tools.encode "
                        "if you wish to return unicode.")
     
     
     def __set__(self, obj, value):
         # Convert the given value to an iterable object.
-        if _py3k and isinstance(value, str):
+        if py3k and isinstance(value, str):
             raise ValueError(self.unicode_err)
         
         if isinstance(value, basestring):
             else:
                 # [''] doesn't evaluate to False, so replace it with [].
                 value = []
-        elif _py3k and isinstance(value, list):
+        elif py3k and isinstance(value, list):
             # every item in a list must be bytes... 
             for i, item in enumerate(value):
                 if isinstance(item, str):
         
         newbody = []
         for chunk in self.body:
-            if _py3k and not isinstance(chunk, bytes):
+            if py3k and not isinstance(chunk, bytes):
                 raise TypeError("Chunk %s is not of type 'bytes'." % repr(chunk))
             newbody.append(chunk)
         newbody = ntob('').join(newbody)

File py3/cherrypy/_cpserver.py

 
 import cherrypy
 from cherrypy.lib import attributes
-from cherrypy._cpcompat import basestring
+from cherrypy._cpcompat import basestring, py3k
 
 # We import * because we want to export check_port
 # et al as attributes of this module.
     ssl_private_key = None
     """The filename of the private key to use with SSL."""
     
-    if sys.version_info >= (3, 0):
+    if py3k:
         ssl_module = 'builtin'
         """The name of a registered SSL adaptation module to use with the builtin
         WSGI server. Builtin options are: 'builtin' (to use the SSL library built

File py3/cherrypy/_cptree.py

 import sys
 
 import cherrypy
-from cherrypy._cpcompat import ntou
+from cherrypy._cpcompat import ntou, py3k
 from cherrypy import _cpconfig, _cplogging, _cprequest, _cpwsgi, tools
 from cherrypy.lib import httputil
 
         
         # Correct the SCRIPT_NAME and PATH_INFO environ entries.
         environ = environ.copy()
-        if sys.version_info < (3, 0):
+        if not py3k:
             if environ.get(ntou('wsgi.version')) == (ntou('u'), 0):
                 # Python 2/WSGI u.0: all strings MUST be of type unicode
                 enc = environ[ntou('wsgi.url_encoding')]

File py3/cherrypy/_cpwsgi.py

 import sys as _sys
 
 import cherrypy as _cherrypy
-from cherrypy._cpcompat import BytesIO, ntob, ntou, unicodestr
+from cherrypy._cpcompat import BytesIO, ntob, ntou, py3k, unicodestr
 from cherrypy import _cperror
 from cherrypy.lib import httputil
 
         self.started_response = True
         return self
     
-    if _sys.version_info >= (3, 0):
+    if py3k:
         def __next__(self):
             return self.trap(next, self.iter_response)
     else:
     """WSGI response iterable for CherryPy applications."""
     
     def __init__(self, environ, start_response, cpapp):
-        if _sys.version_info < (3, 0):
+        if not py3k:
             if environ.get(ntou('wsgi.version')) == (ntou('u'), 0):
                 environ = downgrade_wsgi_ux_to_1x(environ)
         self.environ = environ
     def __iter__(self):
         return self
     
-    if _sys.version_info >= (3, 0):
+    if py3k:
         def __next__(self):
             return next(self.iter_response)
     else:
                                 self.environ.get('PATH_INFO', ''))
         qs = self.environ.get('QUERY_STRING', '')
 
-        if _sys.version_info >= (3, 0):
+        if py3k:
             # This isn't perfect; if the given PATH_INFO is in the wrong encoding,
             # it may fail to match the appropriate config section URI. But meh.
             old_enc = self.environ.get('wsgi.url_encoding', 'ISO-8859-1')

File py3/cherrypy/test/test_dynamicobjectmapping.py

             self.id = id
             self.name = name
 
+        def __unicode__(self):
+            return unicode(self.name)
         def __str__(self):
             return str(self.name)
 

File py3/cherrypy/test/test_etags.py

                 return 'I am a \u1ee4nicode string.'
             unicoded.exposed = True
             # In Python 3, tools.encode is on by default
-            # unicoded._cp_config = {'tools.encode.on': True}
+            unicoded._cp_config = {'tools.encode.on': True}
         
         conf = {'/': {'tools.etags.on': True,
                       'tools.etags.autotags': True,

File py3/cherrypy/test/test_request_obj.py

 localDir = os.path.dirname(__file__)
 import sys
 import types
-from cherrypy._cpcompat import IncompleteRead, ntob, unicodestr
+from cherrypy._cpcompat import IncompleteRead, ntob, ntou, unicodestr
 
 import cherrypy
 from cherrypy import _cptools, tools
                     if isinstance(value, types.FunctionType):
                         value.exposed = True
                 setattr(root, name.lower(), cls())
-        class Test(object, metaclass=TestType):
-            pass
+        Test = TestType('Test', (object,), {})
 
         class PathInfo(Test):
 
 
     def testParams(self):
         self.getPage("/params/?thing=a")
-        self.assertBody("'a'")
+        self.assertBody(repr(ntou("a")))
         
         self.getPage("/params/?thing=a&thing=b&thing=c")
-        self.assertBody("['a', 'b', 'c']")
+        self.assertBody(repr([ntou('a'), ntou('b'), ntou('c')]))
 
         # Test friendly error message when given params are not accepted.
         cherrypy.config.update({"request.show_mismatched_params": True})
         self.assertInBody("Not Found")
 
         # Test "% HEX HEX"-encoded URL, param keys, and values
-        self.getPage("/params/%d4%20%e3/cheese?Gruy%e8re=Bulgn%e9ville")
+        self.getPage("/params/%d4%20%e3/cheese?Gruy%E8re=Bulgn%e9ville")
         self.assertBody("args: ('\xd4 \xe3', 'cheese') "
                         "kwargs: {'Gruy\xe8re': 'Bulgn\xe9ville'}")
         

File py3/cherrypy/test/test_tools.py

 
 import gzip
 import sys
-from cherrypy._cpcompat import BytesIO, copyitems, itervalues, IncompleteRead, ntob, ntou, xrange
+from cherrypy._cpcompat import BytesIO, copyitems, itervalues
+from cherrypy._cpcompat import IncompleteRead, ntob, ntou, py3k, xrange
 import time
 timeout = 0.2
 import types
             def __call__(self, scale):
                 r = cherrypy.response
                 r.collapse_body()
-                r.body = [bytes([(x + scale) % 256 for x in r.body[0]])]
+                if py3k:
+                    r.body = [bytes([(x + scale) % 256 for x in r.body[0]])]
+                else:
+                    r.body = [chr((ord(x) + scale) % 256) for x in r.body[0]]
         cherrypy.tools.rotator = cherrypy.Tool('before_finalize', Rotator())
         
         def stream_handler(next_handler, *args, **kwargs):
                     if isinstance(value, types.FunctionType):
                         value.exposed = True
                 setattr(root, name.lower(), cls())
-        class Test(object, metaclass=TestType):
-            pass
+        Test = TestType('Test', (object,), {})
         
         
         # METHOD ONE:
         # but it proves the priority was changed.
         self.getPage("/decorated_euro/subpath",
                      headers=[("Accept-Encoding", "gzip")])
-        self.assertInBody(bytes([(x + 3) % 256 for x in zbuf.getvalue()]))
+        if py3k:
+            self.assertInBody(bytes([(x + 3) % 256 for x in zbuf.getvalue()]))
+        else:
+            self.assertInBody(''.join([chr((ord(x) + 3) % 256) for x in zbuf.getvalue()]))
     
     def testBareHooks(self):
         content = "bit of a pain in me gulliver"

File py3/cherrypy/test/test_virtualhost.py

             dom4.exposed = True
             
             def method(self, value):
-                return "You sent %s" % repr(value)
+                return "You sent %s" % value
             method.exposed = True
         
         class VHost:
             index.exposed = True
             
             def vmethod(self, value):
-                return "You sent %s" % repr(value)
+                return "You sent %s" % value
             vmethod.exposed = True
             
             def url(self):
         
         # Test GET, POST, and positional params
         self.getPage("/method?value=root")
-        self.assertBody("You sent 'root'")
+        self.assertBody("You sent root")
         self.getPage("/vmethod?value=dom2+GET", [('Host', 'www.mydom2.com')])
-        self.assertBody("You sent 'dom2 GET'")
+        self.assertBody("You sent dom2 GET")
         self.getPage("/vmethod", [('Host', 'www.mydom3.com')], method="POST",
                      body="value=dom3+POST")
-        self.assertBody("You sent 'dom3 POST'")
+        self.assertBody("You sent dom3 POST")
         self.getPage("/vmethod/pos", [('Host', 'www.mydom3.com')])
-        self.assertBody("You sent 'pos'")
+        self.assertBody("You sent pos")
         
         # Test that cherrypy.url uses the browser url, not the virtual url
         self.getPage("/url", [('Host', 'www.mydom2.com')])

File py3/cherrypy/test/test_wsgiapps.py

+from cherrypy._cpcompat import ntob
 from cherrypy.test import helper
 
 
         import cherrypy
         
         def test_app(environ, start_response):
-            status = b'200 OK'
-            response_headers = [(b'Content-type', b'text/plain')]
+            status = ntob('200 OK')
+            response_headers = [(ntob('Content-type'), ntob('text/plain'))]
             start_response(status, response_headers)
             output = ['Hello, world!\n',
                       'This is a wsgi app running within CherryPy!\n\n']
             keys.sort()
             for k in keys:
                 output.append('%s: %s\n' % (k,environ[k]))
-            return [x.encode('utf-8') for x in output]
+            return [ntob(x, 'utf-8') for x in output]
         
         def test_empty_string_app(environ, start_response):
-            status = b'200 OK'
-            response_headers = [(b'Content-type', b'text/plain')]
+            status = ntob('200 OK')
+            response_headers = [(ntob('Content-type'), ntob('text/plain'))]
             start_response(status, response_headers)
-            return [b'Hello', b'', b' ', b'', b'world']
+            return [ntob('Hello'), ntob(''), ntob(' '), ntob(''), ntob('world')]
         
         
         class WSGIResponse(object):
             def __iter__(self):
                 return self
             
+            def next(self):
+                return self.iter.next()
             def __next__(self):
                 return next(self.iter)
             
             def __call__(self, environ, start_response):
                 results = app(environ, start_response)
                 class Reverser(WSGIResponse):
+                    def next(this):
+                        line = list(this.iter.next())
+                        line.reverse()
+                        return "".join(line)
                     def __next__(this):
                         line = list(next(this.iter))
                         line.reverse()
         
         class Root:
             def index(self):
-                return b"I'm a regular CherryPy page handler!"
+                return ntob("I'm a regular CherryPy page handler!")
             index.exposed = True
         
         

File py3/cherrypy/wsgiserver/ssl_builtin.py

     import ssl
 except ImportError:
     ssl = None
+
+try:
+    from _pyio import DEFAULT_BUFFER_SIZE
+except ImportError:
+    try:
+        from io import DEFAULT_BUFFER_SIZE
+    except ImportError:
+        DEFAULT_BUFFER_SIZE = -1
+
 import sys
-if sys.version_info < (3,1):
-    import io
-else:
-    import _pyio as io
+
 from cherrypy import wsgiserver
 
 
             s = ssl.wrap_socket(sock, do_handshake_on_connect=True,
                     server_side=True, certfile=self.certificate,
                     keyfile=self.private_key, ssl_version=ssl.PROTOCOL_SSLv23)
-        except ssl.SSLError as e:
+        except ssl.SSLError:
+            e = sys.exc_info()[1]
             if e.errno == ssl.SSL_ERROR_EOF:
                 # This is almost certainly due to the cherrypy engine
                 # 'pinging' the socket to assert it's connectable;
             }
         return ssl_environ
     
-    def makefile(self, sock, mode='r', bufsize=io.DEFAULT_BUFFER_SIZE):
-        return wsgiserver.CP_makefile(sock, mode, bufsize)
+    if sys.version_info >= (3, 0):
+        def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
+            return wsgiserver.CP_makefile(sock, mode, bufsize)
+    else:
+        def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
+            return wsgiserver.CP_fileobject(sock, mode, bufsize)