Repository: agronholm/sphinx-autodoc-typehints

Issue:
Types created with NewType are rendered poorly.
If I have code like:
```
    Foo = typing.NewType('Foo', str)
    def bar(x: Foo):
        pass
```
then its parameter gets documented as:
```
    x (<function NewType.<locals>.new_type at 0x7f644b4c6488>)
```
I was expecting something like one of the following:
```
    x (Foo)
    x (Foo alias for str)
    x (str)
```

Discussion:
rmorshea: @agronholm thoughts on this?
agronholm: I'll try to take a look at this this weekend.

Patch:
diff --git a/sphinx_autodoc_typehints.py b/sphinx_autodoc_typehints.py
index e7f8f4a..3eafe5b 100644
--- a/sphinx_autodoc_typehints.py
+++ b/sphinx_autodoc_typehints.py
@@ -117,6 +117,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__')):
+        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__


Test patch:
diff --git a/tests/test_sphinx_autodoc_typehints.py b/tests/test_sphinx_autodoc_typehints.py
index cba630f..6c4df94 100644
--- a/tests/test_sphinx_autodoc_typehints.py
+++ b/tests/test_sphinx_autodoc_typehints.py
@@ -3,7 +3,8 @@ import pytest
 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 typing_extensions import Protocol
 
@@ -12,6 +13,7 @@ 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:
@@ -89,7 +91,8 @@ class Slotted:
     (C,                             ':py:class:`~%s.C`' % __name__),
     (D,                             ':py:class:`~%s.D`' % __name__),
     (E,                             ':py:class:`~%s.E`\\[\\~T]' % __name__),
-    (E[int],                        ':py:class:`~%s.E`\\[:py:class:`int`]' % __name__)
+    (E[int],                        ':py:class:`~%s.E`\\[: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)