Commits

Robert Brewer  committed 42eb80a

More py2/py3 sync

  • Participants
  • Parent commits f11e43c

Comments (0)

Files changed (16)

File py2/cherrypy/_cpserver.py

     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

         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

 """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

     
     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

 
 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

     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

+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

 
     __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

     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

         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

 """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

     
     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

 
 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

 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

-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

     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."""