From 957e7c3e0b9a86ae83e4e2a106144c4a310a4919 Mon Sep 17 00:00:00 2001 From: Jeff Dairiki Date: Wed, 15 Apr 2015 12:18:53 -0700 Subject: Restore request.response if renderer raises exception This fixes two bugs in the ``temporary_response`` context manager: - ``Request.response`` should be restored even if the renderer raises an exception - If ``request.response`` is initially set to ``None``, it should be restored to ``None`` (rather than deleted). References: #1563 --- pyramid/renderers.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 088d451bb..de0b1d27f 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -142,25 +142,22 @@ def render_to_response(renderer_name, return result +_marker = object() + @contextlib.contextmanager def temporary_response(request): """ Temporarily delete request.response and restore it afterward. """ - saved_response = None - # save the current response, preventing the renderer from affecting it attrs = request.__dict__ if request is not None else {} - if 'response' in attrs: - saved_response = attrs['response'] - del attrs['response'] - - yield - - # restore the original response, overwriting any changes - if saved_response is not None: - attrs['response'] = saved_response - elif 'response' in attrs: - del attrs['response'] + saved_response = attrs.pop('response', _marker) + try: + yield + finally: + if saved_response is not _marker: + attrs['response'] = saved_response + elif 'response' in attrs: + del attrs['response'] def get_renderer(renderer_name, package=None): """ Return the renderer object for the renderer ``renderer_name``. -- cgit v1.2.3