diff --git a/CHANGES b/CHANGES index 8a06d67aa..5a12230ce 100644 --- a/CHANGES +++ b/CHANGES @@ -36,6 +36,8 @@ Bugs fixed * PR#155: Added support for some C++11 function qualifiers. * Fix: 'make gettext' caused UnicodeDecodeError when templates contain utf-8 encoded strings. +* #828: use inspect.getfullargspec() to be able to document functions with + keyword-only arguments on Python 3. * #1157: Combination of 'globaltoc.html' and hidden toctree caused exception. * #1159: fix wrong generation of objects inventory for Python modules, and add a workaround in intersphinx to fix handling of affected inventories. diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 95b7cb1ee..0212eb7ea 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -19,7 +19,43 @@ from sphinx.util import force_decode from sphinx.util.pycompat import bytes -if sys.version_info >= (2, 5): +if sys.version_info >= (3, 0): + from functools import partial + def getargspec(func): + """Like inspect.getargspec but supports functools.partial as well.""" + if inspect.ismethod(func): + func = func.__func__ + if type(func) is partial: + orig_func = func.func + argspec = inspect.getfullargspec(orig_func) + args = list(argspec[0]) + defaults = list(argspec[3]) + kwoargs = list(argspec[4]) + kwodefs = dict(argspec[5]) + if func.args: + args = args[len(func.args):] + for arg in func.keywords or (): + try: + i = args.index(arg) - len(args) + del args[i] + try: + del defaults[i] + except IndexError: + pass + except ValueError: # must be a kwonly arg + i = kwoargs.index(arg) + del kwoargs[i] + del kwodefs[arg] + return inspect.FullArgSpec(args, argspec[1], argspec[2], + tuple(defaults), kwoargs, + kwodefs, argspec[6]) + while hasattr(func, '__wrapped__'): + func = func.__wrapped__ + if not inspect.isfunction(func): + raise TypeError('%r is not a Python function' % func) + return inspect.getfullargspec(func) + +elif sys.version_info >= (2, 5): from functools import partial def getargspec(func): """Like inspect.getargspec but supports functools.partial as well."""