summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2017-06-05 11:48:51 -0500
committerGitHub <noreply@github.com>2017-06-05 11:48:51 -0500
commit22215dfabb3e8b2b2ca494299766d4703c75f268 (patch)
tree5c8a04670128ebfb20fb3bfcc2f381cb06fcb0b5
parent9ef3311eed03dded36acb8b7cacb67343f253db0 (diff)
parent4f66355fb5d7e6fe319742cb50f263425a88c57f (diff)
downloadpyramid-22215dfabb3e8b2b2ca494299766d4703c75f268.tar.gz
pyramid-22215dfabb3e8b2b2ca494299766d4703c75f268.tar.bz2
pyramid-22215dfabb3e8b2b2ca494299766d4703c75f268.zip
Merge pull request #3060 from Pylons/push_threadlocals_exception_view
When invoking an exception view, push the new threadlocals
-rw-r--r--pyramid/tests/test_view.py19
-rw-r--r--pyramid/threadlocal.py2
-rw-r--r--pyramid/view.py39
3 files changed, 47 insertions, 13 deletions
diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py
index 2061515b3..a9ce2234d 100644
--- a/pyramid/tests/test_view.py
+++ b/pyramid/tests/test_view.py
@@ -790,6 +790,8 @@ class TestViewMethodsMixin(unittest.TestCase):
def test_it_supports_alternate_requests(self):
def exc_view(exc, request):
self.assertTrue(request is other_req)
+ from pyramid.threadlocal import get_current_request
+ self.assertTrue(get_current_request() is other_req)
return DummyResponse(b'foo')
self.config.add_view(exc_view, context=RuntimeError)
request = self._makeOne()
@@ -816,6 +818,23 @@ class TestViewMethodsMixin(unittest.TestCase):
else: # pragma: no cover
self.fail()
+ def test_it_raises_if_no_registry(self):
+ request = self._makeOne()
+ del request.registry
+ from pyramid.threadlocal import manager
+ manager.push({'registry': None, 'request': request})
+ try:
+ raise RuntimeError
+ except RuntimeError:
+ try:
+ request.invoke_exception_view()
+ except RuntimeError as e:
+ self.assertEqual(e.args[0], "Unable to retrieve registry")
+ else: # pragma: no cover
+ self.fail()
+ finally:
+ manager.pop()
+
def test_it_supports_alternate_exc_info(self):
def exc_view(exc, request):
self.assertTrue(request.exc_info is exc_info)
diff --git a/pyramid/threadlocal.py b/pyramid/threadlocal.py
index 638f7b7b0..9429fe953 100644
--- a/pyramid/threadlocal.py
+++ b/pyramid/threadlocal.py
@@ -31,7 +31,7 @@ class ThreadLocalManager(threading.local):
self.stack[:] = []
def defaults():
- return {'request':None, 'registry':global_registry}
+ return {'request': None, 'registry': global_registry}
manager = ThreadLocalManager(default=defaults)
diff --git a/pyramid/view.py b/pyramid/view.py
index 0c1b8cd97..47b756ad8 100644
--- a/pyramid/view.py
+++ b/pyramid/view.py
@@ -28,7 +28,11 @@ from pyramid.httpexceptions import (
default_exceptionresponse_view,
)
-from pyramid.threadlocal import get_current_registry
+from pyramid.threadlocal import (
+ get_current_registry,
+ manager,
+ )
+
from pyramid.util import hide_attrs
_marker = object()
@@ -675,8 +679,13 @@ class ViewMethodsMixin(object):
registry = getattr(request, 'registry', None)
if registry is None:
registry = get_current_registry()
+
+ if registry is None:
+ raise RuntimeError("Unable to retrieve registry")
+
if exc_info is None:
exc_info = sys.exc_info()
+
exc = exc_info[1]
attrs = request.__dict__
context_iface = providedBy(exc)
@@ -690,17 +699,23 @@ class ViewMethodsMixin(object):
# 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,
- context_iface,
- '',
- view_types=None,
- view_classifier=IExceptionViewClassifier,
- secure=secure,
- request_iface=request_iface.combined,
- )
+
+ manager.push({'request': request, 'registry': registry})
+
+ try:
+ response = _call_view(
+ registry,
+ request,
+ exc,
+ context_iface,
+ '',
+ view_types=None,
+ view_classifier=IExceptionViewClassifier,
+ secure=secure,
+ request_iface=request_iface.combined,
+ )
+ finally:
+ manager.pop()
if response is None:
raise HTTPNotFound