diff options
| -rw-r--r-- | pyramid/request.py | 2 | ||||
| -rw-r--r-- | pyramid/view.py | 73 |
2 files changed, 75 insertions, 0 deletions
diff --git a/pyramid/request.py b/pyramid/request.py index 45d936cef..c1c1da514 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -32,6 +32,7 @@ from pyramid.util import ( InstancePropertyHelper, InstancePropertyMixin, ) +from pyramid.view import ViewMethodsMixin class TemplateContext(object): pass @@ -154,6 +155,7 @@ class Request( LocalizerRequestMixin, AuthenticationAPIMixin, AuthorizationAPIMixin, + ViewMethodsMixin, ): """ A subclass of the :term:`WebOb` Request class. An instance of diff --git a/pyramid/view.py b/pyramid/view.py index 7e8996ca4..1f20622dc 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -1,4 +1,6 @@ import itertools +import sys + import venusian from zope.interface import providedBy @@ -10,6 +12,7 @@ from pyramid.interfaces import ( IView, IViewClassifier, IRequest, + IExceptionViewClassifier, ) from pyramid.compat import decode_path_info @@ -547,3 +550,73 @@ def _call_view( raise pme return response + +class ViewMethodsMixin(object): + """ Request methods mixin for BaseRequest having to do with executing + views """ + def invoke_exception_view( + self, + exc_info=None, + request=None, + secure=True + ): + """ Executes an exception view related to the request it's called upon. + The arguments it takes are these: + + ``exc_info`` + + If provided, should be a 3-tuple in the form provided by + ``sys.exc_info()``. If not provided, + ``sys.exc_info()`` will be called to obtain the current + interpreter exception information. Default: ``None``. + + ``request`` + + If the request to be used is not the same one as the instance that + this method is called upon, it may be passed here. Default: + ``None``. + + ``secure`` + + If the exception view should not be rendered if the current user + does not have the appropriate permission, this should be ``True``. + Default: ``True``. + + If called with no arguments, it uses the global exception information + returned by ``sys.exc_info()`` as ``exc_info``, the request + object that this method is attached to as the ``request``, and + ``True`` for ``secure``. + + This method returns a :term:`response` object or ``None`` if no + matching exception view can be found..""" + + if request is None: + request = self + registry = getattr(request, 'registry', None) + if registry is None: + registry = get_current_registry() + if exc_info is None: + exc_info = sys.exc_info() + attrs = request.__dict__ + context_iface = providedBy(exc_info[0]) + view_name = attrs.get('view_name', '') + # probably need something like "with temporarily_munged_request(req)" + # here, which adds exception and exc_info as request attrs, and + # removes response object temporarily (as per the excview tween) + attrs['exception'] = exc_info[0] + attrs['exc_info'] = exc_info + # we use .get instead of .__getitem__ below due to + # https://github.com/Pylons/pyramid/issues/700 + request_iface = attrs.get('request_iface', IRequest) + response = _call_view( + registry, + request, + exc_info[0], + context_iface, + view_name, + view_types=None, + view_classifier=IExceptionViewClassifier, + secure=secure, + request_iface=request_iface.combined, + ) + return response |
