From 0f37a59fa7ce95252a7ce6c1e2c1c92da5ff6dd2 Mon Sep 17 00:00:00 2001 From: George Leslie-Waksman Date: Wed, 21 Nov 2018 12:24:18 -0800 Subject: [PATCH 1/2] Identify typing.NewType wrappers and construct annotation references --- sphinx_autodoc_typehints.py | 4 ++++ tests/test_sphinx_autodoc_typehints.py | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sphinx_autodoc_typehints.py b/sphinx_autodoc_typehints.py index 90a8ac88..df79fc60 100644 --- a/sphinx_autodoc_typehints.py +++ b/sphinx_autodoc_typehints.py @@ -111,6 +111,10 @@ def format_annotation(annotation): return '{}`~{}.{}`{}'.format(prefix, module, class_name, extra) elif annotation is Ellipsis: return '...' + elif (inspect.isfunction(annotation) and annotation.__module__ == 'typing' and + hasattr(annotation, '__name__') and hasattr(annotation, '__supertype__')): + # NewType + return ':py:func:`~typing.NewType`\\(:py:data:`~{}`, {})'.format(annotation.__name__, format_annotation(annotation.__supertype__)) elif inspect.isclass(annotation) or inspect.isclass(getattr(annotation, '__origin__', None)): if not inspect.isclass(annotation): annotation_cls = annotation.__origin__ diff --git a/tests/test_sphinx_autodoc_typehints.py b/tests/test_sphinx_autodoc_typehints.py index 145de1e6..f15c0fd1 100644 --- a/tests/test_sphinx_autodoc_typehints.py +++ b/tests/test_sphinx_autodoc_typehints.py @@ -3,13 +3,15 @@ import sys import textwrap from typing import ( - Any, AnyStr, Callable, Dict, Generic, Mapping, Optional, Pattern, Tuple, TypeVar, Union, Type) + Any, AnyStr, Callable, Dict, Generic, Mapping, NewType, Optional, Pattern, + Tuple, TypeVar, Union, Type) from sphinx_autodoc_typehints import format_annotation, process_docstring T = TypeVar('T') U = TypeVar('U', covariant=True) V = TypeVar('V', contravariant=True) +W = NewType('W', str) class A: @@ -71,7 +73,9 @@ class Slotted: (Pattern[str], ':py:class:`~typing.Pattern`\\[:py:class:`str`]'), (A, ':py:class:`~%s.A`' % __name__), (B, ':py:class:`~%s.B`\\[\\~T]' % __name__), - (B[int], ':py:class:`~%s.B`\\[:py:class:`int`]' % __name__) + (B[int], ':py:class:`~%s.B`\\[:py:class:`int`]' % __name__), + (W, ':py:func:`~typing.NewType`\\(:py:data:`~W`, ' + ':py:class:`str`)'), ]) def test_format_annotation(annotation, expected_result): result = format_annotation(annotation) From 198d277b79f64a84f60d08a0d73e07ca32800e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Sun, 23 Dec 2018 14:04:00 +0200 Subject: [PATCH 2/2] Fixed flake8 error --- sphinx_autodoc_typehints.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx_autodoc_typehints.py b/sphinx_autodoc_typehints.py index 70248814..3eafe5b2 100644 --- a/sphinx_autodoc_typehints.py +++ b/sphinx_autodoc_typehints.py @@ -119,8 +119,8 @@ def format_annotation(annotation): return '...' elif (inspect.isfunction(annotation) and annotation.__module__ == 'typing' and hasattr(annotation, '__name__') and hasattr(annotation, '__supertype__')): - # NewType - return ':py:func:`~typing.NewType`\\(:py:data:`~{}`, {})'.format(annotation.__name__, format_annotation(annotation.__supertype__)) + return ':py:func:`~typing.NewType`\\(:py:data:`~{}`, {})'.format( + annotation.__name__, format_annotation(annotation.__supertype__)) elif inspect.isclass(annotation) or inspect.isclass(getattr(annotation, '__origin__', None)): if not inspect.isclass(annotation): annotation_cls = annotation.__origin__