diff options
| author | Chris McDonough <chrism@plope.com> | 2012-11-20 18:36:56 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2012-11-20 18:36:56 -0500 |
| commit | 71cd93bd78015285db9aaadaa63a5ac9042f6843 (patch) | |
| tree | 518cdc13b191ce927551745f5b1bead84e8662ac | |
| parent | e2bacf5565b86dd3394996b8b503ea87da479340 (diff) | |
| download | pyramid-71cd93bd78015285db9aaadaa63a5ac9042f6843.tar.gz pyramid-71cd93bd78015285db9aaadaa63a5ac9042f6843.tar.bz2 pyramid-71cd93bd78015285db9aaadaa63a5ac9042f6843.zip | |
- Small microspeed enhancement which anticipates that a
``pyramid.response.Response`` object is likely to be returned from a view.
Some code is shortcut if the class of the object returned by a view is this
class. A similar microoptimization was done to
``pyramid.request.Request.is_response``.
| -rw-r--r-- | CHANGES.txt | 9 | ||||
| -rw-r--r-- | pyramid/config/views.py | 78 | ||||
| -rw-r--r-- | pyramid/request.py | 2 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_views.py | 23 | ||||
| -rw-r--r-- | pyramid/tests/test_request.py | 7 |
5 files changed, 85 insertions, 34 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index f5c5c9449..22abf63d9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,15 @@ Next release ============ +Features +-------- + +- Small microspeed enhancement which anticipates that a + ``pyramid.response.Response`` object is likely to be returned from a view. + Some code is shortcut if the class of the object returned by a view is this + class. A similar microoptimization was done to + ``pyramid.request.Request.is_response``. + Bug Fixes --------- diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 745b6f810..4e5af480d 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -59,6 +59,8 @@ from pyramid.registry import ( Deferred, ) +from pyramid.response import Response + from pyramid.security import NO_PERMISSION_REQUIRED from pyramid.static import static_view from pyramid.threadlocal import get_current_registry @@ -341,25 +343,28 @@ class ViewDeriver(object): def rendered_view(context, request): renderer = view_renderer result = view(context, request) - registry = self.registry - # this must adapt, it can't do a simple interface check - # (avoid trying to render webob responses) - response = registry.queryAdapterOrSelf(result, IResponse) - if response is None: - attrs = getattr(request, '__dict__', {}) - if 'override_renderer' in attrs: - # renderer overridden by newrequest event or other - renderer_name = attrs.pop('override_renderer') - renderer = renderers.RendererHelper( - name=renderer_name, - package=self.kw.get('package'), - registry = registry) - if '__view__' in attrs: - view_inst = attrs.pop('__view__') - else: - view_inst = getattr(view, '__original_view__', view) - response = renderer.render_view(request, result, view_inst, - context) + if result.__class__ is Response: # potential common case + response = result + else: + registry = self.registry + # this must adapt, it can't do a simple interface check + # (avoid trying to render webob responses) + response = registry.queryAdapterOrSelf(result, IResponse) + if response is None: + attrs = getattr(request, '__dict__', {}) + if 'override_renderer' in attrs: + # renderer overridden by newrequest event or other + renderer_name = attrs.pop('override_renderer') + renderer = renderers.RendererHelper( + name=renderer_name, + package=self.kw.get('package'), + registry = registry) + if '__view__' in attrs: + view_inst = attrs.pop('__view__') + else: + view_inst = getattr(view, '__original_view__', view) + response = renderer.render_view(request, result, view_inst, + context) return response return rendered_view @@ -368,21 +373,26 @@ class ViewDeriver(object): registry = self.registry def viewresult_to_response(context, request): result = view(context, request) - response = registry.queryAdapterOrSelf(result, IResponse) - if response is None: - if result is None: - append = (' You may have forgotten to return a value from ' - 'the view callable.') - elif isinstance(result, dict): - append = (' You may have forgotten to define a renderer in ' - 'the view configuration.') - else: - append = '' - msg = ('Could not convert return value of the view callable %s ' - 'into a response object. ' - 'The value returned was %r.' + append) - - raise ValueError(msg % (view_description(view), result)) + if result.__class__ is Response: # common case + response = result + else: + response = registry.queryAdapterOrSelf(result, IResponse) + if response is None: + if result is None: + append = (' You may have forgotten to return a value ' + 'from the view callable.') + elif isinstance(result, dict): + append = (' You may have forgotten to define a ' + 'renderer in the view configuration.') + else: + append = '' + + msg = ('Could not convert return value of the view ' + 'callable %s into a response object. ' + 'The value returned was %r.' + append) + + raise ValueError(msg % (view_description(view), result)) + return response return viewresult_to_response diff --git a/pyramid/request.py b/pyramid/request.py index 9e275c2c0..27ab337de 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -372,6 +372,8 @@ class Request(BaseRequest, DeprecatedRequestMethodsMixin, URLMethodsMixin, def is_response(self, ob): """ Return ``True`` if the object passed as ``ob`` is a valid response object, ``False`` otherwise.""" + if ob.__class__ is Response: + return True registry = self.registry adapted = registry.queryAdapterOrSelf(ob, IResponse) if adapted is None: diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 8324eb2b9..bb4c5d519 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -2483,6 +2483,29 @@ class TestViewDeriver(unittest.TestCase): else: # pragma: no cover raise AssertionError + def test_function_returns_true_Response_no_renderer(self): + from pyramid.response import Response + r = Response('Hello') + def view(request): + return r + deriver = self._makeOne() + result = deriver(view) + self.assertFalse(result is view) + response = result(None, None) + self.assertEqual(response, r) + + def test_function_returns_true_Response_with_renderer(self): + from pyramid.response import Response + r = Response('Hello') + def view(request): + return r + renderer = object() + deriver = self._makeOne(renderer=renderer) + result = deriver(view) + self.assertFalse(result is view) + response = result(None, None) + self.assertEqual(response, r) + def test_requestonly_default_method_returns_non_adaptable(self): request = DummyRequest() class AView(object): diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index 945e36a7f..565c6377e 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -230,6 +230,13 @@ class TestRequest(unittest.TestCase): request.registry = self.config.registry self.assertEqual(request.is_response('abc'), False) + def test_is_response_true_ob_is_pyramid_response(self): + from pyramid.response import Response + r = Response('hello') + request = self._makeOne() + request.registry = self.config.registry + self.assertEqual(request.is_response(r), True) + def test_is_response_false_adapter_is_not_self(self): from pyramid.interfaces import IResponse request = self._makeOne() |
