summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-07 15:33:44 -0400
committerChris McDonough <chrism@plope.com>2011-08-07 15:33:44 -0400
commitda13810625ae92f3d76a36dcb88827a18ae4c8f8 (patch)
treea282828398aa42cfc3d36778866e0cde2fcea65f
parent3c9845ccf38b9adc9dd1e4c01a6291f12642db1e (diff)
downloadpyramid-da13810625ae92f3d76a36dcb88827a18ae4c8f8.tar.gz
pyramid-da13810625ae92f3d76a36dcb88827a18ae4c8f8.tar.bz2
pyramid-da13810625ae92f3d76a36dcb88827a18ae4c8f8.zip
prevent both mainhandler and excview tween from needing to send a NewResponse event
-rw-r--r--pyramid/router.py230
-rw-r--r--pyramid/tweens.py5
2 files changed, 116 insertions, 119 deletions
diff --git a/pyramid/router.py b/pyramid/router.py
index 79fd7992b..248ab3b5b 100644
--- a/pyramid/router.py
+++ b/pyramid/router.py
@@ -39,15 +39,11 @@ class Router(object):
self.request_factory = q(IRequestFactory, default=Request)
tweens = q(ITweens)
if tweens is None:
- self.handle_request = excview_tween_factory(self.handle_request,
- registry)
- else:
- self.handle_request = tweens(self.handle_request, registry)
-
+ tweens = excview_tween_factory
+ self.handle_request = tweens(self.handle_request, registry)
self.root_policy = self.root_factory # b/w compat
self.registry = registry
settings = registry.settings
-
if settings is not None:
self.debug_notfound = settings['debug_notfound']
self.debug_routematch = settings['debug_routematch']
@@ -56,117 +52,107 @@ class Router(object):
attrs = request.__dict__
registry = attrs['registry']
- try: # matches finally: if request is not None
- request.request_iface = IRequest
- context = None
- routes_mapper = self.routes_mapper
- debug_routematch = self.debug_routematch
- adapters = registry.adapters
- has_listeners = registry.has_listeners
- notify = registry.notify
- logger = self.logger
-
- has_listeners and notify(NewRequest(request))
- # find the root object
- root_factory = self.root_factory
- if routes_mapper is not None:
- info = routes_mapper(request)
- match, route = info['match'], info['route']
- if route is None:
- if debug_routematch:
- msg = ('no route matched for url %s' %
- request.url)
- logger and logger.debug(msg)
- else:
- # TODO: kill off bfg.routes.* environ keys
- # when traverser requires request arg, and
- # cant cope with environ anymore (they are
- # docs-deprecated as of BFG 1.3)
- environ = request.environ
- environ['bfg.routes.route'] = route
- environ['bfg.routes.matchdict'] = match
- attrs['matchdict'] = match
- attrs['matched_route'] = route
-
- if debug_routematch:
- msg = (
- 'route matched for url %s; '
- 'route_name: %r, '
- 'path_info: %r, '
- 'pattern: %r, '
- 'matchdict: %r, '
- 'predicates: %r' % (
- request.url,
- route.name,
- request.path_info,
- route.pattern, match,
- route.predicates)
- )
- logger and logger.debug(msg)
-
- request.request_iface = registry.queryUtility(
- IRouteRequest,
- name=route.name,
- default=IRequest)
-
- root_factory = route.factory or self.root_factory
-
- root = root_factory(request)
- attrs['root'] = root
-
- # find a context
- traverser = adapters.queryAdapter(root, ITraverser)
- if traverser is None:
- traverser = ResourceTreeTraverser(root)
- tdict = traverser(request)
-
- context, view_name, subpath, traversed, vroot, vroot_path = (
- tdict['context'],
- tdict['view_name'],
- tdict['subpath'],
- tdict['traversed'],
- tdict['virtual_root'],
- tdict['virtual_root_path']
- )
-
- attrs.update(tdict)
- has_listeners and notify(ContextFound(request))
-
- # find a view callable
- context_iface = providedBy(context)
- view_callable = adapters.lookup(
- (IViewClassifier, request.request_iface, context_iface),
- IView, name=view_name, default=None)
-
- # invoke the view callable
- if view_callable is None:
- if self.debug_notfound:
+ request.request_iface = IRequest
+ context = None
+ routes_mapper = self.routes_mapper
+ debug_routematch = self.debug_routematch
+ adapters = registry.adapters
+ has_listeners = registry.has_listeners
+ notify = registry.notify
+ logger = self.logger
+
+ has_listeners and notify(NewRequest(request))
+ # find the root object
+ root_factory = self.root_factory
+ if routes_mapper is not None:
+ info = routes_mapper(request)
+ match, route = info['match'], info['route']
+ if route is None:
+ if debug_routematch:
+ msg = ('no route matched for url %s' %
+ request.url)
+ logger and logger.debug(msg)
+ else:
+ # TODO: kill off bfg.routes.* environ keys
+ # when traverser requires request arg, and
+ # cant cope with environ anymore (they are
+ # docs-deprecated as of BFG 1.3)
+ environ = request.environ
+ environ['bfg.routes.route'] = route
+ environ['bfg.routes.matchdict'] = match
+ attrs['matchdict'] = match
+ attrs['matched_route'] = route
+
+ if debug_routematch:
msg = (
- 'debug_notfound of url %s; path_info: %r, '
- 'context: %r, view_name: %r, subpath: %r, '
- 'traversed: %r, root: %r, vroot: %r, '
- 'vroot_path: %r' % (
- request.url, request.path_info, context,
- view_name, subpath, traversed, root, vroot,
- vroot_path)
+ 'route matched for url %s; '
+ 'route_name: %r, '
+ 'path_info: %r, '
+ 'pattern: %r, '
+ 'matchdict: %r, '
+ 'predicates: %r' % (
+ request.url,
+ route.name,
+ request.path_info,
+ route.pattern, match,
+ route.predicates)
)
logger and logger.debug(msg)
- else:
- msg = request.path_info
- raise HTTPNotFound(msg)
- else:
- response = view_callable(context, request)
-
- has_listeners and notify(NewResponse(request, response))
-
- if request.response_callbacks:
- request._process_response_callbacks(response)
- return response
+ request.request_iface = registry.queryUtility(
+ IRouteRequest,
+ name=route.name,
+ default=IRequest)
+
+ root_factory = route.factory or self.root_factory
+
+ root = root_factory(request)
+ attrs['root'] = root
+
+ # find a context
+ traverser = adapters.queryAdapter(root, ITraverser)
+ if traverser is None:
+ traverser = ResourceTreeTraverser(root)
+ tdict = traverser(request)
+
+ context, view_name, subpath, traversed, vroot, vroot_path = (
+ tdict['context'],
+ tdict['view_name'],
+ tdict['subpath'],
+ tdict['traversed'],
+ tdict['virtual_root'],
+ tdict['virtual_root_path']
+ )
+
+ attrs.update(tdict)
+ has_listeners and notify(ContextFound(request))
+
+ # find a view callable
+ context_iface = providedBy(context)
+ view_callable = adapters.lookup(
+ (IViewClassifier, request.request_iface, context_iface),
+ IView, name=view_name, default=None)
+
+ # invoke the view callable
+ if view_callable is None:
+ if self.debug_notfound:
+ msg = (
+ 'debug_notfound of url %s; path_info: %r, '
+ 'context: %r, view_name: %r, subpath: %r, '
+ 'traversed: %r, root: %r, vroot: %r, '
+ 'vroot_path: %r' % (
+ request.url, request.path_info, context,
+ view_name, subpath, traversed, root, vroot,
+ vroot_path)
+ )
+ logger and logger.debug(msg)
+ else:
+ msg = request.path_info
+ raise HTTPNotFound(msg)
+ else:
+ response = view_callable(context, request)
- finally:
- if request is not None and request.finished_callbacks:
- request._process_finished_callbacks()
+ return response
def __call__(self, environ, start_response):
"""
@@ -177,14 +163,28 @@ class Router(object):
return an iterable.
"""
registry = self.registry
+ has_listeners = self.registry.has_listeners
+ notify = self.registry.notify
request = self.request_factory(environ)
threadlocals = {'registry':registry, 'request':request}
manager = self.threadlocal_manager
manager.push(threadlocals)
+ request.registry = registry
try:
- request.registry = registry
- response = self.handle_request(request)
- return response(request.environ, start_response)
+
+ try:
+ response = self.handle_request(request)
+ has_listeners and notify(NewResponse(request, response))
+
+ if request.response_callbacks:
+ request._process_response_callbacks(response)
+
+ return response(request.environ, start_response)
+
+ finally:
+ if request.finished_callbacks:
+ request._process_finished_callbacks()
+
finally:
manager.pop()
diff --git a/pyramid/tweens.py b/pyramid/tweens.py
index 56945b165..0039b0e39 100644
--- a/pyramid/tweens.py
+++ b/pyramid/tweens.py
@@ -4,7 +4,6 @@ from pyramid.interfaces import IExceptionViewClassifier
from pyramid.interfaces import IView
from pyramid.interfaces import ITweens
-from pyramid.events import NewResponse
from zope.interface import providedBy
from zope.interface import implements
@@ -13,9 +12,7 @@ def excview_tween_factory(handler, registry):
exception raised by downstream tweens (or the main Pyramid request
handler) and, if possible, converts it into a Response using an
:term:`exception view`."""
- has_listeners = registry.has_listeners
adapters = registry.adapters
- notify = registry.notify
def excview_tween(request):
attrs = request.__dict__
@@ -38,8 +35,8 @@ def excview_tween_factory(handler, registry):
if view_callable is None:
raise
response = view_callable(exc, request)
- has_listeners and notify(NewResponse(request, response))
finally:
+ # prevent leakage
attrs['exc_info'] = None
return response