functools.singledispatch picks an implementation based on the type of the first argument. Build your own (without using functools.singledispatch).
Implement a decorator dispatch(func). It returns a wrapper with:
register(cls): a decorator that registers an implementation for cls. It can also be used bare (@f.register), in which case the class comes from the annotation of the function's first parameter.registry: a dict from class to function, including object mapped to the original functiontype(arg).__mro__ that's registered, so subclasses inherit their parent's implementation and bool falls back to int