Registers `func` as an implementation on `dispatcher`.

def register(dispatcher, func, *, hook=None):
    """
    Registers `func` as an implementation on `dispatcher`.
    """
    wrapper = None
    if isinstance(func, (classmethod, staticmethod)):
        wrapper = type(func)
        func = func.__func__
    ensure_function(func)
    if isinstance(dispatcher, (classmethod, staticmethod)):
        wrapper = None
    dp = unwrap(dispatcher)
    try:
        dp.__functions
    except AttributeError:
        raise OverloadingError("%r has not been set up as an overloaded function." % dispatcher)
    fn = unwrap(func)
    if hook:
        dp.__hooks[hook] = func
    else:
        signature = get_signature(fn)
        for i, type_ in enumerate(signature.types):
            if not isinstance(type_, type):
                raise OverloadingError(
                  "Failed to overload function '{0}': parameter '{1}' has "
                  "an annotation that is not a type."
                  .format(dp.__name__, signature.parameters[i]))
        for fninfo in dp.__functions:
            dup_sig = sig_cmp(signature, fninfo.signature)
            if dup_sig and signature.has_varargs == fninfo.signature.has_varargs:
                raise OverloadingError(
                  "Failed to overload function '{0}': non-unique signature ({1})."
                  .format(dp.__name__, str.join(', ', (_repr(t) for t in dup_sig))))
        # All clear; register the function.
        dp.__functions.append(FunctionInfo(func, signature))
        dp.__cache.clear()
        dp.__maxlen = max(dp.__maxlen, len(signature.parameters))
        if typing:
            # For each parameter position and name, compute a bitwise union of complexity
            # values over all registered signatures. Retain the result for parameters where
            # a nonzero value occurs at least twice and at least one of those values is >= 2.
            # Such parameters require deep type-checking during function resolution.
            position_values = defaultdict(lambda: 0)
            keyword_values = defaultdict(lambda: 0)
            position_counter = Counter()
            keyword_counter = Counter()
            for fninfo in dp.__functions:
                sig = fninfo.signature
                complex_positions = {i: v for i, v in enumerate(sig.complexity) if v}
                complex_keywords = {p: v for p, v in zip(sig.parameters, sig.complexity) if v}
                for i, v in complex_positions.items():
                    position_values[i] |= v
                for p, v in complex_keywords.items():
                    keyword_values[p] |= v
                position_counter.update(complex_positions.keys())
                keyword_counter.update(complex_keywords.keys())
            dp.__complex_positions = {
                i: v for i, v in position_values.items() if v >= 2 and position_counter[i] > 1}
            dp.__complex_parameters = {
                p: v for p, v in keyword_values.items() if v >= 2 and keyword_counter[p] > 1}
    if wrapper is None:
        wrapper = lambda x: x
    if func.__name__ == dp.__name__:
        # The returned function is going to be bound to the invocation name
        # in the calling scope, so keep returning the dispatcher.
        return wrapper(dispatcher)
    else:
        return wrapper(func)