@@ 5,24 5,32 @@ def proximity(klass, mro):
def lexicographic_mro(signature, matches):
"dispatch ranking similar to CLOS"
- mros = tuple(klass.mro() for klass in signature)
+ mros = tuple(klass.__mro__ for klass in signature)
return sorted((map(proximity, sig, mros), func)
for sig, func in matches)
+def clos_mro(types_func_map, callsig):
+ 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)))
+ return (x[1] for x in lexicographic_mro(callsig, table))
+
class GF(object):
- def __init__(self):
- self._table = []
+ def __init__(self, mro=clos_mro):
+ self.mro = mro
+ self._reg = {}
self._cache = {}
def register(self, sig, func):
- self._table.append((tuple(sig), func))
+ self._reg[tuple(sig)] = func
self._cache = {}
- def __call__(self, *args):
+ def __call__(self, *args, **kwargs):
sig = tuple(x.__class__ for x in args)
func = self._cache.get(sig)
if func is None:
- self._funcs = self.compute_mro(sig)
+ self._funcs = self.mro(self._reg, sig)
try:
self._cache[sig] = func = self._funcs.next()
except StopIteration:
@@ 33,10 41,4 @@ class GF(object):
func = self._funcs.next()
return func(*args)
- def compute_mro(self, callsig):
- siglen = len(callsig)
- table = ((sig, func) for sig, func in self._table
- if len(sig) == siglen
- and reduce(mul, map(issubclass, callsig, sig)))
- return (x[1] for x in lexicographic_mro(callsig, table))