1. Ben Rousch
  2. CherryPy

Commits

Robert Brewer  committed 42eb80a

More py2/py3 sync

  • Participants
  • Parent commits f11e43c
  • Branches default

Comments (0)

Files changed (16)

File py2/cherrypy/_cpserver.py

View file
     ssl_private_key = None
     """The filename of the private key to use with SSL."""
     
-    if sys.version >= (3, 0):
+    if sys.version_info >= (3, 0):
         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/_cpwsgi_server.py

View file
         self.protocol = self.server_adapter.protocol_version
         self.nodelay = self.server_adapter.nodelay
 
-        if sys.version >= (3, 0):
+        if sys.version_info >= (3, 0):
             ssl_module = self.server_adapter.ssl_module or 'builtin'
         else:
             ssl_module = self.server_adapter.ssl_module or 'pyopenssl'

File py2/cherrypy/lib/__init__.py

View file
 """CherryPy Library"""
 
 # Deprecated in CherryPy 3.2 -- remove in CherryPy 3.3
-from cherrypy.lib.reprconf import _Builder, unrepr, modules, attributes
+from cherrypy.lib.reprconf import unrepr, modules, attributes
 
 class file_generator(object):
     """Yield the given input (a file object) in chunks (default 64k). (Core)"""

File py2/cherrypy/lib/cptools.py

View file
     
     For running a CP server behind Apache, lighttpd, or other HTTP server.
     
+    For Apache and lighttpd, you should leave the 'local' argument at the
+    default value of 'X-Forwarded-Host'. For Squid, you probably want to set
+    tools.proxy.local = 'Origin'.
+    
     If you want the new request.base to include path info (not just the host),
     you must explicitly set base to the full base path, and ALSO set 'local'
     to '', so that the X-Forwarded-Host request header (which never includes

File py2/cherrypy/lib/httputil.py

View file
 
 from binascii import b2a_base64
 from cherrypy._cpcompat import BaseHTTPRequestHandler, HTTPDate, ntob, ntou, reversed, sorted
-from cherrypy._cpcompat import basestring, nativestr, bytestr, iteritems, unicodestr, unquote_qs
+from cherrypy._cpcompat import basestring, bytestr, iteritems, nativestr, unicodestr, unquote_qs
 response_codes = BaseHTTPRequestHandler.responses.copy()
 
 # From http://www.cherrypy.org/ticket/361

File py2/cherrypy/lib/reprconf.py

View file
     set
 except NameError:
     from sets import Set as set
+
+try:
+    basestring
+except NameError:
+    basestring = str
+
+try:
+    # Python 3
+    import builtins
+except ImportError:
+    # Python 2
+    import __builtin__ as builtins
+
+import operator as _operator
 import sys
 
 def as_dict(config):
             if section not in result:
                 result[section] = {}
             for option in self.options(section):
-                value = self.get(section, option, raw, vars)
+                value = self.get(section, option, raw=raw, vars=vars)
                 try:
                     value = unrepr(value)
-                except Exception, x:
+                except Exception:
+                    x = sys.exc_info()[1]
                     msg = ("Config error in section: %r, option: %r, "
                            "value: %r. Config values must be valid Python." %
                            (section, option, value))
 
 # public domain "unrepr" implementation, found on the web and then improved.
 
-class _Builder:
+
+class _Builder2:
     
     def build(self, o):
         m = getattr(self, 'build_' + o.__class__.__name__, None)
                             repr(o.__class__.__name__))
         return m(o)
     
+    def astnode(self, s):
+        """Return a Python2 ast Node compiled from a string."""
+        try:
+            import compiler
+        except ImportError:
+            # Fallback to eval when compiler package is not available,
+            # e.g. IronPython 1.0.
+            return eval(s)
+        
+        p = compiler.parse("__tempvalue__ = " + s)
+        return p.getChildren()[1].getChildren()[0].getChildren()[1]
+    
     def build_Subscript(self, o):
         expr, flags, subs = o.getChildren()
         expr = self.build(expr)
         
         # See if the Name is in builtins.
         try:
-            import __builtin__
-            return getattr(__builtin__, name)
+            return getattr(builtins, name)
         except AttributeError:
             pass
         
         return self.build(o.getChildren()[0])
 
 
-def _astnode(s):
-    """Return a Python ast Node compiled from a string."""
-    try:
-        import compiler
-    except ImportError:
-        # Fallback to eval when compiler package is not available,
-        # e.g. IronPython 1.0.
-        return eval(s)
+class _Builder3:
     
-    p = compiler.parse("__tempvalue__ = " + s)
-    return p.getChildren()[1].getChildren()[0].getChildren()[1]
+    def build(self, o):
+        m = getattr(self, 'build_' + o.__class__.__name__, None)
+        if m is None:
+            raise TypeError("unrepr does not recognize %s" %
+                            repr(o.__class__.__name__))
+        return m(o)
     
+    def astnode(self, s):
+        """Return a Python3 ast Node compiled from a string."""
+        try:
+            import ast
+        except ImportError:
+            # Fallback to eval when ast package is not available,
+            # e.g. IronPython 1.0.
+            return eval(s)
+
+        p = ast.parse("__tempvalue__ = " + s)
+        return p.body[0].value
+
+    def build_Subscript(self, o):
+        return self.build(o.value)[self.build(o.slice)]
+    
+    def build_Index(self, o):
+        return self.build(o.value)
+    
+    def build_Call(self, o):
+        callee = self.build(o.func)
+        
+        if o.args is None:
+            args = ()
+        else: 
+            args = tuple([self.build(a) for a in o.args]) 
+        
+        if o.starargs is None:
+            starargs = ()
+        else:
+            starargs = self.build(o.starargs)
+        
+        if o.kwargs is None:
+            kwargs = {}
+        else:
+            kwargs = self.build(o.kwargs)
+        
+        return callee(*(args + starargs), **kwargs)
+    
+    def build_List(self, o):
+        return list(map(self.build, o.elts))
+    
+    def build_Str(self, o):
+        return o.s
+    
+    def build_Num(self, o):
+        return o.n
+    
+    def build_Dict(self, o):
+        return dict([(self.build(k), self.build(v))
+                     for k, v in zip(o.keys, o.values)])
+    
+    def build_Tuple(self, o):
+        return tuple(self.build_List(o))
+    
+    def build_Name(self, o):
+        name = o.id
+        if name == 'None':
+            return None
+        if name == 'True':
+            return True
+        if name == 'False':
+            return False
+        
+        # See if the Name is a package or module. If it is, import it.
+        try:
+            return modules(name)
+        except ImportError:
+            pass
+        
+        # See if the Name is in builtins.
+        try:
+            import builtins
+            return getattr(builtins, name)
+        except AttributeError:
+            pass
+        
+        raise TypeError("unrepr could not resolve the name %s" % repr(name))
+        
+    def build_UnaryOp(self, o):
+        op, operand = map(self.build, [o.op, o.operand])
+        return op(operand)
+    
+    def build_BinOp(self, o):
+        left, op, right = map(self.build, [o.left, o.op, o.right]) 
+        return op(left, right)
+
+    def build_Add(self, o):
+        return _operator.add
+        
+    def build_USub(self, o):
+        return _operator.neg
+
+    def build_Attribute(self, o):
+        parent = self.build(o.value)
+        return getattr(parent, o.attr)
+
+    def build_NoneType(self, o):
+        return None
+
 
 def unrepr(s):
     """Return a Python object compiled from a string."""
     if not s:
         return s
-    obj = _astnode(s)
-    return _Builder().build(obj)
+    if sys.version_info <= (3, 0):
+        b = _Builder2()
+    else:
+        b = _Builder3()
+    obj = b.astnode(s)
+    return b.build(obj)
 
 
 def modules(modulePath):

File py2/cherrypy/lib/static.py

View file
+try:
+    from io import UnsupportedOperation
+except ImportError:
+    UnsupportedOperation = object()
 import logging
 import mimetypes
 mimetypes.init()
         if debug:
             cherrypy.log('os has no fstat attribute', 'TOOLS.STATIC')
         content_length = None
+    except UnsupportedOperation:
+        content_length = None
     else:
         # Set the Last-Modified response header, so that
         # modified-since validation code can work.

File py2/cherrypy/process/wspbus.py

View file
 
     __repr__ = __str__
 
-    def __nonzero__(self):
+    def __bool__(self):
         return bool(self._exceptions)
+    __nonzero__ = __bool__
 
 # Use a flag to indicate the state of the bus.
 class _StateEnum(object):
         
         items = [(self._priorities[(channel, listener)], listener)
                  for listener in self.listeners[channel]]
-        items.sort()
+        by_priority = lambda item: item[0]
+        items.sort(key=by_priority)
         for priority, listener in items:
             try:
                 output.append(listener(*args, **kwargs))
             except KeyboardInterrupt:
                 raise
-            except SystemExit, e:
+            except SystemExit:
+                e = sys.exc_info()[1]
                 # If we have previous errors ensure the exit code is non-zero
                 if exc and e.code == 0:
                     e.code = 1
         except:
             self.log("Shutting down due to error in start listener:",
                      level=40, traceback=True)
-            e_info = sys.exc_info()
+            e_info = sys.exc_info()[1]
             try:
                 self.exit()
             except:
                 # Any stop/exit errors will be logged inside publish().
                 pass
-            raise e_info[0], e_info[1], e_info[2]
+            # Re-raise the original error
+            raise e
     
     def exit(self):
         """Stop all services and prepare to exit the process."""

File py3/cherrypy/_cpserver.py

View file
     ssl_private_key = None
     """The filename of the private key to use with SSL."""
     
-    if sys.version() >= (3, 0):
+    if sys.version_info >= (3, 0):
         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/_cpwsgi_server.py

View file
         self.protocol = self.server_adapter.protocol_version
         self.nodelay = self.server_adapter.nodelay
 
-        if sys.version >= (3, 0):
+        if sys.version_info >= (3, 0):
             ssl_module = self.server_adapter.ssl_module or 'builtin'
         else:
             ssl_module = self.server_adapter.ssl_module or 'pyopenssl'

File py3/cherrypy/lib/__init__.py

View file
 """CherryPy Library"""
 
 # Deprecated in CherryPy 3.2 -- remove in CherryPy 3.3
-from cherrypy.lib.reprconf import _Builder, unrepr, modules, attributes
+from cherrypy.lib.reprconf import unrepr, modules, attributes
 
 class file_generator(object):
     """Yield the given input (a file object) in chunks (default 64k). (Core)"""

File py3/cherrypy/lib/cptools.py

View file
     
     For running a CP server behind Apache, lighttpd, or other HTTP server.
     
+    For Apache and lighttpd, you should leave the 'local' argument at the
+    default value of 'X-Forwarded-Host'. For Squid, you probably want to set
+    tools.proxy.local = 'Origin'.
+    
     If you want the new request.base to include path info (not just the host),
     you must explicitly set base to the full base path, and ALSO set 'local'
     to '', so that the X-Forwarded-Host request header (which never includes

File py3/cherrypy/lib/httputil.py

View file
 
 from binascii import b2a_base64
 from cherrypy._cpcompat import BaseHTTPRequestHandler, HTTPDate, ntob, ntou, reversed, sorted
-from cherrypy._cpcompat import basestring, iteritems, unicodestr, unquote_qs
+from cherrypy._cpcompat import basestring, bytestr, iteritems, nativestr, unicodestr, unquote_qs
 response_codes = BaseHTTPRequestHandler.responses.copy()
 
 # From http://www.cherrypy.org/ticket/361

File py3/cherrypy/lib/reprconf.py

View file
 except ImportError:
     from ConfigParser import ConfigParser
 
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+try:
+    basestring
+except NameError:
+    basestring = str
+
+try:
+    # Python 3
+    import builtins
+except ImportError:
+    # Python 2
+    import __builtin__ as builtins
+
 import operator as _operator
 import sys
 
 def as_dict(config):
     """Return a dict from 'config' whether it is a dict, file, or filename."""
-    if isinstance(config, str):
+    if isinstance(config, basestring):
         config = Parser().dict_from_file(config)
     elif hasattr(config, 'read'):
         config = Parser().dict_from_file(config)
                 bucket = ns_confs.setdefault(ns, {})
                 bucket[name] = config[k]
         
+        # I chose __enter__ and __exit__ so someday this could be
+        # rewritten using Python 2.5's 'with' statement:
+        # for ns, handler in self.iteritems():
+        #     with handler as callable:
+        #         for k, v in ns_confs.get(ns, {}).iteritems():
+        #             callable(k, v)
         for ns, handler in self.items():
             exit = getattr(handler, "__exit__", None)
             if exit:
-                with handler as callable:
-                    for k, v in ns_confs.get(ns, {}).items():
-                        callable(k, v)
+                callable = handler.__enter__()
+                no_exc = True
+                try:
+                    try:
+                        for k, v in ns_confs.get(ns, {}).items():
+                            callable(k, v)
+                    except:
+                        # The exceptional case is handled here
+                        no_exc = False
+                        if exit is None:
+                            raise
+                        if not exit(*sys.exc_info()):
+                            raise
+                        # The exception is swallowed if exit() returns true
+                finally:
+                    # The normal and non-local-goto cases are handled here
+                    if no_exc and exit:
+                        exit(None, None, None)
             else:
                 for k, v in ns_confs.get(ns, {}).items():
                     handler(k, v)
     
     def update(self, config):
         """Update self from a dict, file or filename."""
-        if isinstance(config, str):
+        if isinstance(config, basestring):
             # Filename
             config = Parser().dict_from_file(config)
         elif hasattr(config, 'read'):
         return optionstr
     
     def read(self, filenames):
-        if isinstance(filenames, str):
+        if isinstance(filenames, basestring):
             filenames = [filenames]
         for filename in filenames:
             # try:
                 value = self.get(section, option, raw=raw, vars=vars)
                 try:
                     value = unrepr(value)
-                except Exception as x:
+                except Exception:
+                    x = sys.exc_info()[1]
                     msg = ("Config error in section: %r, option: %r, "
                            "value: %r. Config values must be valid Python." %
                            (section, option, value))
 
 # public domain "unrepr" implementation, found on the web and then improved.
 
-class _Builder:
+
+class _Builder2:
     
     def build(self, o):
         m = getattr(self, 'build_' + o.__class__.__name__, None)
                             repr(o.__class__.__name__))
         return m(o)
     
+    def astnode(self, s):
+        """Return a Python2 ast Node compiled from a string."""
+        try:
+            import compiler
+        except ImportError:
+            # Fallback to eval when compiler package is not available,
+            # e.g. IronPython 1.0.
+            return eval(s)
+        
+        p = compiler.parse("__tempvalue__ = " + s)
+        return p.getChildren()[1].getChildren()[0].getChildren()[1]
+    
+    def build_Subscript(self, o):
+        expr, flags, subs = o.getChildren()
+        expr = self.build(expr)
+        subs = self.build(subs)
+        return expr[subs]
+    
+    def build_CallFunc(self, o):
+        children = map(self.build, o.getChildren())
+        callee = children.pop(0)
+        kwargs = children.pop() or {}
+        starargs = children.pop() or ()
+        args = tuple(children) + tuple(starargs)
+        return callee(*args, **kwargs)
+    
+    def build_List(self, o):
+        return map(self.build, o.getChildren())
+    
+    def build_Const(self, o):
+        return o.value
+    
+    def build_Dict(self, o):
+        d = {}
+        i = iter(map(self.build, o.getChildren()))
+        for el in i:
+            d[el] = i.next()
+        return d
+    
+    def build_Tuple(self, o):
+        return tuple(self.build_List(o))
+    
+    def build_Name(self, o):
+        name = o.name
+        if name == 'None':
+            return None
+        if name == 'True':
+            return True
+        if name == 'False':
+            return False
+        
+        # See if the Name is a package or module. If it is, import it.
+        try:
+            return modules(name)
+        except ImportError:
+            pass
+        
+        # See if the Name is in builtins.
+        try:
+            return getattr(builtins, name)
+        except AttributeError:
+            pass
+        
+        raise TypeError("unrepr could not resolve the name %s" % repr(name))
+    
+    def build_Add(self, o):
+        left, right = map(self.build, o.getChildren())
+        return left + right
+    
+    def build_Getattr(self, o):
+        parent = self.build(o.expr)
+        return getattr(parent, o.attrname)
+    
+    def build_NoneType(self, o):
+        return None
+    
+    def build_UnarySub(self, o):
+        return -self.build(o.getChildren()[0])
+    
+    def build_UnaryAdd(self, o):
+        return self.build(o.getChildren()[0])
+
+
+class _Builder3:
+    
+    def build(self, o):
+        m = getattr(self, 'build_' + o.__class__.__name__, None)
+        if m is None:
+            raise TypeError("unrepr does not recognize %s" %
+                            repr(o.__class__.__name__))
+        return m(o)
+    
+    def astnode(self, s):
+        """Return a Python3 ast Node compiled from a string."""
+        try:
+            import ast
+        except ImportError:
+            # Fallback to eval when ast package is not available,
+            # e.g. IronPython 1.0.
+            return eval(s)
+
+        p = ast.parse("__tempvalue__ = " + s)
+        return p.body[0].value
+
     def build_Subscript(self, o):
         return self.build(o.value)[self.build(o.slice)]
     
         return None
 
 
-def _astnode(s):
-    """Return a Python ast Node compiled from a string."""
-    try:
-        import ast
-    except ImportError:
-        # Fallback to eval when ast package is not available,
-        # e.g. IronPython 1.0.
-        return eval(s)
-
-    p = ast.parse("__tempvalue__ = " + s)
-    return p.body[0].value
-
 def unrepr(s):
     """Return a Python object compiled from a string."""
     if not s:
         return s
-    obj = _astnode(s)
-    return _Builder().build(obj)
+    if sys.version_info <= (3, 0):
+        b = _Builder2()
+    else:
+        b = _Builder3()
+    obj = b.astnode(s)
+    return b.build(obj)
 
 
 def modules(modulePath):

File py3/cherrypy/lib/static.py

View file
-import io
+try:
+    from io import UnsupportedOperation
+except ImportError:
+    UnsupportedOperation = object()
 import logging
 import mimetypes
 mimetypes.init()
         if debug:
             cherrypy.log('os has no fstat attribute', 'TOOLS.STATIC')
         content_length = None
-    except io.UnsupportedOperation:
+    except UnsupportedOperation:
         content_length = None
     else:
         # Set the Last-Modified response header, so that

File py3/cherrypy/process/wspbus.py

View file
     delimiter = '\n'
     
     def __init__(self, *args, **kwargs):
-        super(ChannelFailures, self).__init__(*args, **kwargs)
+        # Don't use 'super' here; Exceptions are old-style in Py2.4
+        # See http://www.cherrypy.org/ticket/959
+        Exception.__init__(self, *args, **kwargs)
         self._exceptions = list()
     
     def handle_exception(self):
 
     def __bool__(self):
         return bool(self._exceptions)
+    __nonzero__ = __bool__
 
 # Use a flag to indicate the state of the bus.
 class _StateEnum(object):
                 output.append(listener(*args, **kwargs))
             except KeyboardInterrupt:
                 raise
-            except SystemExit as e:
+            except SystemExit:
+                e = sys.exc_info()[1]
                 # If we have previous errors ensure the exit code is non-zero
                 if exc and e.code == 0:
                     e.code = 1
         except:
             self.log("Shutting down due to error in start listener:",
                      level=40, traceback=True)
+            e_info = sys.exc_info()[1]
             try:
                 self.exit()
             except:
                 # Any stop/exit errors will be logged inside publish().
                 pass
-            raise
+            # Re-raise the original error
+            raise e
     
     def exit(self):
         """Stop all services and prepare to exit the process."""