summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2013-08-30 11:48:56 -0400
committerChris McDonough <chrism@plope.com>2013-08-30 11:48:56 -0400
commit97ed56d766298ee042305ff8712df5f1fc3fbe3a (patch)
tree95ec8a89ba91b3da0bad0af91b49ee53582501e3
parent097b4915f490bad988333a69377944e0b64a65f5 (diff)
downloadpyramid-97ed56d766298ee042305ff8712df5f1fc3fbe3a.tar.gz
pyramid-97ed56d766298ee042305ff8712df5f1fc3fbe3a.tar.bz2
pyramid-97ed56d766298ee042305ff8712df5f1fc3fbe3a.zip
allow exception view registrations for HTTPException to override default exception view; closes #985
-rw-r--r--CHANGES.txt5
-rw-r--r--pyramid/httpexceptions.py15
-rw-r--r--pyramid/tests/pkgs/exceptionviewapp/__init__.py8
-rw-r--r--pyramid/tests/pkgs/exceptionviewapp/views.py7
-rw-r--r--pyramid/tests/test_httpexceptions.py6
-rw-r--r--pyramid/tests/test_integration.py4
6 files changed, 34 insertions, 11 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index d3d3f64ce..334785424 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -163,6 +163,11 @@ Features
Bug Fixes
---------
+- It was not possible to use ``pyramid.httpexceptions.HTTPException`` as
+ the ``context`` of an exception view as very general catchall for
+ http-related exceptions when you wanted that exception view to override the
+ default exception view. See https://github.com/Pylons/pyramid/issues/985
+
- When the ``pyramid.reload_templates`` setting was true, and a Chameleon
template was reloaded, and the renderer specification named a macro
(e.g. ``foo#macroname.pt``), renderings of the template after the template
diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py
index d8832570b..10568b26e 100644
--- a/pyramid/httpexceptions.py
+++ b/pyramid/httpexceptions.py
@@ -149,11 +149,8 @@ def _no_escape(value):
value = text_type(value)
return value
-class HTTPException(Exception): # bw compat
- """ Base class for all :term:`exception response` objects."""
-
@implementer(IExceptionResponse)
-class WSGIHTTPException(Response, HTTPException):
+class HTTPException(Response, Exception):
## You should set in subclasses:
# code = 200
@@ -253,7 +250,7 @@ ${body}''')
'html_comment':html_comment,
}
body_tmpl = self.body_template_obj
- if WSGIHTTPException.body_template_obj is not body_tmpl:
+ if HTTPException.body_template_obj is not body_tmpl:
# Custom template; add headers to args
for k, v in environ.items():
if (not k.startswith('wsgi.')) and ('.' in k):
@@ -289,7 +286,9 @@ ${body}''')
self.prepare(environ)
return Response.__call__(self, environ, start_response)
-class HTTPError(WSGIHTTPException):
+WSGIHTTPException = HTTPException # b/c post 1.5
+
+class HTTPError(HTTPException):
"""
base class for exceptions with status codes in the 400s and 500s
@@ -297,7 +296,7 @@ class HTTPError(WSGIHTTPException):
and that any work in progress should not be committed.
"""
-class HTTPRedirection(WSGIHTTPException):
+class HTTPRedirection(HTTPException):
"""
base class for exceptions with status codes in the 300s (redirections)
@@ -307,7 +306,7 @@ class HTTPRedirection(WSGIHTTPException):
condition.
"""
-class HTTPOk(WSGIHTTPException):
+class HTTPOk(HTTPException):
"""
Base class for exceptions with status codes in the 200s (successful
responses)
diff --git a/pyramid/tests/pkgs/exceptionviewapp/__init__.py b/pyramid/tests/pkgs/exceptionviewapp/__init__.py
index f169e0cd5..ffc1b47c6 100644
--- a/pyramid/tests/pkgs/exceptionviewapp/__init__.py
+++ b/pyramid/tests/pkgs/exceptionviewapp/__init__.py
@@ -1,5 +1,8 @@
+from pyramid.httpexceptions import HTTPException
+
def includeme(config):
config.add_route('route_raise_exception', 'route_raise_exception')
+ config.add_route('route_raise_httpexception', 'route_raise_httpexception')
config.add_route('route_raise_exception2', 'route_raise_exception2',
factory='.models.route_factory')
config.add_route('route_raise_exception3', 'route_raise_exception3',
@@ -21,3 +24,8 @@ def includeme(config):
route_name='route_raise_exception4')
config.add_view('.views.whoa', context='.models.AnException',
route_name='route_raise_exception4')
+ config.add_view('.views.raise_httpexception',
+ route_name='route_raise_httpexception')
+ config.add_view('.views.catch_httpexception', context=HTTPException)
+
+
diff --git a/pyramid/tests/pkgs/exceptionviewapp/views.py b/pyramid/tests/pkgs/exceptionviewapp/views.py
index 33b97671e..4953056bc 100644
--- a/pyramid/tests/pkgs/exceptionviewapp/views.py
+++ b/pyramid/tests/pkgs/exceptionviewapp/views.py
@@ -1,5 +1,6 @@
from webob import Response
from .models import AnException
+from pyramid.httpexceptions import HTTPBadRequest
def no(request):
return Response('no')
@@ -15,3 +16,9 @@ def whoa(request):
def raise_exception(request):
raise AnException()
+
+def raise_httpexception(request):
+ raise HTTPBadRequest
+
+def catch_httpexception(request):
+ return Response('caught')
diff --git a/pyramid/tests/test_httpexceptions.py b/pyramid/tests/test_httpexceptions.py
index 0061907ba..d0779e080 100644
--- a/pyramid/tests/test_httpexceptions.py
+++ b/pyramid/tests/test_httpexceptions.py
@@ -57,10 +57,10 @@ class Test__no_escape(unittest.TestCase):
duo = DummyUnicodeObject()
self.assertEqual(self._callFUT(duo), text_('42'))
-class TestWSGIHTTPException(unittest.TestCase):
+class TestHTTPException(unittest.TestCase):
def _getTargetClass(self):
- from pyramid.httpexceptions import WSGIHTTPException
- return WSGIHTTPException
+ from pyramid.httpexceptions import HTTPException
+ return HTTPException
def _getTargetSubclass(self, code='200', title='OK',
explanation='explanation', empty_body=False):
diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py
index eda4ae9f3..391310432 100644
--- a/pyramid/tests/test_integration.py
+++ b/pyramid/tests/test_integration.py
@@ -465,6 +465,10 @@ class TestExceptionViewsApp(IntegrationBase, unittest.TestCase):
res = self.testapp.get('/route_raise_exception4', status=200)
self.assertTrue(b'whoa' in res.body)
+ def test_raise_httpexception(self):
+ res = self.testapp.get('/route_raise_httpexception', status=200)
+ self.assertTrue(b'caught' in res.body)
+
class TestConflictApp(unittest.TestCase):
package = 'pyramid.tests.pkgs.conflictapp'
def _makeConfig(self):