def _extract_first_argument(args: tuple, kwargs: dict):
    """
    Returns the tuple (X, _args, _kwargs) where X is the first argument (
    found in either args or kwargs), and _args, _kwargs are the same (with X
    removed)

    >>> _extract_first_argument((1,2,3), {'d': 4})
    (1, [2, 3], {'d': 4})
    >>> _extract_first_argument((), {'d': 4, 'e': 5})
    (4, [], {'e': 5})

    """
    if len(args) > 0:
        first_arg_val, *_args = args
        return first_arg_val, _args, kwargs
    else:
        first_arg_name = next(iter(kwargs), None)
        if first_arg_name is None:
            raise ValueError(
                "You need to have at least one argument (the data (aka 'X'))"
            )
        first_arg_val = kwargs.pop(first_arg_name)
        return first_arg_val, [], kwargs