takes args and kwargs, as they were passed into the command instance
    being executed with __call__, and compose them into a flat list that
    will eventually be fed into exec.  example:

    with this call:

        sh.ls("-l", "/tmp", color="never")

    this function receives

        args = ['-l', '/tmp']
        kwargs = {'color': 'never'}

    and produces

        ['-l', '/tmp', '--color=never']

def compile_args(args, kwargs, sep, prefix):
    """ takes args and kwargs, as they were passed into the command instance
    being executed with __call__, and compose them into a flat list that
    will eventually be fed into exec.  example:

    with this call:

        sh.ls("-l", "/tmp", color="never")

    this function receives

        args = ['-l', '/tmp']
        kwargs = {'color': 'never'}

    and produces

        ['-l', '/tmp', '--color=never']
        
    """
    processed_args = []
    encode = encode_to_py3bytes_or_py2str

    # aggregate positional args
    for arg in args:
        if isinstance(arg, (list, tuple)):
            if isinstance(arg, GlobResults) and not arg:
                arg = [arg.path]

            for sub_arg in arg:
                processed_args.append(encode(sub_arg))
        elif isinstance(arg, dict):
            processed_args += aggregate_keywords(arg, sep, prefix, raw=True)
        else:
            processed_args.append(encode(arg))

    # aggregate the keyword arguments
    processed_args += aggregate_keywords(kwargs, sep, prefix)

    return processed_args