From b0d20b5c3fe7df472633899024cdab685483807a Mon Sep 17 00:00:00 2001 From: Amos Latteier Date: Thu, 2 Jun 2016 14:50:53 -0700 Subject: add exception_only argument to add_view to only register exception views. --- pyramid/config/views.py | 25 +++++++++++++++++++++---- pyramid/tests/test_config/test_views.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 9e46ba155..198fde5e8 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -213,6 +213,7 @@ class ViewsConfiguratorMixin(object): match_param=None, check_csrf=None, require_csrf=None, + exception_only=False, **view_options): """ Add a :term:`view configuration` to the current configuration state. Arguments to ``add_view`` are broken @@ -701,6 +702,14 @@ class ViewsConfiguratorMixin(object): Support setting view deriver options. Previously, only custom view predicate values could be supplied. + exception_only + + .. versionadded:: 1.8 + + A boolean indicating whether the view is registered only as an + exception view. When this argument is true, the view context must + be an exception. + """ if custom_predicates: warnings.warn( @@ -759,6 +768,11 @@ class ViewsConfiguratorMixin(object): raise ConfigurationError( 'request_type must be an interface, not %s' % request_type) + if exception_only and not isexception(context): + raise ConfigurationError( + 'context must be an exception when exception_only is true' + ) + if context is None: context = for_ @@ -942,10 +956,13 @@ class ViewsConfiguratorMixin(object): view_iface = ISecuredView else: view_iface = IView - self.registry.registerAdapter( - derived_view, - (IViewClassifier, request_iface, context), view_iface, name - ) + if not exception_only: + self.registry.registerAdapter( + derived_view, + (IViewClassifier, request_iface, context), + view_iface, + name + ) if isexc: self.registry.registerAdapter( derived_view, diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 878574e88..c93175ff9 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1815,6 +1815,38 @@ class TestViewsConfigurationMixin(unittest.TestCase): self.assertRaises(ConfigurationError, configure_view) + def test_add_view_exception_only_no_regular_view(self): + from zope.interface import implementedBy + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view1, context=Exception, renderer=null_renderer, + exception_only=True) + view = self._getViewCallable(config, ctx_iface=implementedBy(Exception)) + self.assertTrue(view is None) + + def test_add_view_exception_only(self): + from zope.interface import implementedBy + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view1, context=Exception, renderer=null_renderer, + exception_only=True) + view = self._getViewCallable( + config, ctx_iface=implementedBy(Exception), exception_view=True + ) + self.assertEqual(view1, view) + + def test_add_view_exception_only_misconfiguration(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + class NotAnException(object): + pass + self.assertRaises( + ConfigurationError, + config.add_view, view, context=NotAnException, exception_only=True + ) + def test_derive_view_function(self): from pyramid.renderers import null_renderer def view(request): -- cgit v1.2.3