Merge pull request #7655 from chipaca/optional-union

Make sphinx.util.typing.stringify render optional unions better
This commit is contained in:
Takeshi KOMIYA
2020-05-13 22:12:43 +09:00
committed by GitHub
3 changed files with 22 additions and 6 deletions

View File

@@ -91,11 +91,15 @@ def _stringify_py37(annotation: Any) -> str:
if getattr(annotation, '__args__', None): if getattr(annotation, '__args__', None):
if qualname == 'Union': if qualname == 'Union':
if len(annotation.__args__) == 2 and annotation.__args__[1] is NoneType: # type: ignore # NOQA if len(annotation.__args__) > 1 and annotation.__args__[-1] is NoneType: # type: ignore # NOQA
return 'Optional[%s]' % stringify(annotation.__args__[0]) if len(annotation.__args__) > 2:
args = ', '.join(stringify(a) for a in annotation.__args__[:-1])
return 'Optional[Union[%s]]' % args
else:
return 'Optional[%s]' % stringify(annotation.__args__[0])
else: else:
args = ', '.join(stringify(a) for a in annotation.__args__) args = ', '.join(stringify(a) for a in annotation.__args__)
return '%s[%s]' % (qualname, args) return 'Union[%s]' % args
elif qualname == 'Callable': elif qualname == 'Callable':
args = ', '.join(stringify(a) for a in annotation.__args__[:-1]) args = ', '.join(stringify(a) for a in annotation.__args__[:-1])
returns = stringify(annotation.__args__[-1]) returns = stringify(annotation.__args__[-1])
@@ -170,8 +174,12 @@ def _stringify_py36(annotation: Any) -> str:
annotation.__origin__ is typing.Union): # for Python 3.5.2+ annotation.__origin__ is typing.Union): # for Python 3.5.2+
params = annotation.__args__ params = annotation.__args__
if params is not None: if params is not None:
if len(params) == 2 and params[1] is NoneType: # type: ignore if len(params) > 1 and params[-1] is NoneType: # type: ignore
return 'Optional[%s]' % stringify(params[0]) if len(params) > 2:
param_str = ", ".join(stringify(p) for p in params[:-1])
return 'Optional[Union[%s]]' % param_str
else:
return 'Optional[%s]' % stringify(params[0])
else: else:
param_str = ', '.join(stringify(p) for p in params) param_str = ', '.join(stringify(p) for p in params)
return 'Union[%s]' % param_str return 'Union[%s]' % param_str

View File

@@ -127,7 +127,7 @@ def test_signature_partialmethod():
def test_signature_annotations(): def test_signature_annotations():
from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10,
f11, f12, f13, f14, f15, f16, f17, f18, f19, Node) f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, Node)
# Class annotations # Class annotations
sig = inspect.signature(f0) sig = inspect.signature(f0)
@@ -184,6 +184,10 @@ def test_signature_annotations():
sig = inspect.signature(f13) sig = inspect.signature(f13)
assert stringify_signature(sig) == '() -> Optional[str]' assert stringify_signature(sig) == '() -> Optional[str]'
# optional union
sig = inspect.signature(f20)
assert stringify_signature(sig) == '() -> Optional[Union[int, str]]'
# Any # Any
sig = inspect.signature(f14) sig = inspect.signature(f14)
assert stringify_signature(sig) == '() -> Any' assert stringify_signature(sig) == '() -> Any'

View File

@@ -96,6 +96,10 @@ def f19(*args: int, **kwargs: str):
pass pass
def f20() -> Optional[Union[int, str]]:
pass
class Node: class Node:
def __init__(self, parent: Optional['Node']) -> None: def __init__(self, parent: Optional['Node']) -> None: