#from multimethod import dispatch
# module inlined here
class MultiMethod(object):
registry = {}
def __init__(self, name):
self.name = name
self.typemap = {}
def __call__(self, *args):
types = tuple(arg.__class__ for arg in args)
function = self.typemap.get(types)
if function is None:
raise TypeError("no match")
return function(*args)
def register(self, types, function):
if types in self.typemap:
raise TypeError("duplicate registration")
self.typemap[types] = function
def dispatch(*types):
def register(function):
function = getattr(function, "__lastreg__", function)
name = function.__name__
mm = MultiMethod.registry.get(name)
if mm is None:
mm = MultiMethod.registry[name] = MultiMethod(name)
mm.register(types, function)
mm.__lastreg__ = function
return mm
return register
def assert_full_type_coverage(multi_func):
type_names, type_pairs = set(), set()
for (t1, t2) in MultiMethod.registry[multi_func.name].typemap:
type_names.add(t1.__name__)
type_names.add(t2.__name__)
type_pairs.add((t1.__name__, t2.__name__))
for n1 in type_names:
for n2 in type_names:
if (n1, n2) not in type_pairs:
assert False, "Missing function: %s(%s, %s)" % (multi_func.name, n1, n2)
#----------------------------------------------
class Wheel(object):
def __init__(self, name):
self.name = name
class Engine(object): pass
class Body(object): pass
class Car(object): pass
class CarElementPrint(object): pass
class CarElementDo(object): pass
@dispatch(Wheel, CarElementPrint)
def visit(obj, action):
print "Visiting", obj.name, "wheel"
@dispatch(Engine, CarElementPrint)
def visit(obj, action):
print "Visiting engine"
@dispatch(Body, CarElementPrint)
def visit(obj, action):
print "Visiting thebody"
@dispatch(Car, CarElementPrint)
def visit(obj, action):
print "Visiting car"
@dispatch(Wheel, CarElementDo)
def visit(obj, action):
print "Kicking my", obj.name, "wheel"
@dispatch(Engine, CarElementDo)
def visit(obj, action):
print "Starting my engine"
@dispatch(Body, CarElementDo)
def visit(obj, action):
print "Moving my thebody"
@dispatch(Car, CarElementDo)
def visit(obj, action):
print "Starting my car"
elements = [Wheel("front left"),
Wheel("front right"),
Wheel("back left"),
Wheel("back right"),
Body(),
Engine(),
Car()]
for action in [CarElementPrint(), CarElementDo()]:
for elem in elements:
visit(elem, action)
print