'Find the appropriate overloaded function; don\'t call it.
This won\'t work for old-style classes or classes without __mro__.'

def find_func(self, types):

    func = self.registry.get(types)
    if (func is not None):
        return func
    mros = tuple((t.__mro__ for t in types))
    n = len(mros)
    candidates = [sig for sig in self.registry if ((len(sig) == n) and all(((t in mro) for (t, mro) in zip(sig, mros))))]
    if (not candidates):
        return self.default_func
    if (len(candidates) == 1):
        return self.registry[candidates[0]]
    def dominates(dom, sub, orders=tuple((dict(((t, i) for (i, t) in enumerate(mro))) for mro in mros))):
        if (dom is sub):
            return False
        return all(((order[d] <= order[s]) for (d, s, order) in zip(dom, sub, orders)))
    candidates = [cand for cand in candidates if (not any((dominates(dom, cand) for dom in candidates)))]
    if (len(candidates) == 1):
        return self.registry[candidates[0]]
    funcs = set((self.registry[cand] for cand in candidates))
    if (len(funcs) == 1):
        return funcs.pop()
    raise TypeError(('ambigous    call;    types=%r;    candidates=%r' % (types, candidates)))
