diff -up src/sage/misc/sageinspect.py.orig src/sage/misc/sageinspect.py --- src/sage/misc/sageinspect.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/misc/sageinspect.py 2019-09-11 08:58:24.194413905 -0600 @@ -1658,6 +1658,121 @@ def sage_getargspec(obj): defaults = None return inspect.ArgSpec(args, varargs, varkw, defaults) +def formatannotation(annotation, base_module=None): + """ + This is taken from Python 3.7's inspect.py; the only change is to + add documentation. + + INPUT: + + - ``annotation`` -- annotation for a function + - ``base_module`` (optional, default ``None``) + + This is only relevant with Python 3, so the doctests are marked + accordingly. + + EXAMPLES:: + + sage: from sage.misc.sageinspect import formatannotation + sage: import inspect + sage: def foo(a, *, b:int, **kwargs): # py3 + ....: pass + ....: + sage: s = inspect.signature(foo) # py3 + + sage: a = s.parameters['a'].annotation # py3 + sage: a # py3 + + sage: formatannotation(a) # py3 + 'inspect._empty' + + sage: b = s.parameters['b'].annotation # py3 + sage: b # py3 + + sage: formatannotation(b) # py3 + 'int' + """ + if getattr(annotation, '__module__', None) == 'typing': + return repr(annotation).replace('typing.', '') + if isinstance(annotation, type): + if annotation.__module__ in ('builtins', base_module): + return annotation.__qualname__ + return annotation.__module__+'.'+annotation.__qualname__ + return repr(annotation) + +def sage_formatargspec(args, varargs=None, varkw=None, defaults=None, + kwonlyargs=(), kwonlydefaults={}, annotations={}, + formatarg=str, + formatvarargs=lambda name: '*' + name, + formatvarkw=lambda name: '**' + name, + formatvalue=lambda value: '=' + repr(value), + formatreturns=lambda text: ' -> ' + text, + formatannotation=formatannotation): + """ + Format an argument spec from the values returned by getfullargspec. + + The first seven arguments are (args, varargs, varkw, defaults, + kwonlyargs, kwonlydefaults, annotations). The other five arguments + are the corresponding optional formatting functions that are called to + turn names and values into strings. The last argument is an optional + function to format the sequence of arguments. + + This is taken from Python 3.7's inspect.py, where it is + deprecated. The only change, aside from documentation (this + paragraph and the next, plus doctests), is to remove the + deprecation warning. + + Sage uses this function to format arguments, as obtained by + :func:`sage_getargspec`. Since :func:`sage_getargspec` works for + Cython functions while Python's inspect module does not, it makes + sense to keep this function for formatting instances of + ``inspect.ArgSpec``. + + EXAMPLES:: + + sage: from sage.misc.sageinspect import sage_formatargspec + sage: from inspect import formatargspec # deprecated in Python 3 + sage: args = ['a', 'b', 'c'] + sage: defaults = [3] + sage: sage_formatargspec(args, defaults=defaults) + '(a, b, c=3)' + sage: formatargspec(args, defaults=defaults) == sage_formatargspec(args, defaults=defaults) # py2 + True + sage: formatargspec(args, defaults=defaults) == sage_formatargspec(args, defaults=defaults) # py3 + doctest:...: DeprecationWarning: `formatargspec` is deprecated since Python 3.5. Use `signature` and the `Signature` object directly + True + """ + def formatargandannotation(arg): + result = formatarg(arg) + if arg in annotations: + result += ': ' + formatannotation(annotations[arg]) + return result + specs = [] + if defaults: + firstdefault = len(args) - len(defaults) + for i, arg in enumerate(args): + spec = formatargandannotation(arg) + if defaults and i >= firstdefault: + spec = spec + formatvalue(defaults[i - firstdefault]) + specs.append(spec) + if varargs is not None: + specs.append(formatvarargs(formatargandannotation(varargs))) + else: + if kwonlyargs: + specs.append('*') + if kwonlyargs: + for kwonlyarg in kwonlyargs: + spec = formatargandannotation(kwonlyarg) + if kwonlydefaults and kwonlyarg in kwonlydefaults: + spec += formatvalue(kwonlydefaults[kwonlyarg]) + specs.append(spec) + if varkw is not None: + specs.append(formatvarkw(formatargandannotation(varkw))) + result = '(' + ', '.join(specs) + ')' + if 'return' in annotations: + result += formatreturns(formatannotation(annotations['return'])) + return result + def sage_getdef(obj, obj_name=''): r""" @@ -1693,7 +1808,7 @@ def sage_getdef(obj, obj_name=''): """ try: spec = sage_getargspec(obj) - s = str(inspect.formatargspec(*spec)) + s = str(sage_formatargspec(*spec)) s = s.strip('(').strip(')').strip() if s[:4] == 'self': s = s[4:] diff -up src/sage_setup/docbuild/ext/sage_autodoc.py.orig src/sage_setup/docbuild/ext/sage_autodoc.py --- src/sage_setup/docbuild/ext/sage_autodoc.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage_setup/docbuild/ext/sage_autodoc.py 2019-09-11 08:59:53.728932096 -0600 @@ -38,7 +38,7 @@ from six import PY2, iteritems, itervalu import sphinx from sphinx.errors import ExtensionError from sphinx.ext.autodoc.importer import mock, import_object, get_object_members -from sphinx.ext.autodoc.inspector import format_annotation, formatargspec +from sphinx.ext.autodoc.inspector import format_annotation from sphinx.locale import _, __ from sphinx.pycode import ModuleAnalyzer from sphinx.errors import ExtensionError, PycodeError @@ -51,7 +51,8 @@ from sphinx.util.inspect import Signatur from sphinx.util.inspect import getargspec from sage.misc.sageinspect import (sage_getdoc_original, - sage_getargspec, isclassinstance) + sage_getargspec, isclassinstance, + sage_formatargspec) from sage.misc.lazy_import import LazyImport # This is used to filter objects of classes that inherit from @@ -123,6 +124,16 @@ def bool_option(arg): return True +def formatargspec(function, args, varargs=None, varkw=None, defaults=None, + kwonlyargs=(), kwonlydefaults={}, annotations={}): + """ + Sphinx's version of formatargspec is deprecated, so use Sage's instead. + """ + return sage_formatargspec(args, varargs=varargs, varkw=varkw, defaults=defaults, + kwonlyargs=kwonlyargs, kwonlydefaults=kwonlydefaults, + annotations=annotations) + + class AutodocReporter(object): """ A reporter replacement that assigns the correct source name