summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Piercy <web@stevepiercy.com>2017-05-12 01:27:20 -0700
committerSteve Piercy <web@stevepiercy.com>2017-05-12 01:27:20 -0700
commitdede5366e8b2ce5982806f4306cdaaa6c8e178ca (patch)
tree5a9d27d5f518d1abc5e89c5a5a00b6d409781671
parent0b92dfed800117595ef00fb2847c5db9970f4cac (diff)
parent4e27dd4c452a67d38a07eb79939dcbfcc6e82ab0 (diff)
downloadpyramid-dede5366e8b2ce5982806f4306cdaaa6c8e178ca.tar.gz
pyramid-dede5366e8b2ce5982806f4306cdaaa6c8e178ca.tar.bz2
pyramid-dede5366e8b2ce5982806f4306cdaaa6c8e178ca.zip
Merge remote-tracking branch 'upstream/master'
-rw-r--r--CHANGES.txt42
-rw-r--r--docs/conf.py2
-rw-r--r--docs/whatsnew-1.9.rst9
-rw-r--r--pyramid/tests/test_view.py6
-rw-r--r--pyramid/tweens.py60
-rw-r--r--pyramid/view.py26
-rw-r--r--setup.py2
7 files changed, 77 insertions, 70 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index b299ed6e9..51a1e457d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,28 @@
+1.9a2 (2017-05-09)
+==================
+
+Backward Incompatibilities
+--------------------------
+
+- ``request.exception`` and ``request.exc_info`` will only be set if the
+ response was generated by the EXCVIEW tween. This is to avoid any confusion
+ where a response was generated elsewhere in the pipeline and not in
+ direct relation to the original exception. If anyone upstream wants to
+ catch and render responses for exceptions they should set
+ ``request.exception`` and ``request.exc_info`` themselves to indicate
+ the exception that was squashed when generating the response.
+
+ Similar behavior occurs with ``request.invoke_exception_view`` in which
+ the exception properties are set to reflect the exception if a response
+ is successfully generated by the method.
+
+ This is a very minor incompatibility. Most tweens right now would give
+ priority to the raised exception and ignore ``request.exception``. This
+ change just improves and clarifies that bookkeeping by trying to be
+ more clear about the relationship between the response and its squashed
+ exception. See https://github.com/Pylons/pyramid/pull/3029 and
+ https://github.com/Pylons/pyramid/pull/3031
+
1.9a1 (2017-05-01)
==================
@@ -114,23 +139,6 @@ Deprecations
See https://github.com/Pylons/pyramid/pull/2854 and
https://github.com/Pylons/pyramid/pull/3019
-Backward Incompatibilities
---------------------------
-
-- ``request.exception`` and ``request.exc_info`` will only be set if the
- response was generated by the EXCVIEW tween. This is to avoid any confusion
- where a response was generated elsewhere in the pipeline and not in
- direct relation to the original exception. If anyone upstream wants to
- catch and render responses for exceptions they should set
- ``request.exception`` and ``request.exc_info`` themselves to indicate
- the exception that was squashed when generating the response.
-
- This is a very minor incompatibility. Most tweens right now would give
- priority to the raised exception and ignore ``request.exception``. This
- change just improves and clarifies that bookkeeping by trying to be
- more clear about the relationship between the response and its squashed
- exception. See https://github.com/Pylons/pyramid/pull/3029
-
Documentation Changes
---------------------
diff --git a/docs/conf.py b/docs/conf.py
index f09ae325b..e63019c63 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -70,7 +70,7 @@ intersphinx_mapping = {
'plaster': ('http://docs.pylonsproject.org/projects/plaster/en/latest/', None),
'pylonswebframework': ('http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/', None),
'python': ('https://docs.python.org/3', None),
- 'pytest': ('http://pytest.org/latest/', None),
+ 'pytest': ('https://pytest.org/en/latest/', None),
'sphinx': ('http://www.sphinx-doc.org/en/latest', None),
'sqla': ('http://docs.sqlalchemy.org/en/latest', None),
'tm': ('http://docs.pylonsproject.org/projects/pyramid-tm/en/latest/', None),
diff --git a/docs/whatsnew-1.9.rst b/docs/whatsnew-1.9.rst
index b1a406a74..0ba29625c 100644
--- a/docs/whatsnew-1.9.rst
+++ b/docs/whatsnew-1.9.rst
@@ -46,6 +46,15 @@ Deprecations
See https://github.com/Pylons/pyramid/pull/2854 and https://github.com/Pylons/pyramid/pull/3019
+Backward Incompatibilities
+--------------------------
+
+- ``request.exception`` and ``request.exc_info`` will only be set if the response was generated by the EXCVIEW tween. This is to avoid any confusion where a response was generated elsewhere in the pipeline and not in direct relation to the original exception. If anyone upstream wants to catch and render responses for exceptions they should set ``request.exception`` and ``request.exc_info`` themselves to indicate the exception that was squashed when generating the response.
+
+ Similar behavior occurs with :meth:`pyramid.request.Request.invoke_exception_view` in which the exception properties are set to reflect the exception if a response is successfully generated by the method.
+
+ This is a very minor incompatibility. Most tweens right now would give priority to the raised exception and ignore ``request.exception``. This change just improves and clarifies that bookkeeping by trying to be more clear about the relationship between the response and its squashed exception. See https://github.com/Pylons/pyramid/pull/3029 and https://github.com/Pylons/pyramid/pull/3031
+
Documentation Enhancements
--------------------------
diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py
index cab42cf48..2061515b3 100644
--- a/pyramid/tests/test_view.py
+++ b/pyramid/tests/test_view.py
@@ -778,11 +778,11 @@ class TestViewMethodsMixin(unittest.TestCase):
orig_response = request.response = DummyResponse(b'foo')
try:
raise RuntimeError
- except RuntimeError:
+ except RuntimeError as ex:
response = request.invoke_exception_view()
self.assertEqual(response.app_iter, [b'bar'])
- self.assertTrue(request.exception is orig_exc)
- self.assertTrue(request.exc_info is orig_exc_info)
+ self.assertTrue(request.exception is ex)
+ self.assertTrue(request.exc_info[1] is ex)
self.assertTrue(request.response is orig_response)
else: # pragma: no cover
self.fail()
diff --git a/pyramid/tweens.py b/pyramid/tweens.py
index 673429b06..740b6961c 100644
--- a/pyramid/tweens.py
+++ b/pyramid/tweens.py
@@ -1,55 +1,18 @@
import sys
from pyramid.compat import reraise
-from pyramid.exceptions import PredicateMismatch
-from pyramid.interfaces import (
- IExceptionViewClassifier,
- IRequest,
- )
-
-from zope.interface import providedBy
-from pyramid.view import _call_view
+from pyramid.httpexceptions import HTTPNotFound
def _error_handler(request, exc):
# NOTE: we do not need to delete exc_info because this function
# should never be in the call stack of the exception
exc_info = sys.exc_info()
- attrs = request.__dict__
- attrs['exc_info'] = exc_info
- attrs['exception'] = exc
- # clear old generated request.response, if any; it may
- # have been mutated by the view, and its state is not
- # sane (e.g. caching headers)
- if 'response' in attrs:
- del attrs['response']
- # we use .get instead of .__getitem__ below due to
- # https://github.com/Pylons/pyramid/issues/700
- request_iface = attrs.get('request_iface', IRequest)
- provides = providedBy(exc)
try:
- response = _call_view(
- request.registry,
- request,
- exc,
- provides,
- '',
- view_classifier=IExceptionViewClassifier,
- request_iface=request_iface.combined
- )
-
- # if views matched but did not pass predicates then treat the
- # same as not finding any matching views
- except PredicateMismatch:
- response = None
-
- # re-raise the original exception as no exception views were
- # able to handle the error
- if response is None:
- if 'exception' in attrs:
- del attrs['exception']
- if 'exc_info' in attrs:
- del attrs['exc_info']
+ response = request.invoke_exception_view(exc_info)
+ except HTTPNotFound:
+ # re-raise the original exception as no exception views were
+ # able to handle the error
reraise(*exc_info)
return response
@@ -58,7 +21,18 @@ def excview_tween_factory(handler, registry):
""" A :term:`tween` factory which produces a tween that catches an
exception raised by downstream tweens (or the main Pyramid request
handler) and, if possible, converts it into a Response using an
- :term:`exception view`."""
+ :term:`exception view`.
+
+ .. versionchanged:: 1.9
+ The ``request.response`` will be remain unchanged even if the tween
+ handles an exception. Previously it was deleted after handling an
+ exception.
+
+ Also, ``request.exception`` and ``request.exc_info`` are only set if
+ the tween handles an exception and returns a response otherwise they
+ are left at their original values.
+
+ """
def excview_tween(request):
try:
diff --git a/pyramid/view.py b/pyramid/view.py
index 498bdde45..0c1b8cd97 100644
--- a/pyramid/view.py
+++ b/pyramid/view.py
@@ -657,8 +657,19 @@ class ViewMethodsMixin(object):
This method returns a :term:`response` object or raises
:class:`pyramid.httpexceptions.HTTPNotFound` if a matching view cannot
- be found."""
+ be found.
+ If a response is generated then ``request.exception`` and
+ ``request.exc_info`` will be left at the values used to render the
+ response. Otherwise the previous values for ``request.exception`` and
+ ``request.exc_info`` will be restored.
+
+ .. versionchanged:: 1.9
+ The ``request.exception`` and ``request.exc_info`` properties will
+ reflect the exception used to render the response where previously
+ they were reset to the values prior to invoking the method.
+
+ """
if request is None:
request = self
registry = getattr(request, 'registry', None)
@@ -673,7 +684,7 @@ class ViewMethodsMixin(object):
# clear old generated request.response, if any; it may
# have been mutated by the view, and its state is not
# sane (e.g. caching headers)
- with hide_attrs(request, 'exception', 'exc_info', 'response'):
+ with hide_attrs(request, 'response', 'exc_info', 'exception'):
attrs['exception'] = exc
attrs['exc_info'] = exc_info
# we use .get instead of .__getitem__ below due to
@@ -690,6 +701,11 @@ class ViewMethodsMixin(object):
secure=secure,
request_iface=request_iface.combined,
)
- if response is None:
- raise HTTPNotFound
- return response
+
+ if response is None:
+ raise HTTPNotFound
+
+ # successful response, overwrite exception/exc_info
+ attrs['exception'] = exc
+ attrs['exc_info'] = exc_info
+ return response
diff --git a/setup.py b/setup.py
index 6aac12ff8..03416efe7 100644
--- a/setup.py
+++ b/setup.py
@@ -61,7 +61,7 @@ testing_extras = tests_require + [
]
setup(name='pyramid',
- version='1.9a1',
+ version='1.9a2',
description='The Pyramid Web Framework, a Pylons project',
long_description=README + '\n\n' + CHANGES,
classifiers=[