Skip to content

Commit

Permalink
back this feature out; we'll try a different approach
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdonc committed Jul 24, 2011
1 parent ac77e36 commit 6434998
Show file tree
Hide file tree
Showing 6 changed files with 0 additions and 238 deletions.
44 changes: 0 additions & 44 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,6 @@ Features
``rendering_val``. This can be used to introspect the value returned by a
view in a BeforeRender subscriber.

- New method: ``pyramid.request.Request.add_view_wrapper``. A view wrapper
is used to wrap the found view callable before it is called by Pyramid's
router. This is a feature usually only used by framework extensions, to
provide, for example, view timing support.

A view wrapper factory must be a callable which accepts three arguments:
``view_callable``, ``request``, and ``exc``. It must return a view
callable. The view callable returned by the factory must implement the
``context, request`` view callable calling convention. For example::

import time

def wrapper_factory(view_callable, request, exc):
def wrapper(context, request):
start = time.time()
result = view_callable(context, request)
end = time.time()
request.view_timing = end - start
return result
return wrapper

The ``view_callable`` argument to the factory will be the view callable
found by Pyramid via view lookup. The ``request`` argument to the factory
will be the current request. The ``exc`` argument to the factory will be
an Exception object if the found view is an exception view; it will be
``None`` otherwise.

View wrappers only last for the duration of a single request. You can add
such a factory for every request by using the
``pyramid.events.NewRequest`` subscriber::

from pyramid.events import subscriber, NewRequest

@subscriber(NewRequest)
def newrequest(event):
event.request.add_view_wrapper(wrapper_factory)

If more than one view wrapper is registered during a single request,
a 'later' view wrapper factory will be called with the result of its
directly former view wrapper factory as its ``view_callable``
argument; this chain will be returned to Pyramid as a single view
callable.


1.1 (2011-07-22)
================

Expand Down
2 changes: 0 additions & 2 deletions docs/api/request.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@

.. automethod:: add_finished_callback

.. automethod:: add_view_wrapper

.. automethod:: route_url

.. automethod:: route_path
Expand Down
62 changes: 0 additions & 62 deletions pyramid/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ class Request(BaseRequest, DeprecatedRequestMethods):
implements(IRequest)
response_callbacks = ()
finished_callbacks = ()
view_wrappers = ()
exception = None
matchdict = None
matched_route = None
Expand All @@ -213,67 +212,6 @@ def tmpl_context(self):
""" Template context (for Pylons apps) """
return TemplateContext()

def add_view_wrapper(self, wrapper):
"""
Add a view wrapper factory. A view wrapper is used to wrap the found
view callable before it is called by Pyramid's router. This is a
feature usually only used by framework extensions, to provide, for
example, view timing support.
A view wrapper factory must be a callable which accepts three
arguments: ``view_callable``, ``request``, and ``exc``. It must
return a view callable. The view callable returned by the factory
must implement the ``context, request`` view callable calling
convention. For example:
.. code-block:: python
import time
def wrapper_factory(view_callable, request, exc):
def wrapper(context, request):
start = time.time()
result = view_callable(context, request)
end = time.time()
request.view_timing = end - start
return result
return wrapper
The ``view_callable`` argument to the factory will be the view
callable found by Pyramid via :term:`view lookup`. The ``request``
argument to the factory will be the current request. The ``exc``
argument to the factory will be an Exception object if the found view
is a :term:`exception view`; it will be ``None`` otherwise.
View wrappers only last for the duration of a single request. You
can add such a factory for every request by using the
:class:`pyramid.events.NewRequest` subscriber:
.. code-block:: python
from pyramid.events import subscriber, NewRequest
@subscriber(NewRequest)
def newrequest(event):
event.request.add_view_wrapper(wrapper_factory)
If more than one view wrapper is registered during a single request,
a 'later' view wrapper factory will be called with the result of its
directly former view wrapper factory as its ``view_callable``
argument; this chain will be returned to Pyramid as a single view
callable.
"""
wrappers = self.view_wrappers
if not wrappers:
wrappers = []
wrappers.append(wrapper)
self.view_wrappers = wrappers

def _wrap_view(self, view, exc=None):
for wrapper in self.view_wrappers:
view = wrapper(view, self, exc)
return view

def add_response_callback(self, callback):
"""
Add a callback to the set of callbacks to be called by the
Expand Down
9 changes: 0 additions & 9 deletions pyramid/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,6 @@ def __call__(self, environ, start_response):
msg = request.path_info
raise HTTPNotFound(msg)
else:
# if there were any view wrappers for the current
# request, use them to wrap the view
if request.view_wrappers:
view_callable = request._wrap_view(view_callable)

response = view_callable(context, request)

# handle exceptions raised during root finding and view-exec
Expand All @@ -183,10 +178,6 @@ def __call__(self, environ, start_response):
if view_callable is None:
raise

if request.view_wrappers:
view_callable = request._wrap_view(view_callable,
exc=why)

response = view_callable(why, request)

has_listeners and notify(NewResponse(request, response))
Expand Down
30 changes: 0 additions & 30 deletions pyramid/tests/test_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,36 +145,6 @@ def callback2(request):
self.assertEqual(inst.called2, True)
self.assertEqual(inst.finished_callbacks, [])

def test_add_view_wrapper(self):
inst = self._makeOne({})
wrapper = object()
inst.add_view_wrapper(wrapper)
self.assertEqual(inst.view_wrappers, [wrapper])

def test_add_view_wrapper_wrappers_exist(self):
inst = self._makeOne({})
inst.view_wrappers = [123]
wrapper = object()
inst.add_view_wrapper(wrapper)
self.assertEqual(inst.view_wrappers, [123, wrapper])

def test__wrap_view_no_wrappers(self):
inst = self._makeOne({})
wrapped = inst._wrap_view(lambda *arg: 'OK')
self.assertEqual(wrapped(), 'OK')

def test__wrap_view_with_wrappers_no_exc(self):
inst = self._makeOne({})
def view(*arg): return 'OK'
def view_wrapper(_view, request, exc):
self.assertEqual(_view, view)
self.assertEqual(request, inst)
self.assertEqual(exc, '123')
return _view
inst.view_wrappers = [view_wrapper]
wrapped = inst._wrap_view(view, exc='123')
self.assertEqual(wrapped(), 'OK')

def test_resource_url(self):
self._registerContextURL()
inst = self._makeOne({})
Expand Down
91 changes: 0 additions & 91 deletions pyramid/tests/test_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,97 +498,6 @@ def callback(request):
exc_raised(NotImplementedError, router, environ, start_response)
self.assertEqual(environ['called_back'], True)

def test_call_request_has_view_wrappers(self):
from zope.interface import Interface
from zope.interface import directlyProvides
class IContext(Interface):
pass
from pyramid.interfaces import IRequest
from pyramid.interfaces import IViewClassifier
from pyramid.interfaces import INewRequest
wrappers = []
class ViewWrapper(object):
def __call__(self, view, request, exc):
self.view = view
self.exc = exc
wrappers.append(self)
return self.wrap
def wrap(self, context, request):
return self.view(context, request)
wrapper1 = ViewWrapper()
wrapper2 = ViewWrapper()
def newrequest(event):
event.request.view_wrappers = [wrapper1, wrapper2]
self.registry.registerHandler(newrequest, (INewRequest,))
context = DummyContext()
directlyProvides(context, IContext)
self._registerTraverserFactory(context, subpath=[''])
response = DummyResponse('200 OK')
response.app_iter = ['OK']
def view(context, request):
return response
environ = self._makeEnviron()
self._registerView(view, '', IViewClassifier, IRequest, IContext)
router = self._makeOne()
start_response = DummyStartResponse()
itera = router(environ, start_response)
wrapper1, wrapper2 = wrappers
self.assertEqual(wrapper1.view, view)
self.assertEqual(wrapper2.view, wrapper1.wrap)
self.assertEqual(wrapper1.exc, None)
self.assertEqual(wrapper2.exc, None)
self.assertEqual(itera, ['OK'])

def test_call_request_has_view_wrappers_in_exception(self):
from zope.interface import Interface
from zope.interface import directlyProvides
class IContext(Interface):
pass
from pyramid.interfaces import IRequest
from pyramid.interfaces import IViewClassifier
from pyramid.interfaces import INewRequest
from pyramid.interfaces import IExceptionViewClassifier
wrappers = []
class ViewWrapper(object):
def __init__(self):
self.views = []
self.exc = []
def __call__(self, view, request, exc):
self.views.append(view)
self.exc.append(exc)
wrappers.append(self)
return self.wrap
def wrap(self, context, request):
return self.views[-1](context, request)
wrapper1 = ViewWrapper()
wrapper2 = ViewWrapper()
def newrequest(event):
event.request.view_wrappers = [wrapper1, wrapper2]
self.registry.registerHandler(newrequest, (INewRequest,))
context = DummyContext()
directlyProvides(context, IContext)
self._registerTraverserFactory(context, subpath=[''])
error = NotImplementedError()
def view(context, request):
raise error
environ = self._makeEnviron()
self._registerView(view, '', IViewClassifier, IRequest, IContext)
exception_response = DummyResponse('404 Not Found')
exception_response.app_iter = ['Not Found']
exception_view = DummyView(exception_response)
environ = self._makeEnviron()
self._registerView(exception_view, '', IExceptionViewClassifier,
IRequest, NotImplementedError)
router = self._makeOne()
start_response = DummyStartResponse()
itera = router(environ, start_response)
wrapper1, wrapper2, wrapper3, wrapper4 = wrappers
self.assertEqual(wrapper1.views, [view, exception_view])
self.assertEqual(wrapper2.views, [wrapper1.wrap, wrapper1.wrap])
self.assertEqual(wrapper1.exc, [None, error])
self.assertEqual(wrapper2.exc, [None, error])
self.assertEqual(itera, ['Not Found'])

def test_call_request_factory_raises(self):
# making sure finally doesnt barf when a request cannot be created
environ = self._makeEnviron()
Expand Down

0 comments on commit 6434998

Please sign in to comment.