summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pyramid/request.py2
-rw-r--r--pyramid/view.py73
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