def add_handler_spec(f, handler_spec, *, kwargs=None):
    """
    Attach a handler specification (see :class:`HandlerSpec`) to a function.

    :param f: Function to attach the handler specification to.
    :param handler_spec: Handler specification to attach to the function.
    :type handler_spec: :class:`HandlerSpec`
    :param kwargs: additional keyword arguments passed to the function
       carried in the handler spec.
    :type kwargs: :class:`dict`

    :raises ValueError: if the handler was registered with
       different `kwargs` before

    This uses a private attribute, whose exact name is an implementation
    detail. The `handler_spec` is stored in a :class:`dict` bound to the
    attribute.

    .. versionadded:: 0.11

       The `kwargs` argument. If two handlers with the same spec, but
       different arguments are registered for one function, an error
       will be raised. So you should always include all possible
       arguments, this is the responsibility of the calling decorator.
    """
    handler_dict = automake_magic_attr(f)
    if kwargs is None:
        kwargs = {}
    if kwargs != handler_dict.setdefault(handler_spec, kwargs):
        raise ValueError(
            "The additional keyword arguments to the handler are incompatible")
Attach a handler specification (see :class:`HandlerSpec`) to a function.

    :param f: Function to attach the handler specification to.
    :param handler_spec: Handler specification to attach to the function.
    :type handler_spec: :class:`HandlerSpec`
    :param kwargs: additional keyword arguments passed to the function
       carried in the handler spec.
    :type kwargs: :class:`dict`

    :raises ValueError: if the handler was registered with
       different `kwargs` before

    This uses a private attribute, whose exact name is an implementation
    detail. The `handler_spec` is stored in a :class:`dict` bound to the
    attribute.

    .. versionadded:: 0.11

       The `kwargs` argument. If two handlers with the same spec, but
       different arguments are registered for one function, an error
       will be raised. So you should always include all possible
       arguments, this is the responsibility of the calling decorator.