Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
trac 27971: implement our own version of formatargspec
Browse files Browse the repository at this point in the history
since Python's version is deprecated as of Python 3.5,
and we need this function for formatting with Cython functions.
  • Loading branch information
jhpalmieri committed Jun 19, 2019
1 parent 2393ace commit bbd5b28
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 3 deletions.
117 changes: 116 additions & 1 deletion src/sage/misc/sageinspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -1658,6 +1658,121 @@ def foo(x, a='\')"', b={not (2+1==3):'bar'}): return
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
<class 'inspect._empty'>
sage: formatannotation(a) # py3
'inspect._empty'
sage: b = s.parameters['b'].annotation # py3
sage: b # py3
<class 'int'>
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"""
Expand Down Expand Up @@ -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:]
Expand Down
15 changes: 13 additions & 2 deletions src/sage_setup/docbuild/ext/sage_autodoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
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
Expand All @@ -51,7 +51,8 @@
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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit bbd5b28

Please sign in to comment.