diff options
| author | Michael Merickel <michael@merickel.org> | 2017-06-05 11:48:51 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-06-05 11:48:51 -0500 |
| commit | 22215dfabb3e8b2b2ca494299766d4703c75f268 (patch) | |
| tree | 5c8a04670128ebfb20fb3bfcc2f381cb06fcb0b5 | |
| parent | 9ef3311eed03dded36acb8b7cacb67343f253db0 (diff) | |
| parent | 4f66355fb5d7e6fe319742cb50f263425a88c57f (diff) | |
| download | pyramid-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.py | 19 | ||||
| -rw-r--r-- | pyramid/threadlocal.py | 2 | ||||
| -rw-r--r-- | pyramid/view.py | 39 |
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 |
