Return tuple of the function argument names in the order of the function signature.

    :param func: Function
    :type  func: function object

    :param no_self: Flag that indicates whether the function argument *self*,
                    if present, is included in the output (False) or not (True)
    :type  no_self: boolean

    :param no_varargs: Flag that indicates whether keyword arguments are
                       included in the output (True) or not (False)
    :type  no_varargs: boolean

    :rtype: tuple

    For example:

        >>> import pexdoc.pinspect
        >>> class MyClass(object):
        ...     def __init__(self, value, **kwargs):
        ...         pass
        ...
        >>> pexdoc.pinspect.get_function_args(MyClass.__init__)
        ('self', 'value', '**kwargs')
        >>> pexdoc.pinspect.get_function_args(
        ...     MyClass.__init__, no_self=True
        ... )
        ('value', '**kwargs')
        >>> pexdoc.pinspect.get_function_args(
        ...     MyClass.__init__, no_self=True, no_varargs=True
        ... )
        ('value',)
        >>> pexdoc.pinspect.get_function_args(
        ...     MyClass.__init__, no_varargs=True
        ... )
        ('self', 'value')

def get_function_args(func, no_self=False, no_varargs=False):
    """
    Return tuple of the function argument names in the order of the function signature.

    :param func: Function
    :type  func: function object

    :param no_self: Flag that indicates whether the function argument *self*,
                    if present, is included in the output (False) or not (True)
    :type  no_self: boolean

    :param no_varargs: Flag that indicates whether keyword arguments are
                       included in the output (True) or not (False)
    :type  no_varargs: boolean

    :rtype: tuple

    For example:

        >>> import pexdoc.pinspect
        >>> class MyClass(object):
        ...     def __init__(self, value, **kwargs):
        ...         pass
        ...
        >>> pexdoc.pinspect.get_function_args(MyClass.__init__)
        ('self', 'value', '**kwargs')
        >>> pexdoc.pinspect.get_function_args(
        ...     MyClass.__init__, no_self=True
        ... )
        ('value', '**kwargs')
        >>> pexdoc.pinspect.get_function_args(
        ...     MyClass.__init__, no_self=True, no_varargs=True
        ... )
        ('value',)
        >>> pexdoc.pinspect.get_function_args(
        ...     MyClass.__init__, no_varargs=True
        ... )
        ('self', 'value')
    """
    par_dict = signature(func).parameters
    # Mark positional and/or keyword arguments (if any)
    pos = lambda x: x.kind == Parameter.VAR_POSITIONAL
    kw = lambda x: x.kind == Parameter.VAR_KEYWORD
    opts = ["", "*", "**"]
    args = [
        "{prefix}{arg}".format(prefix=opts[pos(value) + 2 * kw(value)], arg=par)
        for par, value in par_dict.items()
    ]
    # Filter out 'self' from parameter list (optional)
    self_filtered_args = (
        args if not args else (args[1 if (args[0] == "self") and no_self else 0 :])
    )
    # Filter out positional or keyword arguments (optional)
    pos = lambda x: (len(x) > 1) and (x[0] == "*") and (x[1] != "*")
    kw = lambda x: (len(x) > 2) and (x[:2] == "**")
    varargs_filtered_args = [
        arg
        for arg in self_filtered_args
        if (not no_varargs) or all([no_varargs, not pos(arg), not kw(arg)])
    ]
    return tuple(varargs_filtered_args)