def generic(func):
_sentinel = object()<EOL>def _by_class(*args, **kw):<EOL><INDENT>cls = args[<NUM_LIT:0>].__class__<EOL>for t in type(cls.__name__, (cls,object), {}).__mro__:<EOL><INDENT>f = _gbt(t, _sentinel)<EOL>if f is not _sentinel:<EOL><INDENT>return f(*args, **kw)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return func(*args, **kw)<EOL><DEDENT><DEDENT>_by_type = {object: func}<EOL>try:<EOL><INDENT>_by_type[InstanceType] = _by_class<EOL><DEDENT>except NameError:   <EOL><INDENT>pass<EOL><DEDENT>_gbt = _by_type.get<EOL>def when_type(*types):<EOL><INDENT>"""<STR_LIT>"""<EOL>for t in types:<EOL><INDENT>if not isinstance(t, classtypes):<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>" % (t,)<EOL>)<EOL><DEDENT><DEDENT>def decorate(f):<EOL><INDENT>for t in types:<EOL><INDENT>if _by_type.setdefault(t,f) is not f:<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>" % (func, t)<EOL>)<EOL><DEDENT><DEDENT>return f<EOL><DEDENT>return decorate<EOL><DEDENT>_by_object = {}<EOL>_gbo = _by_object.get<EOL>def when_object(*obs):<EOL><INDENT>"""<STR_LIT>"""<EOL>def decorate(f):<EOL><INDENT>for o in obs:<EOL><INDENT>if _by_object.setdefault(id(o), (o,f))[<NUM_LIT:1>] is not f:<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>" % (func, o)<EOL>)<EOL><DEDENT><DEDENT>return f<EOL><DEDENT>return decorate<EOL><DEDENT>def dispatch(*args, **kw):<EOL><INDENT>f = _gbo(id(args[<NUM_LIT:0>]), _sentinel)<EOL>if f is _sentinel:<EOL><INDENT>for t in type(args[<NUM_LIT:0>]).__mro__:<EOL><INDENT>f = _gbt(t, _sentinel)<EOL>if f is not _sentinel:<EOL><INDENT>return f(*args, **kw)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return func(*args, **kw)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return f[<NUM_LIT:1>](*args, **kw)<EOL><DEDENT><DEDENT>dispatch.__name__       = func.__name__<EOL>dispatch.__dict__       = func.__dict__.copy()<EOL>dispatch.__doc__        = func.__doc__<EOL>dispatch.__module__     = func.__module__<EOL>dispatch.when_type = when_type<EOL>dispatch.when_object = when_object<EOL>dispatch.default = func<EOL>dispatch.has_object = lambda o: id(o) in _by_object<EOL>dispatch.has_type   = lambda t: t in _by_type<EOL>return dispatch<EOL>
Create a simple generic function