Hello community,

here is the log from the commit of package python-pecan for openSUSE:Factory 
checked in at 2013-08-15 12:28:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pecan (Old)
 and      /work/SRC/openSUSE:Factory/.python-pecan.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pecan"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pecan/python-pecan.changes        
2013-06-29 14:33:23.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-pecan.new/python-pecan.changes   
2013-08-15 12:28:53.000000000 +0200
@@ -1,0 +2,9 @@
+Tue Aug 13 10:10:55 UTC 2013 - dmuel...@suse.com
+
+- update to 0.3.2:
+  * Made some changes to simplify how ``pecan.conf.app`` is passed to new apps.
+  * Fixed a routing bug for certain ``_lookup`` controller configurations.
+  * Improved documentation for handling file uploads.
+  * Deprecated the ``pecan.conf.requestviewer`` configuration option.
+
+-------------------------------------------------------------------

Old:
----
  pecan-0.3.0.tar.gz

New:
----
  pecan-0.3.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pecan.spec ++++++
--- /var/tmp/diff_new_pack.MGUceP/_old  2013-08-15 12:28:53.000000000 +0200
+++ /var/tmp/diff_new_pack.MGUceP/_new  2013-08-15 12:28:53.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-pecan
-Version:        0.3.0
+Version:        0.3.2
 Release:        0
 Summary:        A WSGI object-dispatching web framework, designed to be lean 
and fast
 License:        BSD-3-Clause
@@ -25,7 +25,7 @@
 Url:            http://github.com/dreamhost/pecan
 Source:         
http://pypi.python.org/packages/source/p/pecan/pecan-%{version}.tar.gz
 BuildRequires:  python-devel
-BuildRequires:  python-distribute
+BuildRequires:  python-setuptools
 # Test requirements:
 #BuildRequires:  python-Genshi
 #BuildRequires:  python-Jinja2

++++++ pecan-0.3.0.tar.gz -> pecan-0.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/PKG-INFO new/pecan-0.3.2/PKG-INFO
--- old/pecan-0.3.0/PKG-INFO    2013-05-08 20:33:53.000000000 +0200
+++ new/pecan-0.3.2/PKG-INFO    2013-08-12 23:42:59.000000000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
 Name: pecan
-Version: 0.3.0
+Version: 0.3.2
 Summary: A WSGI object-dispatching web framework, designed to be lean and 
fast, with few dependancies.
 Home-page: http://github.com/dreamhost/pecan
 Author: Jonathan LaCour
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/README.rst new/pecan-0.3.2/README.rst
--- old/pecan-0.3.0/README.rst  2013-05-07 20:13:05.000000000 +0200
+++ new/pecan-0.3.2/README.rst  2013-08-12 22:49:47.000000000 +0200
@@ -7,6 +7,10 @@
 .. _travis: http://travis-ci.org/dreamhost/pecan
 .. |travis| image:: https://secure.travis-ci.org/dreamhost/pecan.png
 
+.. image:: https://pypip.in/v/pecan/badge.png
+    :target: https://crate.io/packages/pecan/
+    :alt: Latest PyPI version
+
 |travis|_
 
 Installing
@@ -46,5 +50,6 @@
 
 Additional Help/Support
 -----------------------
-Most Pecan interaction is done via the #pecanpy channel on `FreeNode
-<http://freenode.net/>`_ IRC.
+Most Pecan interaction is done via the `pecan-dev Mailing List
+<https://groups.google.com/forum/#!forum/pecan-dev>`_ and the #pecanpy channel
+on `FreeNode <http://freenode.net/>`_ IRC.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/pecan/__init__.py 
new/pecan-0.3.2/pecan/__init__.py
--- old/pecan-0.3.0/pecan/__init__.py   2013-05-07 20:13:05.000000000 +0200
+++ new/pecan-0.3.2/pecan/__init__.py   2013-08-12 22:49:47.000000000 +0200
@@ -17,6 +17,8 @@
 except ImportError:
     from logutils.dictconfig import dictConfig as load_logging_config  # noqa
 
+import warnings
+
 
 __all__ = [
     'make_app', 'load_app', 'Pecan', 'request', 'response',
@@ -25,8 +27,7 @@
 ]
 
 
-def make_app(root, static_root=None, logging={}, debug=False,
-             wrap_app=None, **kw):
+def make_app(root, **kw):
     '''
     Utility for creating the Pecan application object.  This function should
     generally be called from the ``setup_app`` function in your project's
@@ -37,8 +38,6 @@
     :param static_root: The relative path to a directory containing static
                         files.  Serving static files is only enabled when
                         debug mode is set.
-    :param logging: A dictionary used to configure logging.  This uses
-                    ``logging.config.dictConfig``.
     :param debug: A flag to enable debug mode.  This enables the debug
                   middleware and serving static files.
     :param wrap_app: A function or middleware class to wrap the Pecan app.
@@ -49,19 +48,31 @@
                      This should be used if you want to use middleware to
                      perform authentication or intercept all requests before
                      they are routed to the root controller.
+    :param logging: A dictionary used to configure logging.  This uses
+                    ``logging.config.dictConfig``.
 
     All other keyword arguments are passed in to the Pecan app constructor.
 
     :returns: a ``Pecan`` object.
     '''
-    # A shortcut for the RequestViewerHook middleware.
-    if hasattr(conf, 'requestviewer'):
-        existing_hooks = kw.get('hooks', [])
-        existing_hooks.append(RequestViewerHook(conf.requestviewer))
-        kw['hooks'] = existing_hooks
-
     # Pass logging configuration (if it exists) on to the Python logging module
+    logging = kw.get('logging', {})
+    debug = kw.get('debug', False)
     if logging:
+        if debug:
+            try:
+                #
+                # By default, Python 2.7+ silences DeprecationWarnings.
+                # However, if conf.app.debug is True, we should probably ensure
+                # that users see these types of warnings.
+                #
+                from logging import captureWarnings
+                captureWarnings(True)
+                warnings.simplefilter("default", DeprecationWarning)
+            except ImportError:
+                # No captureWarnings on Python 2.6, DeprecationWarnings are on
+                pass
+
         if isinstance(logging, Config):
             logging = logging.to_dict()
         if 'version' not in logging:
@@ -72,28 +83,40 @@
     app = Pecan(root, **kw)
 
     # Optionally wrap the app in another WSGI app
+    wrap_app = kw.get('wrap_app', None)
     if wrap_app:
         app = wrap_app(app)
 
     # Configuration for serving custom error messages
-    if hasattr(conf.app, 'errors'):
-        app = ErrorDocumentMiddleware(app, conf.app.errors)
+    errors = kw.get('errors', getattr(conf.app, 'errors', {}))
+    if errors:
+        app = ErrorDocumentMiddleware(app, errors)
 
     # Included for internal redirect support
     app = RecursiveMiddleware(app)
 
     # When in debug mode, load our exception dumping middleware
+    static_root = kw.get('static_root', None)
     if debug:
         app = DebugMiddleware(app)
 
         # Support for serving static files (for development convenience)
         if static_root:
             app = StaticFileMiddleware(app, static_root)
+
     elif static_root:
-        from warnings import warn
-        warn(
+        warnings.warn(
             "`static_root` is only used when `debug` is True, ignoring",
             RuntimeWarning
         )
 
+    if hasattr(conf, 'requestviewer'):
+        warnings.warn(''.join([
+            "`pecan.conf.requestviewer` is deprecated.  To apply the ",
+            "`RequestViewerHook` to your application, add it to ",
+            "`pecan.conf.app.hooks` or manually in your project's `app.py` ",
+            "file."]),
+            DeprecationWarning
+        )
+
     return app
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/pecan/core.py 
new/pecan-0.3.2/pecan/core.py
--- old/pecan-0.3.0/pecan/core.py       2013-05-07 20:13:05.000000000 +0200
+++ new/pecan-0.3.2/pecan/core.py       2013-08-12 22:49:47.000000000 +0200
@@ -173,11 +173,12 @@
 
     :param root: A string representing a root controller object (e.g.,
                 "myapp.controller.root.RootController")
-    :param default_renderer: The default rendering engine to use. Defaults
-                             to mako.
-    :param template_path: The default relative path to use for templates.
-                          Defaults to 'templates'.
-    :param hooks: A list of Pecan hook objects to use for this application.
+    :param default_renderer: The default template rendering engine to use.
+                             Defaults to mako.
+    :param template_path: A relative file system path (from the project root)
+                          where template files live.  Defaults to 'templates'.
+    :param hooks: A callable which returns a list of
+                  :class:`pecan.hooks.PecanHook`s
     :param custom_renderers: Custom renderer objects, as a dictionary keyed
                              by engine name.
     :param extra_template_vars: Any variables to inject into the template
@@ -195,9 +196,9 @@
     )
 
     def __init__(self, root, default_renderer='mako',
-                 template_path='templates', hooks=[], custom_renderers={},
-                 extra_template_vars={}, force_canonical=True,
-                 guess_content_type_from_ext=True):
+                 template_path='templates', hooks=lambda: [],
+                 custom_renderers={}, extra_template_vars={},
+                 force_canonical=True, guess_content_type_from_ext=True, **kw):
 
         if isinstance(root, six.string_types):
             root = self.__translate_root__(root)
@@ -205,7 +206,11 @@
         self.root = root
         self.renderers = RendererFactory(custom_renderers, extra_template_vars)
         self.default_renderer = default_renderer
+
         # pre-sort these so we don't have to do it per-request
+        if six.callable(hooks):
+            hooks = hooks()
+
         self.hooks = list(sorted(
             hooks,
             key=operator.attrgetter('priority')
@@ -299,7 +304,11 @@
             hooks = reversed(state.hooks)
 
         for hook in hooks:
-            getattr(hook, hook_type)(*args)
+            result = getattr(hook, hook_type)(*args)
+            # on_error hooks can choose to return a Response, which will
+            # be used instead of the standard error pages.
+            if hook_type == 'on_error' and isinstance(result, Response):
+                return result
 
     def get_args(self, req, all_params, remainder, argspec, im_self):
         '''
@@ -564,11 +573,16 @@
                 environ['pecan.original_exception'] = e
 
             # if this is not an internal redirect, run error hooks
+            on_error_result = None
             if not isinstance(e, ForwardRequestException):
-                self.handle_hooks('on_error', state, e)
+                on_error_result = self.handle_hooks('on_error', state, e)
 
-            if not isinstance(e, exc.HTTPException):
-                raise
+            # if the on_error handler returned a Response, use it.
+            if isinstance(on_error_result, Response):
+                state.response = on_error_result
+            else:
+                if not isinstance(e, exc.HTTPException):
+                    raise
         finally:
             # handle "after" hooks
             self.handle_hooks('after', state)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/pecan/routing.py 
new/pecan-0.3.2/pecan/routing.py
--- old/pecan-0.3.0/pecan/routing.py    2013-05-07 20:13:05.000000000 +0200
+++ new/pecan-0.3.2/pecan/routing.py    2013-08-12 22:49:47.000000000 +0200
@@ -46,6 +46,13 @@
                     #   traversal
                     result = handle_lookup_traversal(obj, remainder)
                     if result:
+                        # If no arguments are passed to the _lookup, yet the
+                        # argspec requires at least one, raise a 404
+                        if (
+                            remainder == ['']
+                            and len(obj._pecan['argspec'].args) > 1
+                        ):
+                            raise
                         return lookup_controller(*result)
             else:
                 raise exc.HTTPNotFound
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pecan-0.3.0/pecan/scaffolds/base/+package+/app.py_tmpl 
new/pecan-0.3.2/pecan/scaffolds/base/+package+/app.py_tmpl
--- old/pecan-0.3.0/pecan/scaffolds/base/+package+/app.py_tmpl  2013-05-07 
20:13:05.000000000 +0200
+++ new/pecan-0.3.2/pecan/scaffolds/base/+package+/app.py_tmpl  2013-08-12 
22:49:47.000000000 +0200
@@ -5,16 +5,10 @@
 def setup_app(config):
 
     model.init_model()
+    app_conf = dict(config.app)
 
     return make_app(
-        config.app.root,
-        static_root=config.app.static_root,
-        template_path=config.app.template_path,
+        app_conf.pop('root'),
         logging=getattr(config, 'logging', {}),
-        debug=getattr(config.app, 'debug', False),
-        force_canonical=getattr(config.app, 'force_canonical', True),
-        guess_content_type_from_ext=getattr(
-            config.app,
-            'guess_content_type_from_ext',
-            True),
+        **app_conf
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/pecan/scaffolds/base/config.py_tmpl 
new/pecan-0.3.2/pecan/scaffolds/base/config.py_tmpl
--- old/pecan-0.3.0/pecan/scaffolds/base/config.py_tmpl 2013-05-07 
20:13:05.000000000 +0200
+++ new/pecan-0.3.2/pecan/scaffolds/base/config.py_tmpl 2013-08-12 
22:49:47.000000000 +0200
@@ -20,7 +20,9 @@
 logging = {
     'loggers': {
         'root': {'level': 'INFO', 'handlers': ['console']},
-        '${package}': {'level': 'DEBUG', 'handlers': ['console']}
+        '${package}': {'level': 'DEBUG', 'handlers': ['console']},
+        'py.warnings': {'handlers': ['console']},
+        '__force_dict__': True
     },
     'handlers': {
         'console': {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/pecan/tests/test_base.py 
new/pecan-0.3.2/pecan/tests/test_base.py
--- old/pecan-0.3.0/pecan/tests/test_base.py    2013-05-07 20:13:05.000000000 
+0200
+++ new/pecan-0.3.2/pecan/tests/test_base.py    2013-08-12 22:49:47.000000000 
+0200
@@ -182,6 +182,35 @@
             assert r.status_int == 404
 
 
+class TestCanonicalLookups(PecanTestCase):
+
+    @property
+    def app_(self):
+        class LookupController(object):
+            def __init__(self, someID):
+                self.someID = someID
+
+            @expose()
+            def index(self):
+                return self.someID
+
+        class UserController(object):
+            @expose()
+            def _lookup(self, someID, *remainder):
+                return LookupController(someID), remainder
+
+        class RootController(object):
+            users = UserController()
+
+        return TestApp(Pecan(RootController()))
+
+    def test_canonical_lookup(self):
+        assert self.app_.get('/users', expect_errors=404).status_int == 404
+        assert self.app_.get('/users/', expect_errors=404).status_int == 404
+        assert self.app_.get('/users/100').status_int == 302
+        assert self.app_.get('/users/100/').body == b_('100')
+
+
 class TestControllerArguments(PecanTestCase):
 
     @property
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/pecan/tests/test_hooks.py 
new/pecan-0.3.2/pecan/tests/test_hooks.py
--- old/pecan-0.3.0/pecan/tests/test_hooks.py   2013-05-07 20:13:05.000000000 
+0200
+++ new/pecan-0.3.2/pecan/tests/test_hooks.py   2013-08-12 22:49:47.000000000 
+0200
@@ -1,7 +1,10 @@
 from webtest import TestApp
 from six import b as b_
+from six import u as u_
 from six.moves import cStringIO as StringIO
 
+from webob import Response
+
 from pecan import make_app, expose, redirect, abort
 from pecan.hooks import (
     PecanHook, TransactionHook, HookController, RequestViewerHook
@@ -133,6 +136,33 @@
         assert run_hook[0] == 'on_route'
         assert run_hook[1] == 'error'
 
+    def test_on_error_response_hook(self):
+        run_hook = []
+
+        class RootController(object):
+            @expose()
+            def causeerror(self):
+                return [][1]
+
+        class ErrorHook(PecanHook):
+            def on_error(self, state, e):
+                run_hook.append('error')
+
+                r = Response()
+                r.text = u_('on_error')
+
+                return r
+
+        app = TestApp(make_app(RootController(), hooks=[
+            ErrorHook()
+        ]))
+
+        response = app.get('/causeerror')
+
+        assert len(run_hook) == 1
+        assert run_hook[0] == 'error'
+        assert response.text == 'on_error'
+
     def test_prioritized_hooks(self):
         run_hook = []
 
@@ -1017,21 +1047,6 @@
 
 class TestRequestViewerHook(PecanTestCase):
 
-    def test_hook_from_config(self):
-        from pecan.configuration import _runtime_conf as conf
-        conf['requestviewer'] = {
-            'blacklist': ['/favicon.ico']
-        }
-
-        class RootController(object):
-            pass
-
-        app = make_app(RootController())
-        while hasattr(app, 'application'):
-            app = app.application
-        del conf.__values__['requestviewer']
-        assert app.hooks
-
     def test_basic_single_default_hook(self):
 
         _stdout = StringIO()
@@ -1043,7 +1058,9 @@
 
         app = TestApp(
             make_app(
-                RootController(), hooks=[RequestViewerHook(writer=_stdout)]
+                RootController(), hooks=lambda: [
+                    RequestViewerHook(writer=_stdout)
+                ]
             )
         )
         response = app.get('/')
@@ -1074,7 +1091,9 @@
 
         app = TestApp(
             make_app(
-                RootController(), hooks=[RequestViewerHook(writer=_stdout)]
+                RootController(), hooks=lambda: [
+                    RequestViewerHook(writer=_stdout)
+                ]
             )
         )
         response = app.get('/404', expect_errors=True)
@@ -1104,7 +1123,7 @@
         app = TestApp(
             make_app(
                 RootController(),
-                hooks=[
+                hooks=lambda: [
                     RequestViewerHook(
                         config={'items': ['path']}, writer=_stdout
                     )
@@ -1139,7 +1158,7 @@
         app = TestApp(
             make_app(
                 RootController(),
-                hooks=[
+                hooks=lambda: [
                     RequestViewerHook(
                         config={'blacklist': ['/']}, writer=_stdout
                     )
@@ -1166,7 +1185,7 @@
         app = TestApp(
             make_app(
                 RootController(),
-                hooks=[
+                hooks=lambda: [
                     RequestViewerHook(
                         config={'items': ['date']}, writer=_stdout
                     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/pecan.egg-info/PKG-INFO 
new/pecan-0.3.2/pecan.egg-info/PKG-INFO
--- old/pecan-0.3.0/pecan.egg-info/PKG-INFO     2013-05-08 20:33:52.000000000 
+0200
+++ new/pecan-0.3.2/pecan.egg-info/PKG-INFO     2013-08-12 23:42:58.000000000 
+0200
@@ -1,6 +1,6 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
 Name: pecan
-Version: 0.3.0
+Version: 0.3.2
 Summary: A WSGI object-dispatching web framework, designed to be lean and 
fast, with few dependancies.
 Home-page: http://github.com/dreamhost/pecan
 Author: Jonathan LaCour
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pecan-0.3.0/setup.py new/pecan-0.3.2/setup.py
--- old/pecan-0.3.0/setup.py    2013-05-08 20:05:13.000000000 +0200
+++ new/pecan-0.3.2/setup.py    2013-08-12 22:49:47.000000000 +0200
@@ -2,7 +2,7 @@
 
 from setuptools import setup, find_packages
 
-version = '0.3.0'
+version = '0.3.2'
 
 #
 # determine requirements
@@ -43,7 +43,6 @@
 
 tests_require = requirements + [
     'virtualenv',
-    'Jinja2',
     'gunicorn',
     'mock'
 ]
@@ -58,6 +57,9 @@
     # Genshi added Python3 support in 0.7
     tests_require += ['Genshi>=0.7']
 
+if sys.version_info < (3, 0) or sys.version_info >= (3, 3):
+    tests_require += ['Jinja2']
+
 #
 # call setup
 #

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to