summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-11-20 18:36:56 -0500
committerChris McDonough <chrism@plope.com>2012-11-20 18:36:56 -0500
commit71cd93bd78015285db9aaadaa63a5ac9042f6843 (patch)
tree518cdc13b191ce927551745f5b1bead84e8662ac
parente2bacf5565b86dd3394996b8b503ea87da479340 (diff)
downloadpyramid-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.txt9
-rw-r--r--pyramid/config/views.py78
-rw-r--r--pyramid/request.py2
-rw-r--r--pyramid/tests/test_config/test_views.py23
-rw-r--r--pyramid/tests/test_request.py7
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()