diff options
author | Adam Turner <9087854+AA-Turner@users.noreply.github.com> | 2022-04-19 01:59:12 +0300 |
---|---|---|
committer | Adam Turner <9087854+aa-turner@users.noreply.github.com> | 2022-10-17 17:22:06 +0300 |
commit | eb6e137097ba7db3a4dd442855512b159bd2d4bb (patch) | |
tree | 25e7d4784b59d352d0e6524e9fbfad17ffbf736f | |
parent | dd7f65c98facf036914d15e2116103f5acb77a92 (diff) |
Merge ``_py37`` functions in ``util.typing``
- restify and _restify_py37
- stringify and _stringify_py37
-rw-r--r-- | sphinx/util/typing.py | 299 |
1 files changed, 54 insertions, 245 deletions
diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index b67ec3cd0..8ad451f03 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -2,17 +2,13 @@ import sys import typing -import warnings from struct import Struct from types import TracebackType -from typing import (Any, Callable, Dict, ForwardRef, Generator, List, Optional, Tuple, Type, - TypeVar, Union) +from typing import Any, Callable, Dict, ForwardRef, List, Optional, Tuple, Type, TypeVar, Union from docutils import nodes from docutils.parsers.rst.states import Inliner -from sphinx.deprecation import RemovedInSphinx70Warning - try: from types import UnionType # type: ignore # python 3.10 or above except ImportError: @@ -143,176 +139,64 @@ def restify(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> ) else: return ':py:class:`%s`' % cls.__name__ - else: - return _restify_py37(cls, mode) - except (AttributeError, TypeError): - return inspect.object_description(cls) - - -def _restify_py37(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str: - """Convert python class to a reST reference.""" - from sphinx.util import inspect # lazy loading - - if mode == 'smart': - modprefix = '~' - else: - modprefix = '' - - if (inspect.isgenericalias(cls) and - cls.__module__ == 'typing' and cls.__origin__ is Union): - # Union - if len(cls.__args__) > 1 and cls.__args__[-1] is NoneType: - if len(cls.__args__) > 2: - args = ', '.join(restify(a, mode) for a in cls.__args__[:-1]) - return ':py:obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args - else: - return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0], mode) - else: - args = ', '.join(restify(a, mode) for a in cls.__args__) - return ':py:obj:`~typing.Union`\\ [%s]' % args - elif inspect.isgenericalias(cls): - if isinstance(cls.__origin__, typing._SpecialForm): - text = restify(cls.__origin__, mode) # type: ignore - elif getattr(cls, '_name', None): - if cls.__module__ == 'typing': - text = ':py:class:`~%s.%s`' % (cls.__module__, cls._name) + elif (inspect.isgenericalias(cls) and + cls.__module__ == 'typing' and cls.__origin__ is Union): + # Union + if len(cls.__args__) > 1 and cls.__args__[-1] is NoneType: + if len(cls.__args__) > 2: + args = ', '.join(restify(a, mode) for a in cls.__args__[:-1]) + return ':py:obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args + else: + return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0], mode) else: - text = ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls._name) - else: - text = restify(cls.__origin__, mode) - - origin = getattr(cls, '__origin__', None) - if not hasattr(cls, '__args__'): - pass - elif all(is_system_TypeVar(a) for a in cls.__args__): - # Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT]) - pass - elif cls.__module__ == 'typing' and cls._name == 'Callable': - args = ', '.join(restify(a, mode) for a in cls.__args__[:-1]) - text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1], mode)) - elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal': - text += r"\ [%s]" % ', '.join(repr(a) for a in cls.__args__) - elif cls.__args__: - text += r"\ [%s]" % ", ".join(restify(a, mode) for a in cls.__args__) - - return text - elif isinstance(cls, typing._SpecialForm): - return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name) - elif sys.version_info[:2] >= (3, 11) and cls is typing.Any: - # handle bpo-46998 - return f':py:obj:`~{cls.__module__}.{cls.__name__}`' - elif hasattr(cls, '__qualname__'): - if cls.__module__ == 'typing': - return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__) - else: - return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__) - elif isinstance(cls, ForwardRef): - return ':py:class:`%s`' % cls.__forward_arg__ - else: - # not a class (ex. TypeVar) - if cls.__module__ == 'typing': - return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__) - else: - return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__) - - -def _restify_py36(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str: - warnings.warn('_restify_py36() is deprecated', RemovedInSphinx70Warning) - - if mode == 'smart': - modprefix = '~' - else: - modprefix = '' - - module = getattr(cls, '__module__', None) - if module == 'typing': - if getattr(cls, '_name', None): - qualname = cls._name - elif getattr(cls, '__qualname__', None): - qualname = cls.__qualname__ - elif getattr(cls, '__forward_arg__', None): - qualname = cls.__forward_arg__ - elif getattr(cls, '__origin__', None): - qualname = stringify(cls.__origin__) # ex. Union - else: - qualname = repr(cls).replace('typing.', '') - elif hasattr(cls, '__qualname__'): - qualname = '%s%s.%s' % (modprefix, module, cls.__qualname__) - else: - qualname = repr(cls) - - if (isinstance(cls, typing.TupleMeta) and # type: ignore - not hasattr(cls, '__tuple_params__')): - if module == 'typing': - reftext = ':py:class:`~typing.%s`' % qualname - else: - reftext = ':py:class:`%s%s`' % (modprefix, qualname) - - params = cls.__args__ - if params: - param_str = ', '.join(restify(p, mode) for p in params) - return reftext + '\\ [%s]' % param_str - else: - return reftext - elif isinstance(cls, typing.GenericMeta): # type: ignore[attr-defined] - if module == 'typing': - reftext = ':py:class:`~typing.%s`' % qualname - else: - reftext = ':py:class:`%s%s`' % (modprefix, qualname) - - if cls.__args__ is None or len(cls.__args__) <= 2: - params = cls.__args__ - elif cls.__origin__ == Generator: - params = cls.__args__ - else: # typing.Callable - args = ', '.join(restify(arg, mode) for arg in cls.__args__[:-1]) - result = restify(cls.__args__[-1], mode) - return reftext + '\\ [[%s], %s]' % (args, result) - - if params: - param_str = ', '.join(restify(p, mode) for p in params) - return reftext + '\\ [%s]' % (param_str) - else: - return reftext - elif (hasattr(cls, '__origin__') and - cls.__origin__ is typing.Union): - params = cls.__args__ - if params is not None: - if len(params) > 1 and params[-1] is NoneType: - if len(params) > 2: - param_str = ", ".join(restify(p, mode) for p in params[:-1]) - return (':py:obj:`~typing.Optional`\\ ' - '[:py:obj:`~typing.Union`\\ [%s]]' % param_str) + args = ', '.join(restify(a, mode) for a in cls.__args__) + return ':py:obj:`~typing.Union`\\ [%s]' % args + elif inspect.isgenericalias(cls): + if isinstance(cls.__origin__, typing._SpecialForm): + text = restify(cls.__origin__, mode) # type: ignore + elif getattr(cls, '_name', None): + if cls.__module__ == 'typing': + text = ':py:class:`~%s.%s`' % (cls.__module__, cls._name) else: - return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0], mode) + text = ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls._name) else: - param_str = ', '.join(restify(p, mode) for p in params) - return ':py:obj:`~typing.Union`\\ [%s]' % param_str - else: - return ':py:obj:`Union`' - elif hasattr(cls, '__qualname__'): - if cls.__module__ == 'typing': - return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__) - else: - return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__) - elif hasattr(cls, '_name'): - # SpecialForm - if cls.__module__ == 'typing': + text = restify(cls.__origin__, mode) + + origin = getattr(cls, '__origin__', None) + if not hasattr(cls, '__args__'): + pass + elif all(is_system_TypeVar(a) for a in cls.__args__): + # Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT]) + pass + elif cls.__module__ == 'typing' and cls._name == 'Callable': + args = ', '.join(restify(a, mode) for a in cls.__args__[:-1]) + text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1], mode)) + elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal': + text += r"\ [%s]" % ', '.join(repr(a) for a in cls.__args__) + elif cls.__args__: + text += r"\ [%s]" % ", ".join(restify(a, mode) for a in cls.__args__) + + return text + elif isinstance(cls, typing._SpecialForm): return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name) + elif sys.version_info[:2] >= (3, 11) and cls is typing.Any: + # handle bpo-46998 + return f':py:obj:`~{cls.__module__}.{cls.__name__}`' + elif hasattr(cls, '__qualname__'): + if cls.__module__ == 'typing': + return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__) + else: + return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__) + elif isinstance(cls, ForwardRef): + return ':py:class:`%s`' % cls.__forward_arg__ else: - return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls._name) - elif hasattr(cls, '__name__'): - # not a class (ex. TypeVar) - if cls.__module__ == 'typing': - return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__) - else: - return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__) - else: - # others (ex. Any) - if cls.__module__ == 'typing': - return ':py:obj:`~%s.%s`' % (cls.__module__, qualname) - else: - return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, qualname) + # not a class (ex. TypeVar) + if cls.__module__ == 'typing': + return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__) + else: + return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__) + except (AttributeError, TypeError): + return inspect.object_description(cls) def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str: @@ -375,11 +259,6 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s elif annotation is Ellipsis: return '...' - return _stringify_py37(annotation, mode) - - -def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str: - """stringify() for py37+.""" module = getattr(annotation, '__module__', None) modprefix = '' if module == 'typing' and getattr(annotation, '__forward_arg__', None): @@ -450,73 +329,3 @@ def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing' return '%s%s[%s]' % (modprefix, qualname, args) return modprefix + qualname - - -def _stringify_py36(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str: - """stringify() for py36.""" - warnings.warn('_stringify_py36() is deprecated', RemovedInSphinx70Warning) - - module = getattr(annotation, '__module__', None) - modprefix = '' - if module == 'typing' and getattr(annotation, '__forward_arg__', None): - qualname = annotation.__forward_arg__ - elif module == 'typing': - if getattr(annotation, '_name', None): - qualname = annotation._name - elif getattr(annotation, '__qualname__', None): - qualname = annotation.__qualname__ - elif getattr(annotation, '__origin__', None): - qualname = stringify(annotation.__origin__) # ex. Union - else: - qualname = repr(annotation).replace('typing.', '') - - if mode == 'smart': - modprefix = '~%s.' % module - elif mode == 'fully-qualified': - modprefix = '%s.' % module - elif hasattr(annotation, '__qualname__'): - if mode == 'smart': - modprefix = '~%s.' % module - else: - modprefix = '%s.' % module - qualname = 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(stringify(p, mode) for p in params) - return '%s%s[%s]' % (modprefix, qualname, param_str) - else: - return modprefix + qualname - elif isinstance(annotation, typing.GenericMeta): # type: ignore[attr-defined] - params = None - if annotation.__args__ is None or len(annotation.__args__) <= 2: # NOQA - params = annotation.__args__ - elif annotation.__origin__ == Generator: - params = annotation.__args__ - else: # typing.Callable - args = ', '.join(stringify(arg, mode) for arg - in annotation.__args__[:-1]) - result = stringify(annotation.__args__[-1]) - return '%s%s[[%s], %s]' % (modprefix, qualname, args, result) - if params is not None: - param_str = ', '.join(stringify(p, mode) for p in params) - return '%s%s[%s]' % (modprefix, qualname, param_str) - elif (hasattr(annotation, '__origin__') and - annotation.__origin__ is typing.Union): - params = annotation.__args__ - if params is not None: - if len(params) > 1 and params[-1] is NoneType: - if len(params) > 2: - param_str = ", ".join(stringify(p, mode) for p in params[:-1]) - return '%sOptional[%sUnion[%s]]' % (modprefix, modprefix, param_str) - else: - return '%sOptional[%s]' % (modprefix, stringify(params[0], mode)) - else: - param_str = ', '.join(stringify(p, mode) for p in params) - return '%sUnion[%s]' % (modprefix, param_str) - - return modprefix + qualname |