summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-02 21:10:32 -0400
committerChris McDonough <chrism@plope.com>2011-08-02 21:10:32 -0400
commitd15920e8e4ebf90e0213ad79017f621ea0e9781e (patch)
tree71ce2a8a014249bf41de2deca7101d528e13d548
parent1e04ba77eb69bca09fa0e8e212fa02454194f401 (diff)
downloadpyramid-d15920e8e4ebf90e0213ad79017f621ea0e9781e.tar.gz
pyramid-d15920e8e4ebf90e0213ad79017f621ea0e9781e.tar.bz2
pyramid-d15920e8e4ebf90e0213ad79017f621ea0e9781e.zip
first cut
-rw-r--r--pyramid/router.py286
1 files changed, 143 insertions, 143 deletions
diff --git a/pyramid/router.py b/pyramid/router.py
index ddec23cdb..73e97a94b 100644
--- a/pyramid/router.py
+++ b/pyramid/router.py
@@ -57,143 +57,160 @@ class Router(object):
self.debug_routematch = settings['debug_routematch']
def handle_request(self, request):
+ exc = None
attrs = request.__dict__
registry = attrs['registry']
- 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
-
- try: # matches except Exception (exception view execution)
- 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:
+
+ try: # matches finally: manager.pop()
+ manager = self.threadlocal_manager
+ threadlocals = { 'registry':registry, 'request':request}
+ manager.push(threadlocals)
+ 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
+
+ try: # matches except Exception (exception view execution)
+ 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_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_iface, context_iface),
+ IView, name=view_name, default=None)
+
+ # invoke the view callable
+ if view_callable is None:
+ if self.debug_notfound:
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)
+ '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)
-
- 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_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:
- 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 there were any view wrappers for the current
+ # request, use them to wrap the view
- response = view_callable(context, request)
+ response = view_callable(context, request)
- # handle exceptions raised during root finding and view-exec
- except Exception, why:
- # clear old generated request.response, if any; it may
- # have been mutated by the view, and its state is not
- # sane (e.g. caching headers)
- if 'response' in attrs:
- del attrs['response']
+ # handle exceptions raised during root finding and view-exec
+ except Exception, exc:
+ # WARNING: do not assign the result of sys.exc_info() to a
+ # local var here, doing so will cause a leak
+ attrs['exc_info'] = sys.exc_info()
+ attrs['exception'] = exc
- attrs['exception'] = why
- attrs['exc_info'] = sys.exc_info()
+ # clear old generated request.response, if any; it may
+ # have been mutated by the view, and its state is not
+ # sane (e.g. caching headers)
+ if 'response' in attrs:
+ del attrs['response']
- for_ = (IExceptionViewClassifier,
- request_iface.combined,
- providedBy(why))
- view_callable = adapters.lookup(for_, IView,
- default=None)
+ for_ = (IExceptionViewClassifier,
+ request_iface.combined,
+ providedBy(exc))
+ view_callable = adapters.lookup(for_, IView,
+ default=None)
- if view_callable is None:
- raise
+ if view_callable is None:
+ raise
- response = view_callable(why, request)
+ response = view_callable(exc, request)
- has_listeners and notify(NewResponse(request, response))
+ has_listeners and notify(NewResponse(request, response))
- if request.response_callbacks:
- request._process_response_callbacks(response)
+ if request.response_callbacks:
+ request._process_response_callbacks(response)
- return response
+ return request, response, attrs.get('exc_info')
+
+ finally:
+ manager.pop()
+ if request is not None:
+ try:
+ if request.finished_callbacks:
+ request._process_finished_callbacks()
+ finally:
+ request.exc_info = None
def __call__(self, environ, start_response):
"""
@@ -203,25 +220,8 @@ class Router(object):
within the application registry; call ``start_response`` and
return an iterable.
"""
- registry = self.registry
- manager = self.threadlocal_manager
- request = None
- threadlocals = {'registry':registry, 'request':request}
- manager.push(threadlocals)
-
- try:
- try:
- request = self.request_factory(environ)
- threadlocals['request'] = request
- request.registry = registry
- response = self.handle_request(request)
- finally:
- if request is not None:
- if request.finished_callbacks:
- request._process_finished_callbacks()
- request.exc_info = None # avoid leak
-
- return response(request.environ, start_response)
- finally:
- manager.pop()
+ request = self.request_factory(environ)
+ request.registry = self.registry
+ request, response = self.handle_request(request)[:2]
+ return response(request.environ, start_response)