ext.autodoc: fix formatting instance annotations

Currently `format_annotation` fails on instances, because instances don't have
`__module__` and `__qualname__` attributes.  Defer building the
`qualified_name` of an annotation until we have established that the annotation
is a type.
This commit is contained in:
Joost van Zwieten 2016-07-29 12:27:00 +02:00
parent da7e2d9dda
commit 099b58f7fe
4 changed files with 17 additions and 4 deletions

View File

@ -15,6 +15,7 @@ Bugs fixed
* #2778: Fix autodoc crashes if obj.__dict__ is a property method and raises exception
* Fix duplicated toc in epub3 output.
* #2775: Fix failing linkcheck with servers not supporting identidy encoding
* #2833: Fix formatting instance annotations in ext.autodoc.
Release 1.4.5 (released Jul 13, 2016)
=====================================

View File

@ -261,12 +261,13 @@ def format_annotation(annotation):
Displaying complex types from ``typing`` relies on its private API.
"""
if not isinstance(annotation, type):
return repr(annotation)
qualified_name = (annotation.__module__ + '.' + annotation.__qualname__
if annotation else repr(annotation))
if not isinstance(annotation, type):
return repr(annotation)
elif annotation.__module__ == 'builtins':
if annotation.__module__ == 'builtins':
return annotation.__qualname__
elif typing:
if isinstance(annotation, typing.TypeVar):

View File

@ -1025,7 +1025,7 @@ def test_type_hints():
from sphinx.util.inspect import getargspec
try:
from typing_test_data import f0, f1, f2, f3, f4, f5, f6, f7, f8
from typing_test_data import f0, f1, f2, f3, f4, f5, f6, f7, f8, f9
except (ImportError, SyntaxError):
raise SkipTest('Cannot import Python code with function annotations')
@ -1061,3 +1061,6 @@ def test_type_hints():
# Tuple types
verify_arg_spec(f8, '(x: typing.Tuple[int, str],'
' y: typing.Tuple[int, ...]) -> None')
# Instance annotations
verify_arg_spec(f9, '(x: CustomAnnotation, y: 123) -> None')

View File

@ -46,3 +46,11 @@ def f7(x: Callable[[int, str], int]) -> None:
def f8(x: Tuple[int, str], y: Tuple[int, ...]) -> None:
pass
class CustomAnnotation:
def __repr__(self):
return 'CustomAnnotation'
def f9(x: CustomAnnotation(), y: 123) -> None:
pass