@@ 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