9b591f345b48 — Aurelien Campeas tip 8 years ago
dispatch: unroll mro computation to make it more palatable
1 files changed, 16 insertions(+), 5 deletions(-)

M dispatch.py
M dispatch.py +16 -5
@@ 19,15 19,26 @@ def check_ambiguity(candidates, mros):
 def clos_mro(types_func_map, callsig):
     """ David Mertz's clos mro """
     siglen = len(callsig)
-    table = [(sig, func) for sig, func in types_func_map.iteritems()
-             if len(sig) == siglen
-             and reduce(mul, map(issubclass, callsig, sig))]
+    # table of signature -> function
+    # matching the call signature
+    table = []
+    for signature, func in types_func_map.iteritems():
+        if len(signature) != siglen:
+            continue
+        for callklass, sigklass in zip(callsig, signature):
+            if not issubclass(callklass, sigklass):
+                break
+        else:
+            table.append((signature, func))
     mros = tuple(klass.__mro__ for klass in callsig)
     if len(check_ambiguity(table, mros)) > 1:
         raise TypeError("ambigous call; types=%r; candidates=%r" %
                         (types_func_map, table))
-    return (x[1] for x in sorted((map(proximity, sig, mros), func)
-                  for sig, func in table))
+    sorter = []
+    for signature, func in table:
+        sorter.append((map(proximity, signature, mros), func))
+    sorter.sort()
+    return [elt[1] for elt in sorter]
 
 
 class NoNextMethod(Exception): pass