Skip to content

Commit

Permalink
Fix #9195: autodoc: The args of typing.Literal are wrongly rendered
Browse files Browse the repository at this point in the history
They should be rendered as "repr" form.
  • Loading branch information
tk0miya committed May 11, 2021
1 parent 71e7320 commit 8609193
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES
Expand Up @@ -24,6 +24,7 @@ Features added
allows you to define an alias for a class with module name like
``foo.bar.BazClass``
* #9175: autodoc: Special member is not documented in the module
* #9195: autodoc: The arguments of ``typing.Literal`` are wrongly rendered
* #3257: autosummary: Support instance attributes for classes
* #9129: html search: Show search summaries when html_copy_source = False
* #9120: html theme: Eliminate prompt characters of code-block from copyable
Expand Down
6 changes: 6 additions & 0 deletions sphinx/util/typing.py
Expand Up @@ -153,6 +153,7 @@ def _restify_py37(cls: Optional[Type]) -> str:
else:
text = restify(cls.__origin__)

origin = getattr(cls, '__origin__', None)
if not hasattr(cls, '__args__'):
pass
elif all(is_system_TypeVar(a) for a in cls.__args__):
Expand All @@ -161,6 +162,8 @@ def _restify_py37(cls: Optional[Type]) -> str:
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]))
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__)

Expand Down Expand Up @@ -362,6 +365,9 @@ def _stringify_py37(annotation: Any) -> str:
args = ', '.join(stringify(a) for a in annotation.__args__[:-1])
returns = stringify(annotation.__args__[-1])
return '%s[[%s], %s]' % (qualname, args, returns)
elif qualname == 'Literal':
args = ', '.join(repr(a) for a in annotation.__args__)
return '%s[%s]' % (qualname, args)
elif str(annotation).startswith('typing.Annotated'): # for py39+
return stringify(annotation.__args__[0])
elif all(is_system_TypeVar(a) for a in annotation.__args__):
Expand Down
12 changes: 12 additions & 0 deletions tests/test_util_typing.py
Expand Up @@ -133,6 +133,12 @@ def test_restify_type_ForwardRef():
assert restify(ForwardRef("myint")) == ":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']"


@pytest.mark.skipif(sys.version_info < (3, 10), reason='python 3.10+ is required.')
def test_restify_type_union_operator():
assert restify(int | None) == "Optional[:class:`int`]" # type: ignore
Expand Down Expand Up @@ -237,6 +243,12 @@ def test_stringify_type_hints_alias():
assert stringify(MyTuple) == "Tuple[str, str]" # type: ignore


@pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.')
def test_stringify_type_Literal():
from typing import Literal # type: ignore
assert stringify(Literal[1, "2", "\r"]) == "Literal[1, '2', '\\r']"


@pytest.mark.skipif(sys.version_info < (3, 10), reason='python 3.10+ is required.')
def test_stringify_type_union_operator():
assert stringify(int | None) == "Optional[int]" # type: ignore
Expand Down

0 comments on commit 8609193

Please sign in to comment.