1"""
2    getargspec excerpted from:
3
4    sphinx.util.inspect
5    ~~~~~~~~~~~~~~~~~~~
6    Helpers for inspecting Python modules.
7    :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
8    :license: BSD, see LICENSE for details.
9"""
10
11import inspect
12
13# Unmodified from sphinx below this line
14
15from functools import partial
16
17def getargspec(func):
18    """Like inspect.getargspec but supports functools.partial as well."""
19    if inspect.ismethod(func):
20        func = func.__func__
21    if type(func) is partial:
22        orig_func = func.func
23        argspec = getargspec(orig_func)
24        args = list(argspec[0])
25        defaults = list(argspec[3] or ())
26        kwoargs = list(argspec[4])
27        kwodefs = dict(argspec[5] or {})
28        if func.args:
29            args = args[len(func.args):]
30        for arg in func.keywords or ():
31            try:
32                i = args.index(arg) - len(args)
33                del args[i]
34                try:
35                    del defaults[i]
36                except IndexError:
37                    pass
38            except ValueError:   # must be a kwonly arg
39                i = kwoargs.index(arg)
40                del kwoargs[i]
41                del kwodefs[arg]
42        return inspect.FullArgSpec(args, argspec[1], argspec[2],
43                                   tuple(defaults), kwoargs,
44                                   kwodefs, argspec[6])
45    while hasattr(func, '__wrapped__'):
46        func = func.__wrapped__
47    if not inspect.isfunction(func):
48        raise TypeError('%r is not a Python function' % func)
49    return inspect.getfullargspec(func)
50
51