def get_signature(argspec):
    """
    Return a tuple (args, defaults, varargs, kwargs) from a function
    signature. If there are no varargs, then `varargs` is None.

    PARAMETERS
    ----------
    f : function or method
        Note that f cannot necessarily be an arbitrary callable, and
        also that many decorators will clobber the metadata needed. If
        you use `wrapt` for decorators, the metadata
        should still be available.

    RETURNS
    -------
    args : list
        A list of the string names of all regular arguments (not unpacked
        varargs or keyword args) of `f`.
    varargs : {None, str}
        If the signature of f contains a varargs positional argument,
        this will be the string name of that argument. (For example if
        the argument list contains `*myvarargs` we get `"myvarargs"``).
        If there is no vararg argument, this will be None.
    kwargs : {None, str}
        If the signature of f contains a packed keyword argument,
        this will be the string name of that argument. (For example if
        the argument list contains `**mykwargs` we get `"mykwargs"``).
        If there is no packed keyword argument, this will be None.
    defaults : list
        A list of all the default values for regular arguments of `f`.
        In general it can be shorter than `args`, and `defaults` will
        be aligned with `args[-len(defaults):]`

    EXAMPLES
    --------
    >>> def f(a, b=3, c=5, *stuff, **morestuff): pass

    >>> get_signature(f)
    # (['a', 'b', 'c'], [3, 5], 'stuff', 'morestuff')

    >>> def f(x, y): pass

    >>> get_signature(f)
    # (['x', 'y'], [], None, None)
    """
    f_args = argspec.args
    f_varargs = argspec.varargs
    f_kwargs = argspec.keywords
    f_defaults = [] if argspec.defaults is None else list(argspec.defaults)
    return f_args, f_varargs, f_kwargs, f_defaults
