Checks the callable_ to make sure that it satisfies the given
    expectations.
    expected_args should be an iterable of Arguments in the order you expect to
    receive them.
    expect_starargs means that the function should or should not take a *args
    param. expect_kwargs says the callable should or should not take  **kwargs
    param.
    If expected_args, expect_starargs, or expect_kwargs is Argument.ignore,
    then the checks related to that argument will not occur.

    Example usage:

    callable_check(
        f,
        [Argument('a'), Argument('b', 1)],
        expect_starargs=True,
        expect_kwargs=Argument.ignore
    )

def verify_callable_argspec(callable_,
                            expected_args=Argument.ignore,
                            expect_starargs=Argument.ignore,
                            expect_kwargs=Argument.ignore):
    """
    Checks the callable_ to make sure that it satisfies the given
    expectations.
    expected_args should be an iterable of Arguments in the order you expect to
    receive them.
    expect_starargs means that the function should or should not take a *args
    param. expect_kwargs says the callable should or should not take  **kwargs
    param.
    If expected_args, expect_starargs, or expect_kwargs is Argument.ignore,
    then the checks related to that argument will not occur.

    Example usage:

    callable_check(
        f,
        [Argument('a'), Argument('b', 1)],
        expect_starargs=True,
        expect_kwargs=Argument.ignore
    )
    """
    if not callable(callable_):
        raise NotCallable(callable_)

    expected_arg_list = list(
        expected_args if expected_args is not Argument.ignore else []
    )

    args, starargs, kwargs = Argument.parse_argspec(callable_)

    exc_args = callable_, args, starargs, kwargs

    # Check the *args.
    _expect_extra(
        expect_starargs,
        starargs,
        UnexpectedStarargs,
        NoStarargs,
        exc_args,
    )
    # Check the **kwargs.
    _expect_extra(
        expect_kwargs,
        kwargs,
        UnexpectedKwargs,
        NoKwargs,
        exc_args,
    )

    if expected_args is Argument.ignore:
        # Ignore the argument list checks.
        return

    if len(args) < len(expected_arg_list):
        # One or more argument that we expected was not present.
        raise NotEnoughArguments(
            callable_,
            args,
            starargs,
            kwargs,
            [arg for arg in expected_arg_list if arg not in args],
        )
    elif len(args) > len(expected_arg_list):
        raise TooManyArguments(
            callable_, args, starargs, kwargs
        )

    # Empty argument that will not match with any actual arguments.
    missing_arg = Argument(object(), object())

    for expected, provided in zip_longest(expected_arg_list,
                                          args,
                                          fillvalue=missing_arg):
        if not expected.matches(provided):
            raise MismatchedArguments(
                callable_, args, starargs, kwargs
            )