# HG changeset patch # User Aurelien Campeas # Date 1392503796 -3600 # Sat Feb 15 23:36:36 2014 +0100 # Node ID 9b591f345b4898bdaaf2a19b962ebb90678d1f1e # Parent 84e34cc7d1bd433abcefc9dcd0a0815e43414a07 dispatch: unroll mro computation to make it more palatable diff --git a/dispatch.py b/dispatch.py --- a/dispatch.py +++ b/dispatch.py @@ -19,15 +19,26 @@ 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