diff options
| author | Chris McDonough <chrism@plope.com> | 2015-04-15 18:00:41 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2015-04-15 18:00:41 -0400 |
| commit | bedd5f21f6f2c7660824cf901c24a31cad8f737d (patch) | |
| tree | 3f89fcc4c028844ed4a309abfe068bb31ab717f7 | |
| parent | 50906f073be6c619dfd9a2062a444ff53a87d018 (diff) | |
| parent | ec1ec3f781409f6b0832c0ef11965484220b2c12 (diff) | |
| download | pyramid-bedd5f21f6f2c7660824cf901c24a31cad8f737d.tar.gz pyramid-bedd5f21f6f2c7660824cf901c24a31cad8f737d.tar.bz2 pyramid-bedd5f21f6f2c7660824cf901c24a31cad8f737d.zip | |
Merge branch 'master' of github.com:Pylons/pyramid
| -rw-r--r-- | RELEASING.txt | 10 | ||||
| -rw-r--r-- | pyramid/renderers.py | 23 | ||||
| -rw-r--r-- | pyramid/tests/test_renderers.py | 42 |
3 files changed, 61 insertions, 14 deletions
diff --git a/RELEASING.txt b/RELEASING.txt index 6d25ecb62..87ff62c53 100644 --- a/RELEASING.txt +++ b/RELEASING.txt @@ -24,7 +24,9 @@ Releasing Pyramid communicate with contributors). - Copy relevant changes (delta bug fixes) from CHANGES.txt to - docs/whatsnew-X.X (if it's a major release). + docs/whatsnew-X.X (if it's a major release). Minor releases should + include a link under "Bug Fix Releases" to the minor feature + changes in CHANGES.txt . - update README.rst to use correct versions of badges and URLs according to each branch and context, i.e., RTD "latest" == GitHub/Travis "1.x-branch". @@ -49,6 +51,12 @@ Releasing Pyramid $ python setup.py sdist bdist_wheel $ twine upload dist/pyramid-X.X-* +- Edit Pylons/pylonshq/templates/home/home.mako for minor and major updates. + +- Edit Pylons/pylonshq/templates/home/inside.rst for major updates only. + +- Edit Pylons/pylonsrtd/pylonsrtd/docs/pyramid.rst for all updates. + - Edit `http://wiki.python.org/moin/WebFrameworks <http://wiki.python.org/moin/WebFrameworks>`_. 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``. diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index ed6344a40..542eea9aa 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -592,6 +592,48 @@ class Test_render_to_response(unittest.TestCase): self.assertEqual(result.body, b'{"a": 1}') self.assertFalse('response' in request.__dict__) +class Test_temporary_response(unittest.TestCase): + def _callFUT(self, request): + from pyramid.renderers import temporary_response + return temporary_response(request) + + def test_restores_response(self): + request = testing.DummyRequest() + orig_response = request.response + with self._callFUT(request): + request.response = object() + self.assertEqual(request.response, orig_response) + + def test_restores_response_on_exception(self): + request = testing.DummyRequest() + orig_response = request.response + try: + with self._callFUT(request): + request.response = object() + raise RuntimeError() + except RuntimeError: + self.assertEqual(request.response, orig_response) + else: # pragma: no cover + self.fail("RuntimeError not raised") + + def test_restores_response_to_none(self): + request = testing.DummyRequest(response=None) + with self._callFUT(request): + request.response = object() + self.assertEqual(request.response, None) + + def test_deletes_response(self): + request = testing.DummyRequest() + with self._callFUT(request): + request.response = object() + self.assertTrue('response' not in request.__dict__) + + def test_does_not_delete_response_if_no_response_to_delete(self): + request = testing.DummyRequest() + with self._callFUT(request): + pass + self.assertTrue('response' not in request.__dict__) + class Test_get_renderer(unittest.TestCase): def setUp(self): self.config = testing.setUp() |
