summaryrefslogtreecommitdiff
path: root/pecan/routing.py
diff options
context:
space:
mode:
Diffstat (limited to 'pecan/routing.py')
-rw-r--r--pecan/routing.py42
1 files changed, 23 insertions, 19 deletions
diff --git a/pecan/routing.py b/pecan/routing.py
index fc1a7d4..47eb354 100644
--- a/pecan/routing.py
+++ b/pecan/routing.py
@@ -8,6 +8,10 @@ from .util import iscontroller
__all__ = ['lookup_controller', 'find_object']
+class PecanNotFound(Exception):
+ pass
+
+
class NonCanonicalPath(Exception):
'''
Exception Raised when a non-canonical path is encountered when 'walking'
@@ -19,22 +23,20 @@ class NonCanonicalPath(Exception):
self.remainder = remainder
-def lookup_controller(obj, url_path):
+def lookup_controller(obj, remainder):
'''
Traverses the requested url path and returns the appropriate controller
object, including default routes.
Handles common errors gracefully.
'''
- remainder = url_path
notfound_handlers = []
-
while True:
try:
obj, remainder = find_object(obj, remainder, notfound_handlers)
handle_security(obj)
return obj, remainder
- except exc.HTTPNotFound:
+ except PecanNotFound:
while notfound_handlers:
name, obj, remainder = notfound_handlers.pop()
if name == '_default':
@@ -52,7 +54,7 @@ def lookup_controller(obj, url_path):
remainder == ['']
and len(obj._pecan['argspec'].args) > 1
):
- raise
+ raise exc.HTTPNotFound
return lookup_controller(*result)
else:
raise exc.HTTPNotFound
@@ -84,22 +86,24 @@ def find_object(obj, remainder, notfound_handlers):
prev_obj = None
while True:
if obj is None:
- raise exc.HTTPNotFound
+ raise PecanNotFound
if iscontroller(obj):
return obj, remainder
# are we traversing to another controller
cross_boundary(prev_obj, obj)
-
- if remainder and remainder[0] == '':
- index = getattr(obj, 'index', None)
- if iscontroller(index):
- return index, remainder[1:]
- elif not remainder:
+ try:
+ next_obj, rest = remainder[0], remainder[1:]
+ if next_obj == '':
+ index = getattr(obj, 'index', None)
+ if iscontroller(index):
+ return index, rest
+ except IndexError:
# the URL has hit an index method without a trailing slash
index = getattr(obj, 'index', None)
if iscontroller(index):
- raise NonCanonicalPath(index, remainder[1:])
+ raise NonCanonicalPath(index, [])
+
default = getattr(obj, '_default', None)
if iscontroller(default):
notfound_handlers.append(('_default', default, remainder))
@@ -110,12 +114,12 @@ def find_object(obj, remainder, notfound_handlers):
route = getattr(obj, '_route', None)
if iscontroller(route):
- next, next_remainder = route(remainder)
- cross_boundary(route, next)
- return next, next_remainder
+ next_obj, next_remainder = route(remainder)
+ cross_boundary(route, next_obj)
+ return next_obj, next_remainder
if not remainder:
- raise exc.HTTPNotFound
- next, remainder = remainder[0], remainder[1:]
+ raise PecanNotFound
prev_obj = obj
- obj = getattr(obj, next, None)
+ remainder = rest
+ obj = getattr(obj, next_obj, None)