summaryrefslogtreecommitdiff
path: root/sphinx/util/inspect.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/util/inspect.py')
-rw-r--r--sphinx/util/inspect.py174
1 files changed, 20 insertions, 154 deletions
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 1ce5bb900..2d665c1a6 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -21,8 +21,9 @@ from inspect import ( # NOQA
from io import StringIO
from typing import Any, Callable, Mapping, List, Tuple
+from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.util import logging
-from sphinx.util.typing import NoneType
+from sphinx.util.typing import stringify as stringify_annotation
if sys.version_info > (3, 7):
from types import (
@@ -381,11 +382,11 @@ class Signature:
return None
def format_args(self, show_annotation: bool = True) -> str:
- def format_param_annotation(param: inspect.Parameter) -> str:
+ def get_annotation(param: inspect.Parameter) -> Any:
if isinstance(param.annotation, str) and param.name in self.annotations:
- return self.format_annotation(self.annotations[param.name])
+ return self.annotations[param.name]
else:
- return self.format_annotation(param.annotation)
+ return param.annotation
args = []
last_kind = None
@@ -409,7 +410,7 @@ class Signature:
arg.write(param.name)
if show_annotation and param.annotation is not param.empty:
arg.write(': ')
- arg.write(format_param_annotation(param))
+ arg.write(stringify_annotation(get_annotation(param)))
if param.default is not param.empty:
if param.annotation is param.empty or show_annotation is False:
arg.write('=')
@@ -422,13 +423,13 @@ class Signature:
arg.write(param.name)
if show_annotation and param.annotation is not param.empty:
arg.write(': ')
- arg.write(format_param_annotation(param))
+ arg.write(stringify_annotation(get_annotation(param)))
elif param.kind == param.VAR_KEYWORD:
arg.write('**')
arg.write(param.name)
if show_annotation and param.annotation is not param.empty:
arg.write(': ')
- arg.write(format_param_annotation(param))
+ arg.write(stringify_annotation(get_annotation(param)))
args.append(arg.getvalue())
last_kind = param.kind
@@ -437,164 +438,29 @@ class Signature:
return '(%s)' % ', '.join(args)
else:
if 'return' in self.annotations:
- annotation = self.format_annotation(self.annotations['return'])
+ annotation = stringify_annotation(self.annotations['return'])
else:
- annotation = self.format_annotation(self.return_annotation)
+ annotation = stringify_annotation(self.return_annotation)
return '(%s) -> %s' % (', '.join(args), annotation)
def format_annotation(self, annotation: Any) -> str:
- """Return formatted representation of a type annotation.
-
- Show qualified names for types and additional details for types from
- the ``typing`` module.
-
- Displaying complex types from ``typing`` relies on its private API.
- """
- if isinstance(annotation, str):
- return annotation
- elif isinstance(annotation, typing.TypeVar): # type: ignore
- return annotation.__name__
- elif not annotation:
- return repr(annotation)
- elif annotation is NoneType: # type: ignore
- return 'None'
- elif getattr(annotation, '__module__', None) == 'builtins':
- return annotation.__qualname__
- elif annotation is Ellipsis:
- return '...'
-
- if sys.version_info >= (3, 7): # py37+
- return self.format_annotation_new(annotation)
- else:
- return self.format_annotation_old(annotation)
+ """Return formatted representation of a type annotation."""
+ warnings.warn('format_annotation() is deprecated',
+ RemovedInSphinx40Warning)
+ return stringify_annotation(annotation)
def format_annotation_new(self, annotation: Any) -> str:
"""format_annotation() for py37+"""
- module = getattr(annotation, '__module__', None)
- if module == 'typing':
- if getattr(annotation, '_name', None):
- qualname = annotation._name
- elif getattr(annotation, '__qualname__', None):
- qualname = annotation.__qualname__
- elif getattr(annotation, '__forward_arg__', None):
- qualname = annotation.__forward_arg__
- else:
- qualname = self.format_annotation(annotation.__origin__) # ex. Union
- elif hasattr(annotation, '__qualname__'):
- qualname = '%s.%s' % (module, annotation.__qualname__)
- else:
- qualname = repr(annotation)
-
- if getattr(annotation, '__args__', None):
- if qualname == 'Union':
- if len(annotation.__args__) == 2 and annotation.__args__[1] is NoneType: # type: ignore # NOQA
- return 'Optional[%s]' % self.format_annotation(annotation.__args__[0])
- else:
- args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
- return '%s[%s]' % (qualname, args)
- elif qualname == 'Callable':
- args = ', '.join(self.format_annotation(a) for a in annotation.__args__[:-1])
- returns = self.format_annotation(annotation.__args__[-1])
- return '%s[[%s], %s]' % (qualname, args, returns)
- elif annotation._special:
- return qualname
- else:
- args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
- return '%s[%s]' % (qualname, args)
-
- return qualname
+ warnings.warn('format_annotation_new() is deprecated',
+ RemovedInSphinx40Warning)
+ return stringify_annotation(annotation)
def format_annotation_old(self, annotation: Any) -> str:
"""format_annotation() for py36 or below"""
- module = getattr(annotation, '__module__', None)
- if module == 'typing':
- if getattr(annotation, '_name', None):
- qualname = annotation._name
- elif getattr(annotation, '__qualname__', None):
- qualname = annotation.__qualname__
- elif getattr(annotation, '__forward_arg__', None):
- qualname = annotation.__forward_arg__
- elif getattr(annotation, '__origin__', None):
- qualname = self.format_annotation(annotation.__origin__) # ex. Union
- else:
- qualname = repr(annotation).replace('typing.', '')
- elif hasattr(annotation, '__qualname__'):
- qualname = '%s.%s' % (module, annotation.__qualname__)
- else:
- qualname = repr(annotation)
-
- if (isinstance(annotation, typing.TupleMeta) and # type: ignore
- not hasattr(annotation, '__tuple_params__')): # for Python 3.6
- params = annotation.__args__
- if params:
- param_str = ', '.join(self.format_annotation(p) for p in params)
- return '%s[%s]' % (qualname, param_str)
- else:
- return qualname
- elif isinstance(annotation, typing.GenericMeta):
- params = None
- if hasattr(annotation, '__args__'):
- # for Python 3.5.2+
- if annotation.__args__ is None or len(annotation.__args__) <= 2: # type: ignore # NOQA
- params = annotation.__args__ # type: ignore
- else: # typing.Callable
- args = ', '.join(self.format_annotation(arg) for arg
- in annotation.__args__[:-1]) # type: ignore
- result = self.format_annotation(annotation.__args__[-1]) # type: ignore
- return '%s[[%s], %s]' % (qualname, args, result)
- elif hasattr(annotation, '__parameters__'):
- # for Python 3.5.0 and 3.5.1
- params = annotation.__parameters__ # type: ignore
- if params is not None:
- param_str = ', '.join(self.format_annotation(p) for p in params)
- return '%s[%s]' % (qualname, param_str)
- elif (hasattr(typing, 'UnionMeta') and
- isinstance(annotation, typing.UnionMeta) and # type: ignore
- hasattr(annotation, '__union_params__')): # for Python 3.5
- params = annotation.__union_params__
- if params is not None:
- if len(params) == 2 and params[1] is NoneType: # type: ignore
- return 'Optional[%s]' % self.format_annotation(params[0])
- else:
- param_str = ', '.join(self.format_annotation(p) for p in params)
- return '%s[%s]' % (qualname, param_str)
- elif (hasattr(annotation, '__origin__') and
- annotation.__origin__ is typing.Union): # for Python 3.5.2+
- params = annotation.__args__
- if params is not None:
- if len(params) == 2 and params[1] is NoneType: # type: ignore
- return 'Optional[%s]' % self.format_annotation(params[0])
- else:
- param_str = ', '.join(self.format_annotation(p) for p in params)
- return 'Union[%s]' % param_str
- elif (isinstance(annotation, typing.CallableMeta) and # type: ignore
- getattr(annotation, '__args__', None) is not None and
- hasattr(annotation, '__result__')): # for Python 3.5
- # Skipped in the case of plain typing.Callable
- args = annotation.__args__
- if args is None:
- return qualname
- elif args is Ellipsis:
- args_str = '...'
- else:
- formatted_args = (self.format_annotation(a) for a in args)
- args_str = '[%s]' % ', '.join(formatted_args)
- return '%s[%s, %s]' % (qualname,
- args_str,
- self.format_annotation(annotation.__result__))
- elif (isinstance(annotation, typing.TupleMeta) and # type: ignore
- hasattr(annotation, '__tuple_params__') and
- hasattr(annotation, '__tuple_use_ellipsis__')): # for Python 3.5
- params = annotation.__tuple_params__
- if params is not None:
- param_strings = [self.format_annotation(p) for p in params]
- if annotation.__tuple_use_ellipsis__:
- param_strings.append('...')
- return '%s[%s]' % (qualname,
- ', '.join(param_strings))
-
- return qualname
+ warnings.warn('format_annotation_old() is deprecated',
+ RemovedInSphinx40Warning)
+ return stringify_annotation(annotation)
def getdoc(obj: Any, attrgetter: Callable = safe_getattr,