Alex Grönholm avatar Alex Grönholm committed 3fe54b3

Refactored the code to be compatible with Python 3.1 and above

Comments (0)

Files changed (14)

paste/deploy/compat.py

+# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
+# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+"""Python 2<->3 compatibility module"""
+import sys
+
+
+def print_(template, *args, **kwargs):
+    template = str(template)
+    if args:
+        template = template % args
+    elif kwargs:
+        template = template % kwargs
+    sys.stdout.writelines(template)
+
+if sys.version_info < (3, 0):
+    basestring = basestring
+    from ConfigParser import ConfigParser
+    from urllib import unquote
+    iteritems = lambda d: d.iteritems()
+
+    def reraise(t, e, tb):
+        exec('raise t, e, tb', dict(t=t, e=e, tb=tb))
+else:
+    basestring = str
+    from configparser import ConfigParser
+    from urllib.parse import unquote
+    iteritems = lambda d: d.items()
+
+    def reraise(t, e, tb):
+        exec('raise e from tb', dict(e=e, tb=tb))

paste/deploy/converters.py

 # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
 # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+from paste.deploy.compat import basestring
 
 
 def asbool(obj):
-    if isinstance(obj, (str, unicode)):
+    if isinstance(obj, basestring):
         obj = obj.strip().lower()
         if obj in ['true', 'yes', 'on', 'y', 't', '1']:
             return True
         elif obj in ['false', 'no', 'off', 'n', 'f', '0']:
             return False
         else:
-            raise ValueError(
-                "String is not true/false: %r" % obj)
+            raise ValueError("String is not true/false: %r" % obj)
     return bool(obj)
 
 
     try:
         return int(obj)
     except (TypeError, ValueError):
-        raise ValueError(
-            "Bad integer value: %r" % obj)
+        raise ValueError("Bad integer value: %r" % obj)
 
 
 def aslist(obj, sep=None, strip=True):
-    if isinstance(obj, (str, unicode)):
+    if isinstance(obj, basestring):
         lst = obj.split(sep)
         if strip:
             lst = [v.strip() for v in lst]

paste/deploy/loadwsgi.py

 # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
 # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-from ConfigParser import ConfigParser
+from __future__ import with_statement
 import os
+import sys
 import re
-import urllib
 
 import pkg_resources
 
+from paste.deploy.compat import ConfigParser, unquote, iteritems
 from paste.deploy.util import fix_call
 
 __all__ = ['loadapp', 'loadserver', 'loadfilter', 'appconfig']
     def __init__(self, filename, *args, **kw):
         ConfigParser.__init__(self, *args, **kw)
         self.filename = filename
+        if hasattr(self, '_interpolation'):
+            self._interpolation = self.InterpolateWrapper(self._interpolation)
+
+    read_file = getattr(ConfigParser, 'read_file', ConfigParser.readfp)
 
     def defaults(self):
         """Return the defaults, with their values interpolated (with the
         Mainly to support defaults using values such as %(here)s
         """
         defaults = ConfigParser.defaults(self).copy()
-        for key, val in defaults.iteritems():
-            defaults[key] = self._interpolate('DEFAULT', key, val, defaults)
+        for key, val in iteritems(defaults):
+            defaults[key] = self.get('DEFAULT', key) or val
         return defaults
 
     def _interpolate(self, section, option, rawval, vars):
+        # Python < 3.2
         try:
             return ConfigParser._interpolate(
                 self, section, option, rawval, vars)
-        except Exception, e:
+        except Exception:
+            e = sys.exc_info()[1]
             args = list(e.args)
             args[0] = 'Error in file %s, [%s] %s=%r: %s' % (
                 self.filename, section, option, rawval, e)
             e.args = tuple(args)
+            e.message = args[0]
             raise
 
+    class InterpolateWrapper(object):
+        # Python >= 3.2
+        def __init__(self, original):
+            self._original = original
+
+        def __getattr__(self, name):
+            return getattr(self._original, name)
+
+        def before_get(self, parser, section, option, value, defaults):
+            try:
+                return self._original.before_get(parser, section, option,
+                                                 value, defaults)
+            except Exception:
+                e = sys.exc_info()[1]
+                args = list(e.args)
+                args[0] = 'Error in file %s, [%s] %s=%r: %s' % (
+                    parser.filename, section, option, value, e)
+                e.args = tuple(args)
+                e.message = args[0]
+                raise
+
 
 ############################################################
 ## Object types
 
     def __init__(self):
         # Normalize these variables:
-        self.egg_protocols = map(_aslist, _aslist(self.egg_protocols))
-        self.config_prefixes = map(_aslist, _aslist(self.config_prefixes))
+        self.egg_protocols = [_aslist(p) for p in _aslist(self.egg_protocols)]
+        self.config_prefixes = [_aslist(p) for p in _aslist(self.config_prefixes)]
 
     def __repr__(self):
         return '<%s protocols=%r prefixes=%r>' % (
             path = relative_to + '/' + path
     if path.startswith('///'):
         path = path[2:]
-    path = urllib.unquote(path)
+    path = unquote(path)
     loader = ConfigLoader(path)
     if global_conf:
         loader.update_defaults(global_conf, overwrite=False)
 
     def __init__(self, filename):
         self.filename = filename = filename.strip()
-        self.parser = NicerConfigParser(self.filename)
-        # Don't lower-case keys:
-        self.parser.optionxform = str
-        # Stupid ConfigParser ignores files that aren't found, so
-        # we have to add an extra check:
-        if not os.path.exists(filename):
-            if filename.strip() != filename:
-                raise IOError(
-                    "File %r not found; trailing whitespace: "
-                    "did you try to use a # on the same line as a filename? "
-                    "(comments must be on their own line)" % filename)
-            raise IOError(
-                "File %r not found" % filename)
-        self.parser.read(filename)
-        self.parser._defaults.setdefault(
-            'here', os.path.dirname(os.path.abspath(filename)))
-        self.parser._defaults.setdefault(
-            '__file__', os.path.abspath(filename))
+        defaults = {
+            'here': os.path.dirname(os.path.abspath(filename)),
+            '__file__': os.path.abspath(filename)
+            }
+        self.parser = NicerConfigParser(filename, defaults=defaults)
+        self.parser.optionxform = str  # Don't lower-case keys
+        with open(filename) as f:
+            self.parser.read_file(f)
 
     def update_defaults(self, new_defaults, overwrite=True):
-        for key, value in new_defaults.items():
+        for key, value in iteritems(new_defaults):
             if not overwrite and key in self.parser._defaults:
                 continue
             self.parser._defaults[key] = value

paste/deploy/paster_templates.py

 
 from paste.script.templates import Template
 
+from paste.deploy.compat import print_
+
 
 class PasteDeploy(Template):
 
              '      main = %(package)s.wsgiapp:make_app\n') % vars,
             indent=False)
         if command.verbose:
-            print '*' * 72
-            print '* Run "paster serve docs/devel_config.ini" to run the sample application'
-            print '* on http://localhost:8080'
-            print '*' * 72
+            print_('*' * 72)
+            print_('* Run "paster serve docs/devel_config.ini" to run the sample application')
+            print_('* on http://localhost:8080')
+            print_('*' * 72)

paste/deploy/util.py

 import inspect
 import sys
 
+from paste.deploy.compat import reraise
+
 
 def fix_type_error(exc_info, callable, varargs, kwargs):
     """
         val = callable(*args, **kw)
     except TypeError:
         exc_info = fix_type_error(None, callable, args, kw)
-        raise exc_info[0], exc_info[1], exc_info[2]
+        reraise(*exc_info)
     return val

tests/__init__.py

 # Make absolutely sure we're testing *this* package, not
 # some other installed package
 pkg_resources.require('PasteDeploy')
-
         os.symlink(info_dir, egg_info_dir)
     except:
         shutil.copytree(info_dir, egg_info_dir)
-        
+
 sys.path.append(os.path.dirname(egg_info_dir))
 
 from pkg_resources import *
 working_set.add_entry(os.path.dirname(egg_info_dir))
 require('FakeApp')
-

tests/sample_configs/test_config.ini

 [DEFAULT]
 def1 = a
 def2 = b
+basepath = %(here)s
 
 [app:test1]
 use = egg:FakeApp#configed
 setting1 = foo
 setting2 = bar
+apppath = %(basepath)s/app
 
 [app:test2]
 use = egg:FakeApp#configed

tests/sample_configs/test_error.ini

+[DEFAULT]
+def1 = a
+def2 = b
+
+[app:main]
+use = egg:FakeApp#configed
+setting1 = foo
+setting2 = %(does_not_exist)s/bar

tests/test_basic_app.py

-from paste.deploy import loadapp, loadfilter, appconfig
-from fixture import *
+from paste.deploy import loadapp
+
+from tests.fixture import *
 import fakeapp.apps
 
+
 here = os.path.dirname(__file__)
 
+
 def test_main():
     app = loadapp('config:sample_configs/basic_app.ini',
                   relative_to=here)
                   relative_to=here, name='main')
     assert app is fakeapp.apps.basic_app
 
+
 def test_other():
     app = loadapp('config:sample_configs/basic_app.ini#other',
                   relative_to=here)
     assert app is fakeapp.apps.basic_app2
-    
+
 
 def test_composit():
     app = loadapp('config:sample_configs/basic_app.ini#remote_addr',
     assert isinstance(app, fakeapp.apps.RemoteAddrDispatch)
     assert app.map['127.0.0.1'] is fakeapp.apps.basic_app
     assert app.map['0.0.0.0'] is fakeapp.apps.basic_app2
-    
-    

tests/test_config.py

-import os
-from paste.deploy import loadapp, loadfilter, appconfig
-from fixture import *
+from nose.tools import eq_
+
+from paste.deploy import loadapp, appconfig
+from tests.fixture import *
 import fakeapp.configapps as fc
-from pprint import pprint
+
 
 ini_file = 'config:sample_configs/test_config.ini'
 here = os.path.dirname(__file__)
 config_path = os.path.join(here, 'sample_configs')
 config_filename = os.path.join(config_path, 'test_config.ini')
 
+
 def test_config_egg():
     app = loadapp('egg:FakeApp#configed')
     assert isinstance(app, fc.SimpleApp)
-    
+
+
 def test_config1():
     app = loadapp(ini_file, relative_to=here, name='test1')
-    assert app.local_conf == {
-        'setting1': 'foo', 'setting2': 'bar'}
-    assert app.global_conf == {
-        'def1': 'a', 'def2': 'b',
+    eq_(app.local_conf, {
+        'setting1': 'foo',
+        'setting2': 'bar',
+        'apppath': os.path.join(config_path, 'app')})
+    eq_(app.global_conf, {
+        'def1': 'a',
+        'def2': 'b',
+        'basepath': config_path,
         'here': config_path,
-        '__file__': config_filename}
+        '__file__': config_filename})
+
 
 def test_config2():
     app = loadapp(ini_file, relative_to=here, name='test2')
-    assert app.local_conf == {
-        'local conf': 'something'}
-    assert app.global_conf == {
+    eq_(app.local_conf, {
+        'local conf': 'something'})
+    eq_(app.global_conf, {
         'def1': 'test2',
         'def2': 'b',
+        'basepath': config_path,
         'another': 'TEST',
         'here': config_path,
-        '__file__': config_filename}
+        '__file__': config_filename})
     # Run this to make sure the global-conf-modified test2
     # didn't mess up the general global conf
     test_config1()
 
+
 def test_config3():
     app = loadapp(ini_file, relative_to=here, name='test3')
     assert isinstance(app, fc.SimpleApp)
-    assert app.local_conf == {
+    eq_(app.local_conf, {
         'local conf': 'something',
-        'another': 'something more\nacross several\nlines'}
-    assert app.global_conf == {
+        'another': 'something more\nacross several\nlines'})
+    eq_(app.global_conf, {
         'def1': 'test3',
         'def2': 'b',
+        'basepath': config_path,
         'another': 'TEST',
         'here': config_path,
-        '__file__': config_filename}
+        '__file__': config_filename})
     test_config2()
-    
+
+
 def test_foreign_config():
     app = loadapp(ini_file, relative_to=here, name='test_foreign_config')
     assert isinstance(app, fc.SimpleApp)
-    assert app.local_conf == {
+    eq_(app.local_conf, {
         'another': 'FOO',
-        'bob': 'your uncle'}
-    pprint(app.global_conf)
-    assert app.global_conf == {
+        'bob': 'your uncle'})
+    eq_(app.global_conf, {
         'def1': 'a',
         'def2': 'from include',
         'def3': 'c',
+        'basepath': config_path,
         'glob': 'override',
         'here': config_path,
-        '__file__': os.path.join(config_path, 'test_config.ini')}
-    
+        '__file__': os.path.join(config_path, 'test_config.ini')})
+
+
 def test_config_get():
     app = loadapp(ini_file, relative_to=here, name='test_get')
     assert isinstance(app, fc.SimpleApp)
-    assert app.local_conf == {
+    eq_(app.local_conf, {
         'def1': 'a',
-        'foo': 'TEST'}
-    assert app.global_conf == {
+        'foo': 'TEST'})
+    eq_(app.global_conf, {
         'def1': 'a',
         'def2': 'TEST',
+        'basepath': os.path.join(here, 'sample_configs'),
         'here': config_path,
-        '__file__': config_filename}
+        '__file__': config_filename})
+
 
 def test_appconfig():
     conf = appconfig(ini_file, relative_to=here, name='test_get')
-    assert conf == {
+    eq_(conf, {
         'def1': 'a',
         'def2': 'TEST',
+        'basepath': os.path.join(here, 'sample_configs'),
         'here': config_path,
         '__file__': config_filename,
-        'foo': 'TEST'}
-    assert conf.local_conf == {
+        'foo': 'TEST'})
+    eq_(conf.local_conf, {
         'def1': 'a',
-        'foo': 'TEST'}
-    assert conf.global_conf == {
+        'foo': 'TEST'})
+    eq_(conf.global_conf, {
         'def1': 'a',
         'def2': 'TEST',
+        'basepath': os.path.join(here, 'sample_configs'),
         'here': config_path,
-        '__file__': config_filename,}
+        '__file__': config_filename})
+
 
 def test_appconfig_filter_with():
     conf = appconfig('config:test_filter_with.ini', relative_to=config_path)
-    assert conf['example'] == 'test'
+    eq_(conf['example'], 'test')
+
 
 def test_global_conf():
-    conf = appconfig(ini_file, relative_to=here, name='test_global_conf', global_conf={'def2': 'TEST DEF 2', 'inherit': 'bazbar'})
-    pprint(conf)
-    assert conf == {
+    conf = appconfig(ini_file, relative_to=here, name='test_global_conf',
+                     global_conf={'def2': 'TEST DEF 2', 'inherit': 'bazbar'})
+    eq_(conf, {
         'def1': 'a',
         # Note that this gets overwritten:
         'def2': 'b',
+        'basepath': os.path.join(here, 'sample_configs'),
         'here': config_path,
         'inherit': 'bazbar',
         '__file__': config_filename,
         'test_interp': 'this:bazbar',
-        }
-    assert conf.local_conf == {
-        'test_interp': 'this:bazbar',
-        }
-    
+        })
+    eq_(conf.local_conf, {
+        'test_interp': 'this:bazbar'})
+
+
+def test_interpolate_exception():
+    try:
+        appconfig('config:test_error.ini', relative_to=config_path)
+    except Exception:
+        e = sys.exc_info()[1]
+        expected = "Error in file %s" % os.path.join(config_path, 'test_error.ini')
+        eq_(str(e).split(',')[0], expected)
+    else:
+        assert False, 'Should have raised an exception'

tests/test_config_middleware.py

 from nose.tools import assert_raises
+from nose.plugins.skip import SkipTest
+
 from paste.deploy.config import ConfigMiddleware
-from paste.fixture import TestApp
 
-class Bug(Exception): pass
+
+class Bug(Exception):
+    pass
+
 
 def app_with_exception(environ, start_response):
     def cont():
     start_response('200 OK', [('Content-type', 'text/html')])
     return cont()
 
+
 def test_error():
+    # This import is conditional due to Paste not yet working on py3k
+    try:
+        from paste.fixture import TestApp
+    except ImportError:
+        raise SkipTest
+
     wrapped = ConfigMiddleware(app_with_exception, {'test': 1})
     test_app = TestApp(wrapped)
     assert_raises(Bug, test_app.get, '/')
-

tests/test_filter.py

-from paste.deploy import loadapp, loadfilter
-from fixture import *
+from paste.deploy import loadapp
+from tests.fixture import *
 import fakeapp.apps
 
+
 here = os.path.dirname(__file__)
 
+
 def test_filter_app():
     app = loadapp('config:sample_configs/test_filter.ini#filt',
                   relative_to=here)
     assert app.app is fakeapp.apps.basic_app
     assert app.method_to_call == 'lower'
 
+
 def test_pipeline():
     app = loadapp('config:sample_configs/test_filter.ini#piped',
                   relative_to=here)
     assert app.app is fakeapp.apps.basic_app
     assert app.method_to_call == 'upper'
 
+
 def test_filter_app2():
     app = loadapp('config:sample_configs/test_filter.ini#filt2',
                   relative_to=here)
     assert app.app is fakeapp.apps.basic_app
     assert app.method_to_call == 'lower'
 
+
 def test_pipeline2():
     app = loadapp('config:sample_configs/test_filter.ini#piped2',
                   relative_to=here)
     assert app.app is fakeapp.apps.basic_app
     assert app.method_to_call == 'upper'
 
+
 def test_filter_app_inverted():
     app = loadapp('config:sample_configs/test_filter.ini#inv',
                   relative_to=here)
     assert isinstance(app, fakeapp.apps.CapFilter)
     assert app.app is fakeapp.apps.basic_app
 
+
 def test_filter_with_filter_with():
     app = loadapp('config:sample_configs/test_filter_with.ini',
                   relative_to=here)

tests/test_load_package.py

-import sys, os
+from pprint import pprint
+import sys
+
 import pkg_resources
-import site
-from pprint import pprint
+
+from paste.deploy.compat import print_
+
 
 def test_load_package():
-    print 'Path:'
+    print_('Path:')
     pprint(sys.path)
-    print pkg_resources.require('FakeApp')
-    
+    print_(pkg_resources.require('FakeApp'))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.