summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sphinx/ext/autodoc/__init__.py31
-rw-r--r--sphinx/util/typing.py97
-rw-r--r--tests/roots/test-ext-autodoc/target/genericalias.py3
-rw-r--r--tests/roots/test-ext-autodoc/target/typevar.py5
-rw-r--r--tests/test_ext_autodoc.py19
-rw-r--r--tests/test_ext_autodoc_autoattribute.py2
-rw-r--r--tests/test_ext_autodoc_autodata.py2
-rw-r--r--tests/test_ext_autodoc_configs.py56
-rw-r--r--tests/test_util_typing.py40
9 files changed, 207 insertions, 48 deletions
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index 920e2220c..8a86f05b1 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -1676,7 +1676,11 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
self.env.events.emit('autodoc-process-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()
self.add_line('', 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():
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:
pass # Invalid class object is passed.
@@ -1846,7 +1854,12 @@ class GenericAliasMixin(DataDocumenterMixinBase):
def update_content(self, more_content: StringList) -> None:
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('', '')
super().update_content(more_content)
@@ -1864,7 +1877,11 @@ class NewTypeMixin(DataDocumenterMixinBase):
def update_content(self, more_content: StringList) -> None:
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('', '')
@@ -1901,7 +1918,11 @@ class TypeVarMixin(DataDocumenterMixinBase):
for constraint in self.object.__constraints__:
attrs.append(stringify_typehint(constraint))
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__:
attrs.append("covariant=True")
if self.object.__contravariant__:
diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py
index 68b305cff..d9b63e046 100644
--- a/sphinx/util/typing.py
+++ b/sphinx/util/typing.py
@@ -105,10 +105,24 @@ def is_system_TypeVar(typ: Any) -> bool:
return modname == 'typing' and isinstance(typ, TypeVar)
-def restify(cls: Optional[Type]) -> str:
- """Convert python class to a reST reference."""
+def restify(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str:
+ """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
+ if mode == 'smart':
+ modprefix = '~'
+ else:
+ modprefix = ''
+
try:
if cls is None or cls is NoneType:
return ':py:obj:`None`'
@@ -117,63 +131,67 @@ def restify(cls: Optional[Type]) -> str:
elif isinstance(cls, str):
return cls
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):
if sys.version_info > (3, 10):
# newtypes have correct module info since Python 3.10+
- print(cls, type(cls), dir(cls))
- return ':py:class:`%s.%s`' % (cls.__module__, cls.__name__)
+ return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__)
else:
return ':py:class:`%s`' % cls.__name__
elif UnionType and isinstance(cls, UnionType):
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
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'):
if hasattr(cls, '__args__'):
return ':py:class:`%s`\\ [%s]' % (
cls.__name__,
- ', '.join(restify(arg) for arg in cls.__args__),
+ ', '.join(restify(arg, mode) for arg in cls.__args__),
)
else:
return ':py:class:`%s`' % cls.__name__
else:
if sys.version_info >= (3, 7): # py37+
- return _restify_py37(cls)
+ return _restify_py37(cls, mode)
else:
- return _restify_py36(cls)
+ return _restify_py36(cls, mode)
except (AttributeError, TypeError):
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."""
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) 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
else:
- return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0])
+ return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0], mode)
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
elif inspect.isgenericalias(cls):
if isinstance(cls.__origin__, typing._SpecialForm):
- text = restify(cls.__origin__) # type: ignore
+ 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:
- text = ':py:class:`%s.%s`' % (cls.__module__, cls._name)
+ text = ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls._name)
else:
- text = restify(cls.__origin__)
+ text = restify(cls.__origin__, mode)
origin = getattr(cls, '__origin__', None)
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])
pass
elif cls.__module__ == 'typing' and cls._name == 'Callable':
- args = ', '.join(restify(a) for a in cls.__args__[:-1])
- text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1]))
+ 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) for a in cls.__args__)
+ text += r"\ [%s]" % ", ".join(restify(a, mode) for a in cls.__args__)
return text
elif isinstance(cls, typing._SpecialForm):
@@ -196,7 +214,7 @@ def _restify_py37(cls: Optional[Type]) -> str:
if cls.__module__ == 'typing':
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
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):
return ':py:class:`%s`' % cls.__forward_arg__
else:
@@ -204,10 +222,15 @@ def _restify_py37(cls: Optional[Type]) -> str:
if cls.__module__ == 'typing':
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
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], mode: str = 'fully-qualified-except-typing') -> str:
+ if mode == 'smart':
+ modprefix = '~'
+ else:
+ modprefix = ''
-def _restify_py36(cls: Optional[Type]) -> str:
module = getattr(cls, '__module__', None)
if module == 'typing':
if getattr(cls, '_name', None):
@@ -221,7 +244,7 @@ def _restify_py36(cls: Optional[Type]) -> str:
else:
qualname = repr(cls).replace('typing.', '')
elif hasattr(cls, '__qualname__'):
- qualname = '%s.%s' % (module, cls.__qualname__)
+ qualname = '%s%s.%s' % (modprefix, module, cls.__qualname__)
else:
qualname = repr(cls)
@@ -230,11 +253,11 @@ def _restify_py36(cls: Optional[Type]) -> str:
if module == 'typing':
reftext = ':py:class:`~typing.%s`' % qualname
else:
- reftext = ':py:class:`%s`' % qualname
+ reftext = ':py:class:`%s%s`' % (modprefix, qualname)
params = cls.__args__
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
else:
return reftext
@@ -242,19 +265,19 @@ def _restify_py36(cls: Optional[Type]) -> str:
if module == 'typing':
reftext = ':py:class:`~typing.%s`' % qualname
else:
- reftext = ':py:class:`%s`' % qualname
+ 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) for arg in cls.__args__[:-1])
- result = restify(cls.__args__[-1])
+ 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) for p in params)
+ param_str = ', '.join(restify(p, mode) for p in params)
return reftext + '\\ [%s]' % (param_str)
else:
return reftext
@@ -264,13 +287,13 @@ def _restify_py36(cls: Optional[Type]) -> str:
if params is not None:
if len(params) > 1 and params[-1] is NoneType:
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`\\ '
'[:py:obj:`~typing.Union`\\ [%s]]' % param_str)
else:
- return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0])
+ return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0], mode)
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
else:
return ':py:obj:`Union`'
@@ -278,25 +301,25 @@ def _restify_py36(cls: Optional[Type]) -> str:
if cls.__module__ == 'typing':
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
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'):
# SpecialForm
if cls.__module__ == 'typing':
return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name)
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__'):
# not a class (ex. TypeVar)
if cls.__module__ == 'typing':
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
else:
- return ':py:obj:`%s.%s`' % (cls.__module__, cls.__name__)
+ 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`' % (cls.__module__, qualname)
+ return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, qualname)
def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
diff --git a/tests/roots/test-ext-autodoc/target/genericalias.py b/tests/roots/test-ext-autodoc/target/genericalias.py
index 9909efca1..3856e034d 100644
--- a/tests/roots/test-ext-autodoc/target/genericalias.py
+++ b/tests/roots/test-ext-autodoc/target/genericalias.py
@@ -9,3 +9,6 @@ C = Callable[[int], None] # a generic alias not having a doccomment
class Class:
#: A list of int
T = List[int]
+
+#: A list of Class
+L = List[Class]
diff --git a/tests/roots/test-ext-autodoc/target/typevar.py b/tests/roots/test-ext-autodoc/target/typevar.py
index c330e2d88..ff2d46d19 100644
--- a/tests/roots/test-ext-autodoc/target/typevar.py
+++ b/tests/roots/test-ext-autodoc/target/typevar.py
@@ -1,3 +1,4 @@
+from datetime import date
from typing import NewType, TypeVar
#: T1
@@ -15,7 +16,7 @@ T4 = TypeVar("T4", covariant=True)
T5 = TypeVar("T5", contravariant=True)
#: T6
-T6 = NewType("T6", int)
+T6 = NewType("T6", date)
#: T7
T7 = TypeVar("T7", bound=int)
@@ -26,4 +27,4 @@ class Class:
T1 = TypeVar("T1")
#: T6
- T6 = NewType("T6", int)
+ T6 = NewType("T6", date)
diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py
index f70e505f3..62bbf83d0 100644
--- a/tests/test_ext_autodoc.py
+++ b/tests/test_ext_autodoc.py
@@ -1874,6 +1874,12 @@ def test_autodoc_GenericAlias(app):
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
+ '.. py:attribute:: L',
+ ' :module: target.genericalias',
+ '',
+ ' A list of Class',
+ '',
+ '',
'.. py:attribute:: T',
' :module: target.genericalias',
'',
@@ -1898,6 +1904,15 @@ def test_autodoc_GenericAlias(app):
' 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',
' :module: target.genericalias',
'',
@@ -1935,7 +1950,7 @@ def test_autodoc_TypeVar(app):
'',
' T6',
'',
- ' alias of :py:class:`int`',
+ ' alias of :py:class:`datetime.date`',
'',
'',
'.. py:data:: T1',
@@ -1975,7 +1990,7 @@ def test_autodoc_TypeVar(app):
'',
' T6',
'',
- ' alias of :py:class:`int`',
+ ' alias of :py:class:`datetime.date`',
'',
'',
'.. py:data:: T7',
diff --git a/tests/test_ext_autodoc_autoattribute.py b/tests/test_ext_autodoc_autoattribute.py
index 0dc84f195..9502b3c52 100644
--- a/tests/test_ext_autodoc_autoattribute.py
+++ b/tests/test_ext_autodoc_autoattribute.py
@@ -183,7 +183,7 @@ def test_autoattribute_NewType(app):
'',
' T6',
'',
- ' alias of :py:class:`int`',
+ ' alias of :py:class:`datetime.date`',
'',
]
diff --git a/tests/test_ext_autodoc_autodata.py b/tests/test_ext_autodoc_autodata.py
index 966d0359a..9fbfaaf39 100644
--- a/tests/test_ext_autodoc_autodata.py
+++ b/tests/test_ext_autodoc_autodata.py
@@ -111,7 +111,7 @@ def test_autodata_NewType(app):
'',
' T6',
'',
- ' alias of :py:class:`int`',
+ ' alias of :py:class:`datetime.date`',
'',
]
diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py
index ab72d436d..e84e360e8 100644
--- a/tests/test_ext_autodoc_configs.py
+++ b/tests/test_ext_autodoc_configs.py
@@ -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')
def test_autodoc_default_options(app):
# no settings
diff --git a/tests/test_util_typing.py b/tests/test_util_typing.py
index a49585588..c061fa085 100644
--- a/tests/test_util_typing.py
+++ b/tests/test_util_typing.py
@@ -43,13 +43,28 @@ class BrokenType:
def test_restify():
assert restify(int) == ":py:class:`int`"
+ assert restify(int, "smart") == ":py:class:`int`"
+
assert restify(str) == ":py:class:`str`"
+ assert restify(str, "smart") == ":py:class:`str`"
+
assert restify(None) == ":py:obj:`None`"
+ assert restify(None, "smart") == ":py:obj:`None`"
+
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, "smart") == ":py:class:`~struct.Struct`"
+
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, "smart") == ":py:obj:`~typing.Any`"
+
assert restify('str') == "str"
+ assert restify('str', "smart") == "str"
def test_restify_type_hints_containers():
@@ -99,13 +114,24 @@ def test_restify_type_hints_Union():
if sys.version_info >= (3, 7):
assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ "
"[: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]) ==
(":py:obj:`~typing.Union`\\ "
"[:py:class:`tests.test_util_typing.MyClass1`, "
":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:
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], "smart") == ":py:class:`~tests.test_util_typing.MyClass1`"
@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)
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, "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, "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], "smart") == ":py:class:`~typing.List`\\ [:py:obj:`~tests.test_util_typing.T`]"
if sys.version_info >= (3, 10):
assert restify(MyInt) == ":py:class:`tests.test_util_typing.MyInt`"
+ assert restify(MyInt, "smart") == ":py:class:`~tests.test_util_typing.MyInt`"
else:
assert restify(MyInt) == ":py:class:`MyInt`"
+ assert restify(MyInt, "smart") == ":py:class:`MyInt`"
def test_restify_type_hints_custom_class():
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, "smart") == ":py:class:`~tests.test_util_typing.<MyClass2>`"
def test_restify_type_hints_alias():
@@ -169,12 +207,14 @@ def test_restify_type_union_operator():
def test_restify_broken_type_hints():
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():
with mock(['unknown']):
import unknown
assert restify(unknown.secret.Class) == ':py:class:`unknown.secret.Class`'
+ assert restify(unknown.secret.Class, "smart") == ':py:class:`~unknown.secret.Class`'
def test_stringify():