diff options
| author | Chris McDonough <chrism@plope.com> | 2011-08-07 15:33:44 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-08-07 15:33:44 -0400 |
| commit | da13810625ae92f3d76a36dcb88827a18ae4c8f8 (patch) | |
| tree | a282828398aa42cfc3d36778866e0cde2fcea65f | |
| parent | 3c9845ccf38b9adc9dd1e4c01a6291f12642db1e (diff) | |
| download | pyramid-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.py | 230 | ||||
| -rw-r--r-- | pyramid/tweens.py | 5 |
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 |
