Fix #4490: autodoc: type annotation is broken with python 3.7.0a4+

This commit is contained in:
Takeshi KOMIYA
2018-01-27 12:20:39 +09:00
parent 376b6a597d
commit fd2425238e
3 changed files with 51 additions and 6 deletions

View File

@@ -24,6 +24,7 @@ Bugs fixed
* #4415: autodoc classifies inherited classmethods as regular methods * #4415: autodoc classifies inherited classmethods as regular methods
* #4415: autodoc classifies inherited staticmethods as regular methods * #4415: autodoc classifies inherited staticmethods as regular methods
* #4472: DOCUMENTATION_OPTIONS is not defined * #4472: DOCUMENTATION_OPTIONS is not defined
* #4490: autodoc: type annotation is broken with python 3.7.0a4+
Testing Testing
-------- --------

View File

@@ -431,6 +431,55 @@ class Signature(object):
Displaying complex types from ``typing`` relies on its private API. Displaying complex types from ``typing`` relies on its private API.
""" """
if sys.version_info >= (3, 7): # py37+
return self.format_annotation_new(annotation)
else:
return self.format_annotation_old(annotation)
def format_annotation_new(self, annotation):
# type: (Any) -> str
"""format_annotation() for py37+"""
module = getattr(annotation, '__module__', None)
if isinstance(annotation, string_types):
return annotation # type: ignore
elif isinstance(annotation, typing.TypeVar): # type: ignore
return annotation.__name__
elif not annotation:
return repr(annotation)
elif module == 'builtins':
return annotation.__qualname__
elif annotation is Ellipsis:
return '...'
if module == 'typing':
if getattr(annotation, '_name', None):
qualname = annotation._name
elif getattr(annotation, '__qualname__', None):
qualname = annotation.__qualname__
else:
qualname = self.format_annotation(annotation.__origin__) # ex. Union
elif hasattr(annotation, '__qualname__'):
qualname = '%s.%s' % (module, annotation.__qualname__)
else:
qualname = repr(annotation)
if getattr(annotation, '__args__', None):
if qualname == 'Union':
args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
return '%s[%s]' % (qualname, args)
elif qualname == 'Callable':
args = ', '.join(self.format_annotation(a) for a in annotation.__args__[:-1])
returns = self.format_annotation(annotation.__args__[-1])
return '%s[[%s], %s]' % (qualname, args, returns)
else:
args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
return '%s[%s]' % (qualname, args)
return qualname
def format_annotation_old(self, annotation):
# type: (Any) -> str
"""format_annotation() for py36 or below"""
if isinstance(annotation, string_types): if isinstance(annotation, string_types):
return annotation # type: ignore return annotation # type: ignore
if isinstance(annotation, typing.TypeVar): # type: ignore if isinstance(annotation, typing.TypeVar): # type: ignore

View File

@@ -215,12 +215,7 @@ def test_Signature_annotations():
# TypeVars and generic types with TypeVars # TypeVars and generic types with TypeVars
sig = inspect.Signature(f2).format_args() sig = inspect.Signature(f2).format_args()
if sys.version_info < (3, 7): assert sig == '(x: List[T], y: List[T_co], z: T) -> List[T_contra]'
sig == ('(x: typing.List[T], y: typing.List[T_co], z: T) -> '
'typing.List[T_contra]')
else:
sig == ('(x: typing.List[~T], y: typing.List[+T_co], z: T) -> '
'typing.List[-T_contra]')
# Union types # Union types
sig = inspect.Signature(f3).format_args() sig = inspect.Signature(f3).format_args()