summaryrefslogtreecommitdiff
path: root/routes/mapper.py
diff options
context:
space:
mode:
Diffstat (limited to 'routes/mapper.py')
-rw-r--r--routes/mapper.py98
1 files changed, 57 insertions, 41 deletions
diff --git a/routes/mapper.py b/routes/mapper.py
index 524c177..6382762 100644
--- a/routes/mapper.py
+++ b/routes/mapper.py
@@ -7,7 +7,7 @@ import pkg_resources
from repoze.lru import LRUCache
from routes import request_config
-from routes.util import controller_scan, MatchException, RoutesException
+from routes.util import controller_scan, MatchException, RoutesException, as_unicode
from routes.route import Route
@@ -742,6 +742,9 @@ class Mapper(SubMapperParent):
if val != self:
return val
+ controller = as_unicode(controller, self.encoding)
+ action = as_unicode(action, self.encoding)
+
actionlist = self._gendict.get(controller) or self._gendict.get('*', {})
if not actionlist and not args:
return None
@@ -765,44 +768,60 @@ class Mapper(SubMapperParent):
if len(route.minkeys - route.dotkeys - keys) == 0:
newlist.append(route)
keylist = newlist
+
+ class KeySorter:
+
+ def __init__(self, obj, *args):
+ self.obj = obj
+
+ def __lt__(self, other):
+ return self._keysort(self.obj, other.obj) < 0
- def keysort(a, b):
- """Sorts two sets of sets, to order them ideally for
- matching."""
- am = a.minkeys
- a = a.maxkeys
- b = b.maxkeys
-
- lendiffa = len(keys^a)
- lendiffb = len(keys^b)
- # If they both match, don't switch them
- if lendiffa == 0 and lendiffb == 0:
- return 0
-
- # First, if a matches exactly, use it
- if lendiffa == 0:
- return -1
-
- # Or b matches exactly, use it
- if lendiffb == 0:
- return 1
-
- # Neither matches exactly, return the one with the most in
- # common
- if cmp(lendiffa, lendiffb) != 0:
- return cmp(lendiffa, lendiffb)
-
- # Neither matches exactly, but if they both have just as much
- # in common
- if len(keys&b) == len(keys&a):
- # Then we return the shortest of the two
- return cmp(len(a), len(b))
-
- # Otherwise, we return the one that has the most in common
- else:
- return cmp(len(keys&b), len(keys&a))
+ def _keysort(self, a, b):
+ """Sorts two sets of sets, to order them ideally for
+ matching."""
+ am = a.minkeys
+ a = a.maxkeys
+ b = b.maxkeys
+
+ lendiffa = len(keys^a)
+ lendiffb = len(keys^b)
+ # If they both match, don't switch them
+ if lendiffa == 0 and lendiffb == 0:
+ return 0
+
+ # First, if a matches exactly, use it
+ if lendiffa == 0:
+ return -1
+
+ # Or b matches exactly, use it
+ if lendiffb == 0:
+ return 1
+
+ # Neither matches exactly, return the one with the most in
+ # common
+ if self._compare(lendiffa, lendiffb) != 0:
+ return self._compare(lendiffa, lendiffb)
+
+ # Neither matches exactly, but if they both have just as much
+ # in common
+ if len(keys&b) == len(keys&a):
+ # Then we return the shortest of the two
+ return self._compare(len(a), len(b))
+
+ # Otherwise, we return the one that has the most in common
+ else:
+ return self._compare(len(keys&b), len(keys&a))
+
+ def _compare(self, obj1, obj2):
+ if obj1 < obj2:
+ return -1
+ elif obj1 < obj2:
+ return 1
+ else:
+ return 0
- keylist.sort(keysort)
+ keylist.sort(key=KeySorter)
if cacheset:
sortcache[cachekey] = keylist
@@ -814,10 +833,7 @@ class Mapper(SubMapperParent):
kval = kargs.get(key)
if not kval:
continue
- if isinstance(kval, str):
- kval = kval.decode(self.encoding)
- else:
- kval = unicode(kval)
+ kval = as_unicode(kval, self.encoding)
if kval != route.defaults[key] and not callable(route.defaults[key]):
fail = True
break