mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #10034 from tk0miya/10027_autodoc_typehints_format_for_bases
Fix #10027: autodoc_typehints_format does not work with :show-inheritance:
This commit is contained in:
commit
e1c090d9f7
@ -1676,7 +1676,11 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|||||||
self.env.events.emit('autodoc-process-bases',
|
self.env.events.emit('autodoc-process-bases',
|
||||||
self.fullname, self.object, self.options, bases)
|
self.fullname, self.object, self.options, bases)
|
||||||
|
|
||||||
base_classes = [restify(cls) for cls in bases]
|
if self.config.autodoc_typehints_format == "short":
|
||||||
|
base_classes = [restify(cls, "smart") for cls in bases]
|
||||||
|
else:
|
||||||
|
base_classes = [restify(cls) for cls in bases]
|
||||||
|
|
||||||
sourcename = self.get_sourcename()
|
sourcename = self.get_sourcename()
|
||||||
self.add_line('', sourcename)
|
self.add_line('', sourcename)
|
||||||
self.add_line(' ' + _('Bases: %s') % ', '.join(base_classes), sourcename)
|
self.add_line(' ' + _('Bases: %s') % ', '.join(base_classes), sourcename)
|
||||||
@ -1773,7 +1777,11 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|||||||
|
|
||||||
if self.doc_as_attr and not self.get_variable_comment():
|
if self.doc_as_attr and not self.get_variable_comment():
|
||||||
try:
|
try:
|
||||||
more_content = StringList([_('alias of %s') % restify(self.object)], source='')
|
if self.config.autodoc_typehints_format == "short":
|
||||||
|
alias = restify(self.object, "smart")
|
||||||
|
else:
|
||||||
|
alias = restify(self.object)
|
||||||
|
more_content = StringList([_('alias of %s') % alias], source='')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass # Invalid class object is passed.
|
pass # Invalid class object is passed.
|
||||||
|
|
||||||
@ -1846,7 +1854,12 @@ class GenericAliasMixin(DataDocumenterMixinBase):
|
|||||||
|
|
||||||
def update_content(self, more_content: StringList) -> None:
|
def update_content(self, more_content: StringList) -> None:
|
||||||
if inspect.isgenericalias(self.object):
|
if inspect.isgenericalias(self.object):
|
||||||
more_content.append(_('alias of %s') % restify(self.object), '')
|
if self.config.autodoc_typehints_format == "short":
|
||||||
|
alias = restify(self.object, "smart")
|
||||||
|
else:
|
||||||
|
alias = restify(self.object)
|
||||||
|
|
||||||
|
more_content.append(_('alias of %s') % alias, '')
|
||||||
more_content.append('', '')
|
more_content.append('', '')
|
||||||
|
|
||||||
super().update_content(more_content)
|
super().update_content(more_content)
|
||||||
@ -1864,7 +1877,11 @@ class NewTypeMixin(DataDocumenterMixinBase):
|
|||||||
|
|
||||||
def update_content(self, more_content: StringList) -> None:
|
def update_content(self, more_content: StringList) -> None:
|
||||||
if inspect.isNewType(self.object):
|
if inspect.isNewType(self.object):
|
||||||
supertype = restify(self.object.__supertype__)
|
if self.config.autodoc_typehints_format == "short":
|
||||||
|
supertype = restify(self.object.__supertype__, "smart")
|
||||||
|
else:
|
||||||
|
supertype = restify(self.object.__supertype__)
|
||||||
|
|
||||||
more_content.append(_('alias of %s') % supertype, '')
|
more_content.append(_('alias of %s') % supertype, '')
|
||||||
more_content.append('', '')
|
more_content.append('', '')
|
||||||
|
|
||||||
@ -1901,7 +1918,11 @@ class TypeVarMixin(DataDocumenterMixinBase):
|
|||||||
for constraint in self.object.__constraints__:
|
for constraint in self.object.__constraints__:
|
||||||
attrs.append(stringify_typehint(constraint))
|
attrs.append(stringify_typehint(constraint))
|
||||||
if self.object.__bound__:
|
if self.object.__bound__:
|
||||||
attrs.append(r"bound=\ " + restify(self.object.__bound__))
|
if self.config.autodoc_typehints_format == "short":
|
||||||
|
bound = restify(self.object.__bound__, "smart")
|
||||||
|
else:
|
||||||
|
bound = restify(self.object.__bound__)
|
||||||
|
attrs.append(r"bound=\ " + bound)
|
||||||
if self.object.__covariant__:
|
if self.object.__covariant__:
|
||||||
attrs.append("covariant=True")
|
attrs.append("covariant=True")
|
||||||
if self.object.__contravariant__:
|
if self.object.__contravariant__:
|
||||||
|
@ -105,10 +105,24 @@ def is_system_TypeVar(typ: Any) -> bool:
|
|||||||
return modname == 'typing' and isinstance(typ, TypeVar)
|
return modname == 'typing' and isinstance(typ, TypeVar)
|
||||||
|
|
||||||
|
|
||||||
def restify(cls: Optional[Type]) -> str:
|
def restify(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str:
|
||||||
"""Convert python class to a reST reference."""
|
"""Convert python class to a reST reference.
|
||||||
|
|
||||||
|
:param mode: Specify a method how annotations will be stringified.
|
||||||
|
|
||||||
|
'fully-qualified-except-typing'
|
||||||
|
Show the module name and qualified name of the annotation except
|
||||||
|
the "typing" module.
|
||||||
|
'smart'
|
||||||
|
Show the name of the annotation.
|
||||||
|
"""
|
||||||
from sphinx.util import inspect # lazy loading
|
from sphinx.util import inspect # lazy loading
|
||||||
|
|
||||||
|
if mode == 'smart':
|
||||||
|
modprefix = '~'
|
||||||
|
else:
|
||||||
|
modprefix = ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if cls is None or cls is NoneType:
|
if cls is None or cls is NoneType:
|
||||||
return ':py:obj:`None`'
|
return ':py:obj:`None`'
|
||||||
@ -117,63 +131,67 @@ def restify(cls: Optional[Type]) -> str:
|
|||||||
elif isinstance(cls, str):
|
elif isinstance(cls, str):
|
||||||
return cls
|
return cls
|
||||||
elif cls in INVALID_BUILTIN_CLASSES:
|
elif cls in INVALID_BUILTIN_CLASSES:
|
||||||
return ':py:class:`%s`' % INVALID_BUILTIN_CLASSES[cls]
|
return ':py:class:`%s%s`' % (modprefix, INVALID_BUILTIN_CLASSES[cls])
|
||||||
elif inspect.isNewType(cls):
|
elif inspect.isNewType(cls):
|
||||||
if sys.version_info > (3, 10):
|
if sys.version_info > (3, 10):
|
||||||
# newtypes have correct module info since Python 3.10+
|
# newtypes have correct module info since Python 3.10+
|
||||||
print(cls, type(cls), dir(cls))
|
return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__)
|
||||||
return ':py:class:`%s.%s`' % (cls.__module__, cls.__name__)
|
|
||||||
else:
|
else:
|
||||||
return ':py:class:`%s`' % cls.__name__
|
return ':py:class:`%s`' % cls.__name__
|
||||||
elif UnionType and isinstance(cls, UnionType):
|
elif UnionType and isinstance(cls, UnionType):
|
||||||
if len(cls.__args__) > 1 and None in cls.__args__:
|
if len(cls.__args__) > 1 and None in cls.__args__:
|
||||||
args = ' | '.join(restify(a) for a in cls.__args__ if a)
|
args = ' | '.join(restify(a, mode) for a in cls.__args__ if a)
|
||||||
return 'Optional[%s]' % args
|
return 'Optional[%s]' % args
|
||||||
else:
|
else:
|
||||||
return ' | '.join(restify(a) for a in cls.__args__)
|
return ' | '.join(restify(a, mode) for a in cls.__args__)
|
||||||
elif cls.__module__ in ('__builtin__', 'builtins'):
|
elif cls.__module__ in ('__builtin__', 'builtins'):
|
||||||
if hasattr(cls, '__args__'):
|
if hasattr(cls, '__args__'):
|
||||||
return ':py:class:`%s`\\ [%s]' % (
|
return ':py:class:`%s`\\ [%s]' % (
|
||||||
cls.__name__,
|
cls.__name__,
|
||||||
', '.join(restify(arg) for arg in cls.__args__),
|
', '.join(restify(arg, mode) for arg in cls.__args__),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return ':py:class:`%s`' % cls.__name__
|
return ':py:class:`%s`' % cls.__name__
|
||||||
else:
|
else:
|
||||||
if sys.version_info >= (3, 7): # py37+
|
if sys.version_info >= (3, 7): # py37+
|
||||||
return _restify_py37(cls)
|
return _restify_py37(cls, mode)
|
||||||
else:
|
else:
|
||||||
return _restify_py36(cls)
|
return _restify_py36(cls, mode)
|
||||||
except (AttributeError, TypeError):
|
except (AttributeError, TypeError):
|
||||||
return inspect.object_description(cls)
|
return inspect.object_description(cls)
|
||||||
|
|
||||||
|
|
||||||
def _restify_py37(cls: Optional[Type]) -> str:
|
def _restify_py37(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str:
|
||||||
"""Convert python class to a reST reference."""
|
"""Convert python class to a reST reference."""
|
||||||
from sphinx.util import inspect # lazy loading
|
from sphinx.util import inspect # lazy loading
|
||||||
|
|
||||||
|
if mode == 'smart':
|
||||||
|
modprefix = '~'
|
||||||
|
else:
|
||||||
|
modprefix = ''
|
||||||
|
|
||||||
if (inspect.isgenericalias(cls) and
|
if (inspect.isgenericalias(cls) and
|
||||||
cls.__module__ == 'typing' and cls.__origin__ is Union):
|
cls.__module__ == 'typing' and cls.__origin__ is Union):
|
||||||
# Union
|
# Union
|
||||||
if len(cls.__args__) > 1 and cls.__args__[-1] is NoneType:
|
if len(cls.__args__) > 1 and cls.__args__[-1] is NoneType:
|
||||||
if len(cls.__args__) > 2:
|
if len(cls.__args__) > 2:
|
||||||
args = ', '.join(restify(a) for a in cls.__args__[:-1])
|
args = ', '.join(restify(a, mode) for a in cls.__args__[:-1])
|
||||||
return ':py:obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args
|
return ':py:obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args
|
||||||
else:
|
else:
|
||||||
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0])
|
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0], mode)
|
||||||
else:
|
else:
|
||||||
args = ', '.join(restify(a) for a in cls.__args__)
|
args = ', '.join(restify(a, mode) for a in cls.__args__)
|
||||||
return ':py:obj:`~typing.Union`\\ [%s]' % args
|
return ':py:obj:`~typing.Union`\\ [%s]' % args
|
||||||
elif inspect.isgenericalias(cls):
|
elif inspect.isgenericalias(cls):
|
||||||
if isinstance(cls.__origin__, typing._SpecialForm):
|
if isinstance(cls.__origin__, typing._SpecialForm):
|
||||||
text = restify(cls.__origin__) # type: ignore
|
text = restify(cls.__origin__, mode) # type: ignore
|
||||||
elif getattr(cls, '_name', None):
|
elif getattr(cls, '_name', None):
|
||||||
if cls.__module__ == 'typing':
|
if cls.__module__ == 'typing':
|
||||||
text = ':py:class:`~%s.%s`' % (cls.__module__, cls._name)
|
text = ':py:class:`~%s.%s`' % (cls.__module__, cls._name)
|
||||||
else:
|
else:
|
||||||
text = ':py:class:`%s.%s`' % (cls.__module__, cls._name)
|
text = ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls._name)
|
||||||
else:
|
else:
|
||||||
text = restify(cls.__origin__)
|
text = restify(cls.__origin__, mode)
|
||||||
|
|
||||||
origin = getattr(cls, '__origin__', None)
|
origin = getattr(cls, '__origin__', None)
|
||||||
if not hasattr(cls, '__args__'):
|
if not hasattr(cls, '__args__'):
|
||||||
@ -182,12 +200,12 @@ def _restify_py37(cls: Optional[Type]) -> str:
|
|||||||
# Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT])
|
# Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT])
|
||||||
pass
|
pass
|
||||||
elif cls.__module__ == 'typing' and cls._name == 'Callable':
|
elif cls.__module__ == 'typing' and cls._name == 'Callable':
|
||||||
args = ', '.join(restify(a) for a in cls.__args__[:-1])
|
args = ', '.join(restify(a, mode) for a in cls.__args__[:-1])
|
||||||
text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1]))
|
text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1], mode))
|
||||||
elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal':
|
elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal':
|
||||||
text += r"\ [%s]" % ', '.join(repr(a) for a in cls.__args__)
|
text += r"\ [%s]" % ', '.join(repr(a) for a in cls.__args__)
|
||||||
elif cls.__args__:
|
elif cls.__args__:
|
||||||
text += r"\ [%s]" % ", ".join(restify(a) for a in cls.__args__)
|
text += r"\ [%s]" % ", ".join(restify(a, mode) for a in cls.__args__)
|
||||||
|
|
||||||
return text
|
return text
|
||||||
elif isinstance(cls, typing._SpecialForm):
|
elif isinstance(cls, typing._SpecialForm):
|
||||||
@ -196,7 +214,7 @@ def _restify_py37(cls: Optional[Type]) -> str:
|
|||||||
if cls.__module__ == 'typing':
|
if cls.__module__ == 'typing':
|
||||||
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||||
else:
|
else:
|
||||||
return ':py:class:`%s.%s`' % (cls.__module__, cls.__qualname__)
|
return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__)
|
||||||
elif isinstance(cls, ForwardRef):
|
elif isinstance(cls, ForwardRef):
|
||||||
return ':py:class:`%s`' % cls.__forward_arg__
|
return ':py:class:`%s`' % cls.__forward_arg__
|
||||||
else:
|
else:
|
||||||
@ -204,10 +222,15 @@ def _restify_py37(cls: Optional[Type]) -> str:
|
|||||||
if cls.__module__ == 'typing':
|
if cls.__module__ == 'typing':
|
||||||
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
||||||
else:
|
else:
|
||||||
return ':py:obj:`%s.%s`' % (cls.__module__, cls.__name__)
|
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__)
|
||||||
|
|
||||||
|
|
||||||
def _restify_py36(cls: Optional[Type]) -> str:
|
def _restify_py36(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str:
|
||||||
|
if mode == 'smart':
|
||||||
|
modprefix = '~'
|
||||||
|
else:
|
||||||
|
modprefix = ''
|
||||||
|
|
||||||
module = getattr(cls, '__module__', None)
|
module = getattr(cls, '__module__', None)
|
||||||
if module == 'typing':
|
if module == 'typing':
|
||||||
if getattr(cls, '_name', None):
|
if getattr(cls, '_name', None):
|
||||||
@ -221,7 +244,7 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
|||||||
else:
|
else:
|
||||||
qualname = repr(cls).replace('typing.', '')
|
qualname = repr(cls).replace('typing.', '')
|
||||||
elif hasattr(cls, '__qualname__'):
|
elif hasattr(cls, '__qualname__'):
|
||||||
qualname = '%s.%s' % (module, cls.__qualname__)
|
qualname = '%s%s.%s' % (modprefix, module, cls.__qualname__)
|
||||||
else:
|
else:
|
||||||
qualname = repr(cls)
|
qualname = repr(cls)
|
||||||
|
|
||||||
@ -230,11 +253,11 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
|||||||
if module == 'typing':
|
if module == 'typing':
|
||||||
reftext = ':py:class:`~typing.%s`' % qualname
|
reftext = ':py:class:`~typing.%s`' % qualname
|
||||||
else:
|
else:
|
||||||
reftext = ':py:class:`%s`' % qualname
|
reftext = ':py:class:`%s%s`' % (modprefix, qualname)
|
||||||
|
|
||||||
params = cls.__args__
|
params = cls.__args__
|
||||||
if params:
|
if params:
|
||||||
param_str = ', '.join(restify(p) for p in params)
|
param_str = ', '.join(restify(p, mode) for p in params)
|
||||||
return reftext + '\\ [%s]' % param_str
|
return reftext + '\\ [%s]' % param_str
|
||||||
else:
|
else:
|
||||||
return reftext
|
return reftext
|
||||||
@ -242,19 +265,19 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
|||||||
if module == 'typing':
|
if module == 'typing':
|
||||||
reftext = ':py:class:`~typing.%s`' % qualname
|
reftext = ':py:class:`~typing.%s`' % qualname
|
||||||
else:
|
else:
|
||||||
reftext = ':py:class:`%s`' % qualname
|
reftext = ':py:class:`%s%s`' % (modprefix, qualname)
|
||||||
|
|
||||||
if cls.__args__ is None or len(cls.__args__) <= 2:
|
if cls.__args__ is None or len(cls.__args__) <= 2:
|
||||||
params = cls.__args__
|
params = cls.__args__
|
||||||
elif cls.__origin__ == Generator:
|
elif cls.__origin__ == Generator:
|
||||||
params = cls.__args__
|
params = cls.__args__
|
||||||
else: # typing.Callable
|
else: # typing.Callable
|
||||||
args = ', '.join(restify(arg) for arg in cls.__args__[:-1])
|
args = ', '.join(restify(arg, mode) for arg in cls.__args__[:-1])
|
||||||
result = restify(cls.__args__[-1])
|
result = restify(cls.__args__[-1], mode)
|
||||||
return reftext + '\\ [[%s], %s]' % (args, result)
|
return reftext + '\\ [[%s], %s]' % (args, result)
|
||||||
|
|
||||||
if params:
|
if params:
|
||||||
param_str = ', '.join(restify(p) for p in params)
|
param_str = ', '.join(restify(p, mode) for p in params)
|
||||||
return reftext + '\\ [%s]' % (param_str)
|
return reftext + '\\ [%s]' % (param_str)
|
||||||
else:
|
else:
|
||||||
return reftext
|
return reftext
|
||||||
@ -264,13 +287,13 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
|||||||
if params is not None:
|
if params is not None:
|
||||||
if len(params) > 1 and params[-1] is NoneType:
|
if len(params) > 1 and params[-1] is NoneType:
|
||||||
if len(params) > 2:
|
if len(params) > 2:
|
||||||
param_str = ", ".join(restify(p) for p in params[:-1])
|
param_str = ", ".join(restify(p, mode) for p in params[:-1])
|
||||||
return (':py:obj:`~typing.Optional`\\ '
|
return (':py:obj:`~typing.Optional`\\ '
|
||||||
'[:py:obj:`~typing.Union`\\ [%s]]' % param_str)
|
'[:py:obj:`~typing.Union`\\ [%s]]' % param_str)
|
||||||
else:
|
else:
|
||||||
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0])
|
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0], mode)
|
||||||
else:
|
else:
|
||||||
param_str = ', '.join(restify(p) for p in params)
|
param_str = ', '.join(restify(p, mode) for p in params)
|
||||||
return ':py:obj:`~typing.Union`\\ [%s]' % param_str
|
return ':py:obj:`~typing.Union`\\ [%s]' % param_str
|
||||||
else:
|
else:
|
||||||
return ':py:obj:`Union`'
|
return ':py:obj:`Union`'
|
||||||
@ -278,25 +301,25 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
|||||||
if cls.__module__ == 'typing':
|
if cls.__module__ == 'typing':
|
||||||
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||||
else:
|
else:
|
||||||
return ':py:class:`%s.%s`' % (cls.__module__, cls.__qualname__)
|
return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__)
|
||||||
elif hasattr(cls, '_name'):
|
elif hasattr(cls, '_name'):
|
||||||
# SpecialForm
|
# SpecialForm
|
||||||
if cls.__module__ == 'typing':
|
if cls.__module__ == 'typing':
|
||||||
return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name)
|
return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name)
|
||||||
else:
|
else:
|
||||||
return ':py:obj:`%s.%s`' % (cls.__module__, cls._name)
|
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls._name)
|
||||||
elif hasattr(cls, '__name__'):
|
elif hasattr(cls, '__name__'):
|
||||||
# not a class (ex. TypeVar)
|
# not a class (ex. TypeVar)
|
||||||
if cls.__module__ == 'typing':
|
if cls.__module__ == 'typing':
|
||||||
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
||||||
else:
|
else:
|
||||||
return ':py:obj:`%s.%s`' % (cls.__module__, cls.__name__)
|
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__)
|
||||||
else:
|
else:
|
||||||
# others (ex. Any)
|
# others (ex. Any)
|
||||||
if cls.__module__ == 'typing':
|
if cls.__module__ == 'typing':
|
||||||
return ':py:obj:`~%s.%s`' % (cls.__module__, qualname)
|
return ':py:obj:`~%s.%s`' % (cls.__module__, qualname)
|
||||||
else:
|
else:
|
||||||
return ':py:obj:`%s.%s`' % (cls.__module__, qualname)
|
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, qualname)
|
||||||
|
|
||||||
|
|
||||||
def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
|
def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
|
||||||
|
@ -9,3 +9,6 @@ C = Callable[[int], None] # a generic alias not having a doccomment
|
|||||||
class Class:
|
class Class:
|
||||||
#: A list of int
|
#: A list of int
|
||||||
T = List[int]
|
T = List[int]
|
||||||
|
|
||||||
|
#: A list of Class
|
||||||
|
L = List[Class]
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from datetime import date
|
||||||
from typing import NewType, TypeVar
|
from typing import NewType, TypeVar
|
||||||
|
|
||||||
#: T1
|
#: T1
|
||||||
@ -15,7 +16,7 @@ T4 = TypeVar("T4", covariant=True)
|
|||||||
T5 = TypeVar("T5", contravariant=True)
|
T5 = TypeVar("T5", contravariant=True)
|
||||||
|
|
||||||
#: T6
|
#: T6
|
||||||
T6 = NewType("T6", int)
|
T6 = NewType("T6", date)
|
||||||
|
|
||||||
#: T7
|
#: T7
|
||||||
T7 = TypeVar("T7", bound=int)
|
T7 = TypeVar("T7", bound=int)
|
||||||
@ -26,4 +27,4 @@ class Class:
|
|||||||
T1 = TypeVar("T1")
|
T1 = TypeVar("T1")
|
||||||
|
|
||||||
#: T6
|
#: T6
|
||||||
T6 = NewType("T6", int)
|
T6 = NewType("T6", date)
|
||||||
|
@ -1874,6 +1874,12 @@ def test_autodoc_GenericAlias(app):
|
|||||||
'',
|
'',
|
||||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||||
'',
|
'',
|
||||||
|
'.. py:attribute:: L',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
' A list of Class',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
'.. py:attribute:: T',
|
'.. py:attribute:: T',
|
||||||
' :module: target.genericalias',
|
' :module: target.genericalias',
|
||||||
'',
|
'',
|
||||||
@ -1898,6 +1904,15 @@ def test_autodoc_GenericAlias(app):
|
|||||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
|
'.. py:data:: L',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
' A list of Class',
|
||||||
|
'',
|
||||||
|
' alias of :py:class:`~typing.List`\\ '
|
||||||
|
'[:py:class:`target.genericalias.Class`]',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
'.. py:data:: T',
|
'.. py:data:: T',
|
||||||
' :module: target.genericalias',
|
' :module: target.genericalias',
|
||||||
'',
|
'',
|
||||||
@ -1935,7 +1950,7 @@ def test_autodoc_TypeVar(app):
|
|||||||
'',
|
'',
|
||||||
' T6',
|
' T6',
|
||||||
'',
|
'',
|
||||||
' alias of :py:class:`int`',
|
' alias of :py:class:`datetime.date`',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'.. py:data:: T1',
|
'.. py:data:: T1',
|
||||||
@ -1975,7 +1990,7 @@ def test_autodoc_TypeVar(app):
|
|||||||
'',
|
'',
|
||||||
' T6',
|
' T6',
|
||||||
'',
|
'',
|
||||||
' alias of :py:class:`int`',
|
' alias of :py:class:`datetime.date`',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'.. py:data:: T7',
|
'.. py:data:: T7',
|
||||||
|
@ -183,7 +183,7 @@ def test_autoattribute_NewType(app):
|
|||||||
'',
|
'',
|
||||||
' T6',
|
' T6',
|
||||||
'',
|
'',
|
||||||
' alias of :py:class:`int`',
|
' alias of :py:class:`datetime.date`',
|
||||||
'',
|
'',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ def test_autodata_NewType(app):
|
|||||||
'',
|
'',
|
||||||
' T6',
|
' T6',
|
||||||
'',
|
'',
|
||||||
' alias of :py:class:`int`',
|
' alias of :py:class:`datetime.date`',
|
||||||
'',
|
'',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1231,6 +1231,62 @@ def test_autodoc_typehints_format_short(app):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc',
|
||||||
|
confoverrides={'autodoc_typehints_format': "short"})
|
||||||
|
def test_autodoc_typehints_format_short_for_class_alias(app):
|
||||||
|
actual = do_autodoc(app, 'class', 'target.classes.Alias')
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:attribute:: Alias',
|
||||||
|
' :module: target.classes',
|
||||||
|
'',
|
||||||
|
' alias of :py:class:`~target.classes.Foo`',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc',
|
||||||
|
confoverrides={'autodoc_typehints_format': "short"})
|
||||||
|
def test_autodoc_typehints_format_short_for_generic_alias(app):
|
||||||
|
actual = do_autodoc(app, 'data', 'target.genericalias.L')
|
||||||
|
if sys.version_info < (3, 7):
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:data:: L',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
' :value: typing.List[target.genericalias.Class]',
|
||||||
|
'',
|
||||||
|
' A list of Class',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:data:: L',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
' A list of Class',
|
||||||
|
'',
|
||||||
|
' alias of :py:class:`~typing.List`\\ [:py:class:`~target.genericalias.Class`]',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc',
|
||||||
|
confoverrides={'autodoc_typehints_format': "short"})
|
||||||
|
def test_autodoc_typehints_format_short_for_newtype_alias(app):
|
||||||
|
actual = do_autodoc(app, 'data', 'target.typevar.T6')
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:data:: T6',
|
||||||
|
' :module: target.typevar',
|
||||||
|
'',
|
||||||
|
' T6',
|
||||||
|
'',
|
||||||
|
' alias of :py:class:`~datetime.date`',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autodoc_default_options(app):
|
def test_autodoc_default_options(app):
|
||||||
# no settings
|
# no settings
|
||||||
|
@ -43,13 +43,28 @@ class BrokenType:
|
|||||||
|
|
||||||
def test_restify():
|
def test_restify():
|
||||||
assert restify(int) == ":py:class:`int`"
|
assert restify(int) == ":py:class:`int`"
|
||||||
|
assert restify(int, "smart") == ":py:class:`int`"
|
||||||
|
|
||||||
assert restify(str) == ":py:class:`str`"
|
assert restify(str) == ":py:class:`str`"
|
||||||
|
assert restify(str, "smart") == ":py:class:`str`"
|
||||||
|
|
||||||
assert restify(None) == ":py:obj:`None`"
|
assert restify(None) == ":py:obj:`None`"
|
||||||
|
assert restify(None, "smart") == ":py:obj:`None`"
|
||||||
|
|
||||||
assert restify(Integral) == ":py:class:`numbers.Integral`"
|
assert restify(Integral) == ":py:class:`numbers.Integral`"
|
||||||
|
assert restify(Integral, "smart") == ":py:class:`~numbers.Integral`"
|
||||||
|
|
||||||
assert restify(Struct) == ":py:class:`struct.Struct`"
|
assert restify(Struct) == ":py:class:`struct.Struct`"
|
||||||
|
assert restify(Struct, "smart") == ":py:class:`~struct.Struct`"
|
||||||
|
|
||||||
assert restify(TracebackType) == ":py:class:`types.TracebackType`"
|
assert restify(TracebackType) == ":py:class:`types.TracebackType`"
|
||||||
|
assert restify(TracebackType, "smart") == ":py:class:`~types.TracebackType`"
|
||||||
|
|
||||||
assert restify(Any) == ":py:obj:`~typing.Any`"
|
assert restify(Any) == ":py:obj:`~typing.Any`"
|
||||||
|
assert restify(Any, "smart") == ":py:obj:`~typing.Any`"
|
||||||
|
|
||||||
assert restify('str') == "str"
|
assert restify('str') == "str"
|
||||||
|
assert restify('str', "smart") == "str"
|
||||||
|
|
||||||
|
|
||||||
def test_restify_type_hints_containers():
|
def test_restify_type_hints_containers():
|
||||||
@ -99,13 +114,24 @@ def test_restify_type_hints_Union():
|
|||||||
if sys.version_info >= (3, 7):
|
if sys.version_info >= (3, 7):
|
||||||
assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ "
|
assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ "
|
||||||
"[:py:class:`int`, :py:class:`numbers.Integral`]")
|
"[:py:class:`int`, :py:class:`numbers.Integral`]")
|
||||||
|
assert restify(Union[int, Integral], "smart") == (":py:obj:`~typing.Union`\\ "
|
||||||
|
"[:py:class:`int`,"
|
||||||
|
" :py:class:`~numbers.Integral`]")
|
||||||
|
|
||||||
assert (restify(Union[MyClass1, MyClass2]) ==
|
assert (restify(Union[MyClass1, MyClass2]) ==
|
||||||
(":py:obj:`~typing.Union`\\ "
|
(":py:obj:`~typing.Union`\\ "
|
||||||
"[:py:class:`tests.test_util_typing.MyClass1`, "
|
"[:py:class:`tests.test_util_typing.MyClass1`, "
|
||||||
":py:class:`tests.test_util_typing.<MyClass2>`]"))
|
":py:class:`tests.test_util_typing.<MyClass2>`]"))
|
||||||
|
assert (restify(Union[MyClass1, MyClass2], "smart") ==
|
||||||
|
(":py:obj:`~typing.Union`\\ "
|
||||||
|
"[:py:class:`~tests.test_util_typing.MyClass1`,"
|
||||||
|
" :py:class:`~tests.test_util_typing.<MyClass2>`]"))
|
||||||
else:
|
else:
|
||||||
assert restify(Union[int, Integral]) == ":py:class:`numbers.Integral`"
|
assert restify(Union[int, Integral]) == ":py:class:`numbers.Integral`"
|
||||||
|
assert restify(Union[int, Integral], "smart") == ":py:class:`~numbers.Integral`"
|
||||||
|
|
||||||
assert restify(Union[MyClass1, MyClass2]) == ":py:class:`tests.test_util_typing.MyClass1`"
|
assert restify(Union[MyClass1, MyClass2]) == ":py:class:`tests.test_util_typing.MyClass1`"
|
||||||
|
assert restify(Union[MyClass1, MyClass2], "smart") == ":py:class:`~tests.test_util_typing.MyClass1`"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
|
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
|
||||||
@ -115,19 +141,31 @@ def test_restify_type_hints_typevars():
|
|||||||
T_contra = TypeVar('T_contra', contravariant=True)
|
T_contra = TypeVar('T_contra', contravariant=True)
|
||||||
|
|
||||||
assert restify(T) == ":py:obj:`tests.test_util_typing.T`"
|
assert restify(T) == ":py:obj:`tests.test_util_typing.T`"
|
||||||
|
assert restify(T, "smart") == ":py:obj:`~tests.test_util_typing.T`"
|
||||||
|
|
||||||
assert restify(T_co) == ":py:obj:`tests.test_util_typing.T_co`"
|
assert restify(T_co) == ":py:obj:`tests.test_util_typing.T_co`"
|
||||||
|
assert restify(T_co, "smart") == ":py:obj:`~tests.test_util_typing.T_co`"
|
||||||
|
|
||||||
assert restify(T_contra) == ":py:obj:`tests.test_util_typing.T_contra`"
|
assert restify(T_contra) == ":py:obj:`tests.test_util_typing.T_contra`"
|
||||||
|
assert restify(T_contra, "smart") == ":py:obj:`~tests.test_util_typing.T_contra`"
|
||||||
|
|
||||||
assert restify(List[T]) == ":py:class:`~typing.List`\\ [:py:obj:`tests.test_util_typing.T`]"
|
assert restify(List[T]) == ":py:class:`~typing.List`\\ [:py:obj:`tests.test_util_typing.T`]"
|
||||||
|
assert restify(List[T], "smart") == ":py:class:`~typing.List`\\ [:py:obj:`~tests.test_util_typing.T`]"
|
||||||
|
|
||||||
if sys.version_info >= (3, 10):
|
if sys.version_info >= (3, 10):
|
||||||
assert restify(MyInt) == ":py:class:`tests.test_util_typing.MyInt`"
|
assert restify(MyInt) == ":py:class:`tests.test_util_typing.MyInt`"
|
||||||
|
assert restify(MyInt, "smart") == ":py:class:`~tests.test_util_typing.MyInt`"
|
||||||
else:
|
else:
|
||||||
assert restify(MyInt) == ":py:class:`MyInt`"
|
assert restify(MyInt) == ":py:class:`MyInt`"
|
||||||
|
assert restify(MyInt, "smart") == ":py:class:`MyInt`"
|
||||||
|
|
||||||
|
|
||||||
def test_restify_type_hints_custom_class():
|
def test_restify_type_hints_custom_class():
|
||||||
assert restify(MyClass1) == ":py:class:`tests.test_util_typing.MyClass1`"
|
assert restify(MyClass1) == ":py:class:`tests.test_util_typing.MyClass1`"
|
||||||
|
assert restify(MyClass1, "smart") == ":py:class:`~tests.test_util_typing.MyClass1`"
|
||||||
|
|
||||||
assert restify(MyClass2) == ":py:class:`tests.test_util_typing.<MyClass2>`"
|
assert restify(MyClass2) == ":py:class:`tests.test_util_typing.<MyClass2>`"
|
||||||
|
assert restify(MyClass2, "smart") == ":py:class:`~tests.test_util_typing.<MyClass2>`"
|
||||||
|
|
||||||
|
|
||||||
def test_restify_type_hints_alias():
|
def test_restify_type_hints_alias():
|
||||||
@ -169,12 +207,14 @@ def test_restify_type_union_operator():
|
|||||||
|
|
||||||
def test_restify_broken_type_hints():
|
def test_restify_broken_type_hints():
|
||||||
assert restify(BrokenType) == ':py:class:`tests.test_util_typing.BrokenType`'
|
assert restify(BrokenType) == ':py:class:`tests.test_util_typing.BrokenType`'
|
||||||
|
assert restify(BrokenType, "smart") == ':py:class:`~tests.test_util_typing.BrokenType`'
|
||||||
|
|
||||||
|
|
||||||
def test_restify_mock():
|
def test_restify_mock():
|
||||||
with mock(['unknown']):
|
with mock(['unknown']):
|
||||||
import unknown
|
import unknown
|
||||||
assert restify(unknown.secret.Class) == ':py:class:`unknown.secret.Class`'
|
assert restify(unknown.secret.Class) == ':py:class:`unknown.secret.Class`'
|
||||||
|
assert restify(unknown.secret.Class, "smart") == ':py:class:`~unknown.secret.Class`'
|
||||||
|
|
||||||
|
|
||||||
def test_stringify():
|
def test_stringify():
|
||||||
|
Loading…
Reference in New Issue
Block a user