mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #9630: autodoc: Failed to build xrefs if primary_domain is not 'py'
Autodoc generates reST code that uses raw `:obj:` and `:class:` xrefs to refer the classes and types. But they're fragile because they assume the primary_domain=='py'. This adds `:py:` prefix to these xrefs to make them robust.
This commit is contained in:
parent
ba2439a105
commit
ed227d7d3c
3
CHANGES
3
CHANGES
@ -16,6 +16,9 @@ Features added
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #9630: autodoc: Failed to build cross references if :confval:`primary_domain`
|
||||
is not 'py'
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
|
@ -110,18 +110,18 @@ def restify(cls: Optional[Type]) -> str:
|
||||
|
||||
try:
|
||||
if cls is None or cls is NoneType:
|
||||
return ':obj:`None`'
|
||||
return ':py:obj:`None`'
|
||||
elif cls is Ellipsis:
|
||||
return '...'
|
||||
elif cls in INVALID_BUILTIN_CLASSES:
|
||||
return ':class:`%s`' % INVALID_BUILTIN_CLASSES[cls]
|
||||
return ':py:class:`%s`' % 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 ':class:`%s.%s`' % (cls.__module__, cls.__name__)
|
||||
return ':py:class:`%s.%s`' % (cls.__module__, cls.__name__)
|
||||
else:
|
||||
return ':class:`%s`' % cls.__name__
|
||||
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)
|
||||
@ -130,12 +130,12 @@ def restify(cls: Optional[Type]) -> str:
|
||||
return ' | '.join(restify(a) for a in cls.__args__)
|
||||
elif cls.__module__ in ('__builtin__', 'builtins'):
|
||||
if hasattr(cls, '__args__'):
|
||||
return ':class:`%s`\\ [%s]' % (
|
||||
return ':py:class:`%s`\\ [%s]' % (
|
||||
cls.__name__,
|
||||
', '.join(restify(arg) for arg in cls.__args__),
|
||||
)
|
||||
else:
|
||||
return ':class:`%s`' % cls.__name__
|
||||
return ':py:class:`%s`' % cls.__name__
|
||||
else:
|
||||
if sys.version_info >= (3, 7): # py37+
|
||||
return _restify_py37(cls)
|
||||
@ -155,20 +155,20 @@ def _restify_py37(cls: Optional[Type]) -> str:
|
||||
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])
|
||||
return ':obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args
|
||||
return ':py:obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args
|
||||
else:
|
||||
return ':obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0])
|
||||
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0])
|
||||
else:
|
||||
args = ', '.join(restify(a) for a in cls.__args__)
|
||||
return ':obj:`~typing.Union`\\ [%s]' % args
|
||||
return ':py:obj:`~typing.Union`\\ [%s]' % args
|
||||
elif inspect.isgenericalias(cls):
|
||||
if isinstance(cls.__origin__, typing._SpecialForm):
|
||||
text = restify(cls.__origin__) # type: ignore
|
||||
elif getattr(cls, '_name', None):
|
||||
if cls.__module__ == 'typing':
|
||||
text = ':class:`~%s.%s`' % (cls.__module__, cls._name)
|
||||
text = ':py:class:`~%s.%s`' % (cls.__module__, cls._name)
|
||||
else:
|
||||
text = ':class:`%s.%s`' % (cls.__module__, cls._name)
|
||||
text = ':py:class:`%s.%s`' % (cls.__module__, cls._name)
|
||||
else:
|
||||
text = restify(cls.__origin__)
|
||||
|
||||
@ -188,20 +188,20 @@ def _restify_py37(cls: Optional[Type]) -> str:
|
||||
|
||||
return text
|
||||
elif isinstance(cls, typing._SpecialForm):
|
||||
return ':obj:`~%s.%s`' % (cls.__module__, cls._name)
|
||||
return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name)
|
||||
elif hasattr(cls, '__qualname__'):
|
||||
if cls.__module__ == 'typing':
|
||||
return ':class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
else:
|
||||
return ':class:`%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
return ':py:class:`%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
elif isinstance(cls, ForwardRef):
|
||||
return ':class:`%s`' % cls.__forward_arg__
|
||||
return ':py:class:`%s`' % cls.__forward_arg__
|
||||
else:
|
||||
# not a class (ex. TypeVar)
|
||||
if cls.__module__ == 'typing':
|
||||
return ':obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
||||
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
||||
else:
|
||||
return ':obj:`%s.%s`' % (cls.__module__, cls.__name__)
|
||||
return ':py:obj:`%s.%s`' % (cls.__module__, cls.__name__)
|
||||
|
||||
|
||||
def _restify_py36(cls: Optional[Type]) -> str:
|
||||
@ -225,9 +225,9 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
||||
if (isinstance(cls, typing.TupleMeta) and # type: ignore
|
||||
not hasattr(cls, '__tuple_params__')):
|
||||
if module == 'typing':
|
||||
reftext = ':class:`~typing.%s`' % qualname
|
||||
reftext = ':py:class:`~typing.%s`' % qualname
|
||||
else:
|
||||
reftext = ':class:`%s`' % qualname
|
||||
reftext = ':py:class:`%s`' % qualname
|
||||
|
||||
params = cls.__args__
|
||||
if params:
|
||||
@ -237,9 +237,9 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
||||
return reftext
|
||||
elif isinstance(cls, typing.GenericMeta):
|
||||
if module == 'typing':
|
||||
reftext = ':class:`~typing.%s`' % qualname
|
||||
reftext = ':py:class:`~typing.%s`' % qualname
|
||||
else:
|
||||
reftext = ':class:`%s`' % qualname
|
||||
reftext = ':py:class:`%s`' % qualname
|
||||
|
||||
if cls.__args__ is None or len(cls.__args__) <= 2:
|
||||
params = cls.__args__
|
||||
@ -262,38 +262,38 @@ def _restify_py36(cls: Optional[Type]) -> str:
|
||||
if len(params) > 1 and params[-1] is NoneType:
|
||||
if len(params) > 2:
|
||||
param_str = ", ".join(restify(p) for p in params[:-1])
|
||||
return (':obj:`~typing.Optional`\\ '
|
||||
'[:obj:`~typing.Union`\\ [%s]]' % param_str)
|
||||
return (':py:obj:`~typing.Optional`\\ '
|
||||
'[:py:obj:`~typing.Union`\\ [%s]]' % param_str)
|
||||
else:
|
||||
return ':obj:`~typing.Optional`\\ [%s]' % restify(params[0])
|
||||
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0])
|
||||
else:
|
||||
param_str = ', '.join(restify(p) for p in params)
|
||||
return ':obj:`~typing.Union`\\ [%s]' % param_str
|
||||
return ':py:obj:`~typing.Union`\\ [%s]' % param_str
|
||||
else:
|
||||
return ':obj:`Union`'
|
||||
return ':py:obj:`Union`'
|
||||
elif hasattr(cls, '__qualname__'):
|
||||
if cls.__module__ == 'typing':
|
||||
return ':class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
else:
|
||||
return ':class:`%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
return ':py:class:`%s.%s`' % (cls.__module__, cls.__qualname__)
|
||||
elif hasattr(cls, '_name'):
|
||||
# SpecialForm
|
||||
if cls.__module__ == 'typing':
|
||||
return ':obj:`~%s.%s`' % (cls.__module__, cls._name)
|
||||
return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name)
|
||||
else:
|
||||
return ':obj:`%s.%s`' % (cls.__module__, cls._name)
|
||||
return ':py:obj:`%s.%s`' % (cls.__module__, cls._name)
|
||||
elif hasattr(cls, '__name__'):
|
||||
# not a class (ex. TypeVar)
|
||||
if cls.__module__ == 'typing':
|
||||
return ':obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
||||
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
|
||||
else:
|
||||
return ':obj:`%s.%s`' % (cls.__module__, cls.__name__)
|
||||
return ':py:obj:`%s.%s`' % (cls.__module__, cls.__name__)
|
||||
else:
|
||||
# others (ex. Any)
|
||||
if cls.__module__ == 'typing':
|
||||
return ':obj:`~%s.%s`' % (cls.__module__, qualname)
|
||||
return ':py:obj:`~%s.%s`' % (cls.__module__, qualname)
|
||||
else:
|
||||
return ':obj:`%s.%s`' % (cls.__module__, qualname)
|
||||
return ':py:obj:`%s.%s`' % (cls.__module__, qualname)
|
||||
|
||||
|
||||
def stringify(annotation: Any) -> str:
|
||||
|
@ -984,7 +984,7 @@ def test_autodoc_inner_class(app):
|
||||
' .. py:attribute:: Outer.factory',
|
||||
' :module: target',
|
||||
'',
|
||||
' alias of :class:`dict`'
|
||||
' alias of :py:class:`dict`'
|
||||
]
|
||||
|
||||
actual = do_autodoc(app, 'class', 'target.Outer.Inner', options)
|
||||
@ -1009,7 +1009,7 @@ def test_autodoc_inner_class(app):
|
||||
'',
|
||||
'.. py:class:: InnerChild()',
|
||||
' :module: target', '',
|
||||
' Bases: :class:`target.Outer.Inner`',
|
||||
' Bases: :py:class:`target.Outer.Inner`',
|
||||
'',
|
||||
' InnerChild docstring',
|
||||
'',
|
||||
@ -1750,7 +1750,7 @@ def test_autodoc_typed_instance_variables(app):
|
||||
'.. py:attribute:: Alias',
|
||||
' :module: target.typed_vars',
|
||||
'',
|
||||
' alias of :class:`target.typed_vars.Derived`',
|
||||
' alias of :py:class:`target.typed_vars.Derived`',
|
||||
'',
|
||||
'.. py:class:: Class()',
|
||||
' :module: target.typed_vars',
|
||||
@ -1915,12 +1915,12 @@ def test_autodoc_GenericAlias(app):
|
||||
' .. py:attribute:: Class.T',
|
||||
' :module: target.genericalias',
|
||||
'',
|
||||
' alias of :class:`~typing.List`\\ [:class:`int`]',
|
||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||
'',
|
||||
'.. py:attribute:: T',
|
||||
' :module: target.genericalias',
|
||||
'',
|
||||
' alias of :class:`~typing.List`\\ [:class:`int`]',
|
||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||
]
|
||||
else:
|
||||
assert list(actual) == [
|
||||
@ -1937,7 +1937,7 @@ def test_autodoc_GenericAlias(app):
|
||||
'',
|
||||
' A list of int',
|
||||
'',
|
||||
' alias of :class:`~typing.List`\\ [:class:`int`]',
|
||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||
'',
|
||||
'',
|
||||
'.. py:data:: T',
|
||||
@ -1945,7 +1945,7 @@ def test_autodoc_GenericAlias(app):
|
||||
'',
|
||||
' A list of int',
|
||||
'',
|
||||
' alias of :class:`~typing.List`\\ [:class:`int`]',
|
||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||
'',
|
||||
]
|
||||
|
||||
@ -1977,7 +1977,7 @@ def test_autodoc_TypeVar(app):
|
||||
'',
|
||||
' T6',
|
||||
'',
|
||||
' alias of :class:`int`',
|
||||
' alias of :py:class:`int`',
|
||||
'',
|
||||
'',
|
||||
'.. py:data:: T1',
|
||||
@ -2017,7 +2017,7 @@ def test_autodoc_TypeVar(app):
|
||||
'',
|
||||
' T6',
|
||||
'',
|
||||
' alias of :class:`int`',
|
||||
' alias of :py:class:`int`',
|
||||
'',
|
||||
'',
|
||||
'.. py:data:: T7',
|
||||
@ -2025,7 +2025,7 @@ def test_autodoc_TypeVar(app):
|
||||
'',
|
||||
' T7',
|
||||
'',
|
||||
" alias of TypeVar('T7', bound=\\ :class:`int`)",
|
||||
" alias of TypeVar('T7', bound=\\ :py:class:`int`)",
|
||||
'',
|
||||
]
|
||||
|
||||
|
@ -167,7 +167,7 @@ def test_autoattribute_GenericAlias(app):
|
||||
'',
|
||||
' A list of int',
|
||||
'',
|
||||
' alias of :class:`~typing.List`\\ [:class:`int`]',
|
||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||
'',
|
||||
]
|
||||
|
||||
@ -182,7 +182,7 @@ def test_autoattribute_NewType(app):
|
||||
'',
|
||||
' T6',
|
||||
'',
|
||||
' alias of :class:`int`',
|
||||
' alias of :py:class:`int`',
|
||||
'',
|
||||
]
|
||||
|
||||
|
@ -265,8 +265,8 @@ def test_show_inheritance_for_subclass_of_generic_type(app):
|
||||
'.. py:class:: Quux(iterable=(), /)',
|
||||
' :module: target.classes',
|
||||
'',
|
||||
' Bases: :class:`~typing.List`\\ '
|
||||
'[:obj:`~typing.Union`\\ [:class:`int`, :class:`float`]]',
|
||||
' Bases: :py:class:`~typing.List`\\ '
|
||||
'[:py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`]]',
|
||||
'',
|
||||
' A subclass of List[Union[int, float]]',
|
||||
'',
|
||||
@ -296,7 +296,7 @@ def test_autodoc_process_bases(app):
|
||||
'.. py:class:: Quux(*args, **kwds)',
|
||||
' :module: target.classes',
|
||||
'',
|
||||
' Bases: :class:`int`, :class:`str`',
|
||||
' Bases: :py:class:`int`, :py:class:`str`',
|
||||
'',
|
||||
' A subclass of List[Union[int, float]]',
|
||||
'',
|
||||
@ -307,7 +307,7 @@ def test_autodoc_process_bases(app):
|
||||
'.. py:class:: Quux(iterable=(), /)',
|
||||
' :module: target.classes',
|
||||
'',
|
||||
' Bases: :class:`int`, :class:`str`',
|
||||
' Bases: :py:class:`int`, :py:class:`str`',
|
||||
'',
|
||||
' A subclass of List[Union[int, float]]',
|
||||
'',
|
||||
@ -375,7 +375,7 @@ def test_class_alias(app):
|
||||
'.. py:attribute:: Alias',
|
||||
' :module: target.classes',
|
||||
'',
|
||||
' alias of :class:`target.classes.Foo`',
|
||||
' alias of :py:class:`target.classes.Foo`',
|
||||
]
|
||||
|
||||
|
||||
|
@ -96,7 +96,7 @@ def test_autodata_GenericAlias(app):
|
||||
'',
|
||||
' A list of int',
|
||||
'',
|
||||
' alias of :class:`~typing.List`\\ [:class:`int`]',
|
||||
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
|
||||
'',
|
||||
]
|
||||
|
||||
@ -111,7 +111,7 @@ def test_autodata_NewType(app):
|
||||
'',
|
||||
' T6',
|
||||
'',
|
||||
' alias of :class:`int`',
|
||||
' alias of :py:class:`int`',
|
||||
'',
|
||||
]
|
||||
|
||||
|
@ -41,66 +41,69 @@ class BrokenType:
|
||||
|
||||
|
||||
def test_restify():
|
||||
assert restify(int) == ":class:`int`"
|
||||
assert restify(str) == ":class:`str`"
|
||||
assert restify(None) == ":obj:`None`"
|
||||
assert restify(Integral) == ":class:`numbers.Integral`"
|
||||
assert restify(Struct) == ":class:`struct.Struct`"
|
||||
assert restify(TracebackType) == ":class:`types.TracebackType`"
|
||||
assert restify(Any) == ":obj:`~typing.Any`"
|
||||
assert restify(int) == ":py:class:`int`"
|
||||
assert restify(str) == ":py:class:`str`"
|
||||
assert restify(None) == ":py:obj:`None`"
|
||||
assert restify(Integral) == ":py:class:`numbers.Integral`"
|
||||
assert restify(Struct) == ":py:class:`struct.Struct`"
|
||||
assert restify(TracebackType) == ":py:class:`types.TracebackType`"
|
||||
assert restify(Any) == ":py:obj:`~typing.Any`"
|
||||
|
||||
|
||||
def test_restify_type_hints_containers():
|
||||
assert restify(List) == ":class:`~typing.List`"
|
||||
assert restify(Dict) == ":class:`~typing.Dict`"
|
||||
assert restify(List[int]) == ":class:`~typing.List`\\ [:class:`int`]"
|
||||
assert restify(List[str]) == ":class:`~typing.List`\\ [:class:`str`]"
|
||||
assert restify(Dict[str, float]) == (":class:`~typing.Dict`\\ "
|
||||
"[:class:`str`, :class:`float`]")
|
||||
assert restify(Tuple[str, str, str]) == (":class:`~typing.Tuple`\\ "
|
||||
"[:class:`str`, :class:`str`, :class:`str`]")
|
||||
assert restify(Tuple[str, ...]) == ":class:`~typing.Tuple`\\ [:class:`str`, ...]"
|
||||
assert restify(Tuple[()]) == ":class:`~typing.Tuple`\\ [()]"
|
||||
assert restify(List[Dict[str, Tuple]]) == (":class:`~typing.List`\\ "
|
||||
"[:class:`~typing.Dict`\\ "
|
||||
"[:class:`str`, :class:`~typing.Tuple`]]")
|
||||
assert restify(MyList[Tuple[int, int]]) == (":class:`tests.test_util_typing.MyList`\\ "
|
||||
"[:class:`~typing.Tuple`\\ "
|
||||
"[:class:`int`, :class:`int`]]")
|
||||
assert restify(Generator[None, None, None]) == (":class:`~typing.Generator`\\ "
|
||||
"[:obj:`None`, :obj:`None`, :obj:`None`]")
|
||||
assert restify(List) == ":py:class:`~typing.List`"
|
||||
assert restify(Dict) == ":py:class:`~typing.Dict`"
|
||||
assert restify(List[int]) == ":py:class:`~typing.List`\\ [:py:class:`int`]"
|
||||
assert restify(List[str]) == ":py:class:`~typing.List`\\ [:py:class:`str`]"
|
||||
assert restify(Dict[str, float]) == (":py:class:`~typing.Dict`\\ "
|
||||
"[:py:class:`str`, :py:class:`float`]")
|
||||
assert restify(Tuple[str, str, str]) == (":py:class:`~typing.Tuple`\\ "
|
||||
"[:py:class:`str`, :py:class:`str`, "
|
||||
":py:class:`str`]")
|
||||
assert restify(Tuple[str, ...]) == ":py:class:`~typing.Tuple`\\ [:py:class:`str`, ...]"
|
||||
assert restify(Tuple[()]) == ":py:class:`~typing.Tuple`\\ [()]"
|
||||
assert restify(List[Dict[str, Tuple]]) == (":py:class:`~typing.List`\\ "
|
||||
"[:py:class:`~typing.Dict`\\ "
|
||||
"[:py:class:`str`, :py:class:`~typing.Tuple`]]")
|
||||
assert restify(MyList[Tuple[int, int]]) == (":py:class:`tests.test_util_typing.MyList`\\ "
|
||||
"[:py:class:`~typing.Tuple`\\ "
|
||||
"[:py:class:`int`, :py:class:`int`]]")
|
||||
assert restify(Generator[None, None, None]) == (":py:class:`~typing.Generator`\\ "
|
||||
"[:py:obj:`None`, :py:obj:`None`, "
|
||||
":py:obj:`None`]")
|
||||
|
||||
|
||||
def test_restify_type_hints_Callable():
|
||||
assert restify(Callable) == ":class:`~typing.Callable`"
|
||||
assert restify(Callable) == ":py:class:`~typing.Callable`"
|
||||
|
||||
if sys.version_info >= (3, 7):
|
||||
assert restify(Callable[[str], int]) == (":class:`~typing.Callable`\\ "
|
||||
"[[:class:`str`], :class:`int`]")
|
||||
assert restify(Callable[..., int]) == (":class:`~typing.Callable`\\ "
|
||||
"[[...], :class:`int`]")
|
||||
assert restify(Callable[[str], int]) == (":py:class:`~typing.Callable`\\ "
|
||||
"[[:py:class:`str`], :py:class:`int`]")
|
||||
assert restify(Callable[..., int]) == (":py:class:`~typing.Callable`\\ "
|
||||
"[[...], :py:class:`int`]")
|
||||
else:
|
||||
assert restify(Callable[[str], int]) == (":class:`~typing.Callable`\\ "
|
||||
"[:class:`str`, :class:`int`]")
|
||||
assert restify(Callable[..., int]) == (":class:`~typing.Callable`\\ "
|
||||
"[..., :class:`int`]")
|
||||
assert restify(Callable[[str], int]) == (":py:class:`~typing.Callable`\\ "
|
||||
"[:py:class:`str`, :py:class:`int`]")
|
||||
assert restify(Callable[..., int]) == (":py:class:`~typing.Callable`\\ "
|
||||
"[..., :py:class:`int`]")
|
||||
|
||||
|
||||
def test_restify_type_hints_Union():
|
||||
assert restify(Optional[int]) == ":obj:`~typing.Optional`\\ [:class:`int`]"
|
||||
assert restify(Union[str, None]) == ":obj:`~typing.Optional`\\ [:class:`str`]"
|
||||
assert restify(Union[int, str]) == ":obj:`~typing.Union`\\ [:class:`int`, :class:`str`]"
|
||||
assert restify(Optional[int]) == ":py:obj:`~typing.Optional`\\ [:py:class:`int`]"
|
||||
assert restify(Union[str, None]) == ":py:obj:`~typing.Optional`\\ [:py:class:`str`]"
|
||||
assert restify(Union[int, str]) == (":py:obj:`~typing.Union`\\ "
|
||||
"[:py:class:`int`, :py:class:`str`]")
|
||||
|
||||
if sys.version_info >= (3, 7):
|
||||
assert restify(Union[int, Integral]) == (":obj:`~typing.Union`\\ "
|
||||
"[:class:`int`, :class:`numbers.Integral`]")
|
||||
assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ "
|
||||
"[:py:class:`int`, :py:class:`numbers.Integral`]")
|
||||
assert (restify(Union[MyClass1, MyClass2]) ==
|
||||
(":obj:`~typing.Union`\\ "
|
||||
"[:class:`tests.test_util_typing.MyClass1`, "
|
||||
":class:`tests.test_util_typing.<MyClass2>`]"))
|
||||
(":py:obj:`~typing.Union`\\ "
|
||||
"[:py:class:`tests.test_util_typing.MyClass1`, "
|
||||
":py:class:`tests.test_util_typing.<MyClass2>`]"))
|
||||
else:
|
||||
assert restify(Union[int, Integral]) == ":class:`numbers.Integral`"
|
||||
assert restify(Union[MyClass1, MyClass2]) == ":class:`tests.test_util_typing.MyClass1`"
|
||||
assert restify(Union[int, Integral]) == ":py:class:`numbers.Integral`"
|
||||
assert restify(Union[MyClass1, MyClass2]) == ":py:class:`tests.test_util_typing.MyClass1`"
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
|
||||
@ -109,58 +112,61 @@ def test_restify_type_hints_typevars():
|
||||
T_co = TypeVar('T_co', covariant=True)
|
||||
T_contra = TypeVar('T_contra', contravariant=True)
|
||||
|
||||
assert restify(T) == ":obj:`tests.test_util_typing.T`"
|
||||
assert restify(T_co) == ":obj:`tests.test_util_typing.T_co`"
|
||||
assert restify(T_contra) == ":obj:`tests.test_util_typing.T_contra`"
|
||||
assert restify(List[T]) == ":class:`~typing.List`\\ [:obj:`tests.test_util_typing.T`]"
|
||||
assert restify(T) == ":py:obj:`tests.test_util_typing.T`"
|
||||
assert restify(T_co) == ":py:obj:`tests.test_util_typing.T_co`"
|
||||
assert restify(T_contra) == ":py:obj:`tests.test_util_typing.T_contra`"
|
||||
assert restify(List[T]) == ":py:class:`~typing.List`\\ [:py:obj:`tests.test_util_typing.T`]"
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
assert restify(MyInt) == ":class:`tests.test_util_typing.MyInt`"
|
||||
assert restify(MyInt) == ":py:class:`tests.test_util_typing.MyInt`"
|
||||
else:
|
||||
assert restify(MyInt) == ":class:`MyInt`"
|
||||
assert restify(MyInt) == ":py:class:`MyInt`"
|
||||
|
||||
|
||||
def test_restify_type_hints_custom_class():
|
||||
assert restify(MyClass1) == ":class:`tests.test_util_typing.MyClass1`"
|
||||
assert restify(MyClass2) == ":class:`tests.test_util_typing.<MyClass2>`"
|
||||
assert restify(MyClass1) == ":py:class:`tests.test_util_typing.MyClass1`"
|
||||
assert restify(MyClass2) == ":py:class:`tests.test_util_typing.<MyClass2>`"
|
||||
|
||||
|
||||
def test_restify_type_hints_alias():
|
||||
MyStr = str
|
||||
MyTuple = Tuple[str, str]
|
||||
assert restify(MyStr) == ":class:`str`"
|
||||
assert restify(MyTuple) == ":class:`~typing.Tuple`\\ [:class:`str`, :class:`str`]"
|
||||
assert restify(MyStr) == ":py:class:`str`"
|
||||
assert restify(MyTuple) == ":py:class:`~typing.Tuple`\\ [:py:class:`str`, :py:class:`str`]"
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
|
||||
def test_restify_type_ForwardRef():
|
||||
from typing import ForwardRef # type: ignore
|
||||
assert restify(ForwardRef("myint")) == ":class:`myint`"
|
||||
assert restify(ForwardRef("myint")) == ":py:class:`myint`"
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.')
|
||||
def test_restify_type_Literal():
|
||||
from typing import Literal # type: ignore
|
||||
assert restify(Literal[1, "2", "\r"]) == ":obj:`~typing.Literal`\\ [1, '2', '\\r']"
|
||||
assert restify(Literal[1, "2", "\r"]) == ":py:obj:`~typing.Literal`\\ [1, '2', '\\r']"
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 9), reason='python 3.9+ is required.')
|
||||
def test_restify_pep_585():
|
||||
assert restify(list[str]) == ":class:`list`\\ [:class:`str`]" # type: ignore
|
||||
assert restify(dict[str, str]) == ":class:`dict`\\ [:class:`str`, :class:`str`]" # type: ignore
|
||||
assert restify(dict[str, tuple[int, ...]]) == \
|
||||
":class:`dict`\\ [:class:`str`, :class:`tuple`\\ [:class:`int`, ...]]" # type: ignore
|
||||
assert restify(list[str]) == ":py:class:`list`\\ [:py:class:`str`]" # type: ignore
|
||||
assert restify(dict[str, str]) == (":py:class:`dict`\\ " # type: ignore
|
||||
"[:py:class:`str`, :py:class:`str`]")
|
||||
assert restify(dict[str, tuple[int, ...]]) == (":py:class:`dict`\\ " # type: ignore
|
||||
"[:py:class:`str`, :py:class:`tuple`\\ "
|
||||
"[:py:class:`int`, ...]]")
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 10), reason='python 3.10+ is required.')
|
||||
def test_restify_type_union_operator():
|
||||
assert restify(int | None) == ":class:`int` | :obj:`None`" # type: ignore
|
||||
assert restify(int | str) == ":class:`int` | :class:`str`" # type: ignore
|
||||
assert restify(int | str | None) == ":class:`int` | :class:`str` | :obj:`None`" # type: ignore
|
||||
assert restify(int | None) == ":py:class:`int` | :py:obj:`None`" # type: ignore
|
||||
assert restify(int | str) == ":py:class:`int` | :py:class:`str`" # type: ignore
|
||||
assert restify(int | str | None) == (":py:class:`int` | :py:class:`str` | " # type: ignore
|
||||
":py:obj:`None`")
|
||||
|
||||
|
||||
def test_restify_broken_type_hints():
|
||||
assert restify(BrokenType) == ':class:`tests.test_util_typing.BrokenType`'
|
||||
assert restify(BrokenType) == ':py:class:`tests.test_util_typing.BrokenType`'
|
||||
|
||||
|
||||
def test_stringify():
|
||||
|
Loading…
Reference in New Issue
Block a user