Hello community,

here is the log from the commit of package python-sphinx-autodoc-typehints for 
openSUSE:Factory checked in at 2020-03-10 14:05:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sphinx-autodoc-typehints (Old)
 and      /work/SRC/openSUSE:Factory/.python-sphinx-autodoc-typehints.new.26092 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sphinx-autodoc-typehints"

Tue Mar 10 14:05:52 2020 rev:5 rq:782837 version:1.10.3

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-sphinx-autodoc-typehints/python-sphinx-autodoc-typehints.changes
  2019-09-17 13:39:14.165825381 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-sphinx-autodoc-typehints.new.26092/python-sphinx-autodoc-typehints.changes
       2020-03-10 14:05:52.903400813 +0100
@@ -1,0 +2,22 @@
+Fri Mar  6 14:50:12 UTC 2020 - [email protected]
+
+- version update to 1.10.3
+  * Fixed ``TypeError`` (or wrong rendered class name) when an annotation is a 
generic class that has
+    a ``name`` property
+  * Fixed inner classes missing their parent class name(s) when rendered
+  * Fixed ``KeyError`` when encountering mocked annotations 
(``autodoc_mock_imports``)
+  * Rewrote the annotation formatting logic (fixes Python 3.5.2 compatibility 
regressions and an
+    ``AttributeError`` regression introduced in v1.9.0)
+  * Fixed decorator classes not being processed as classes
+  * Added support for typing_extensions_
+  * Added the ``typehints_document_rtype`` option (PR by Simon-Martin Schröder)
+  * Fixed metaclasses as annotations causing ``TypeError``
+  * Fixed rendering of ``typing.Literal``
+  * Fixed OSError when generating docs for SQLAlchemy mapped classes
+  * Fixed unparametrized generic classes being rendered with their type 
parameters
+    (e.g. ``Dict[~KT, ~VT]``)
+- added patches
+  fix use object.inv which comes with python-doc
+  + python-sphinx-autodoc-typehints-system-object.inv.patch
+
+-------------------------------------------------------------------

Old:
----
  sphinx-autodoc-typehints-1.8.0.tar.gz

New:
----
  python-sphinx-autodoc-typehints-system-object.inv.patch
  sphinx-autodoc-typehints-1.10.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-sphinx-autodoc-typehints.spec ++++++
--- /var/tmp/diff_new_pack.pM4fJF/_old  2020-03-10 14:05:53.627401165 +0100
+++ /var/tmp/diff_new_pack.pM4fJF/_new  2020-03-10 14:05:53.627401165 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-sphinx-autodoc-typehints
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,13 +19,15 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-sphinx-autodoc-typehints
-Version:        1.8.0
+Version:        1.10.3
 Release:        0
 Summary:        Type hints (PEP 484) support for the Sphinx autodoc extension
 License:        MIT
 Group:          Development/Languages/Python
 URL:            https://github.com/agronholm/sphinx-autodoc-typehints
 Source:         
https://files.pythonhosted.org/packages/source/s/sphinx-autodoc-typehints/sphinx-autodoc-typehints-%{version}.tar.gz
+# use object.inv which comes with python-doc; TODO more elegant solution
+Patch0:         python-sphinx-autodoc-typehints-system-object.inv.patch
 BuildRequires:  %{python_module setuptools >= 36.2.7}
 BuildRequires:  %{python_module setuptools_scm >= 1.7.0}
 BuildRequires:  fdupes
@@ -35,8 +37,10 @@
 BuildArch:      noarch
 # SECTION tests
 BuildRequires:  %{python_module Sphinx >= 1.7}
+BuildRequires:  %{python_module doc}
 BuildRequires:  %{python_module pathlib}
 BuildRequires:  %{python_module pytest}
+BuildRequires:  %{python_module sphobjinv}
 BuildRequires:  %{python_module typing_extensions}
 # /SECTION
 %python_subpackages
@@ -47,6 +51,7 @@
 
 %prep
 %setup -q -n sphinx-autodoc-typehints-%{version}
+%patch0 -p1
 
 %build
 %python_build

++++++ python-sphinx-autodoc-typehints-system-object.inv.patch ++++++
Index: sphinx-autodoc-typehints-1.10.3/tests/conftest.py
===================================================================
--- sphinx-autodoc-typehints-1.10.3.orig/tests/conftest.py      2019-11-11 
20:10:08.000000000 +0100
+++ sphinx-autodoc-typehints-1.10.3/tests/conftest.py   2020-03-06 
15:49:28.411760937 +0100
@@ -13,10 +13,8 @@ collect_ignore = ['roots']
 
 @pytest.fixture(scope='session')
 def inv(pytestconfig):
-    cache_path = 
'python{v.major}.{v.minor}/objects.inv'.format(v=sys.version_info)
-    inv_dict = pytestconfig.cache.get(cache_path, None)
-    if inv_dict is not None:
-        return Inventory(inv_dict)
+    inv_dict = '/usr/share/doc/packages/python3/html/objects.inv'
+    return Inventory(inv_dict)
 
     print("Downloading objects.inv")
     url = 
'https://docs.python.org/{v.major}.{v.minor}/objects.inv'.format(v=sys.version_info)
++++++ sphinx-autodoc-typehints-1.8.0.tar.gz -> 
sphinx-autodoc-typehints-1.10.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.8.0/.gitignore 
new/sphinx-autodoc-typehints-1.10.3/.gitignore
--- old/sphinx-autodoc-typehints-1.8.0/.gitignore       2019-09-12 
08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/.gitignore      2019-11-11 
20:10:08.000000000 +0100
@@ -10,3 +10,4 @@
 __pycache__/
 dist/
 build/
+.vscode/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.8.0/.travis.yml 
new/sphinx-autodoc-typehints-1.10.3/.travis.yml
--- old/sphinx-autodoc-typehints-1.8.0/.travis.yml      2019-09-12 
08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/.travis.yml     2019-11-11 
20:10:08.000000000 +0100
@@ -15,12 +15,17 @@
 
     - stage: test
       env: TOXENV=py35
-      python: "3.5"
+      python: "3.5.2"
       after_success: &after_success
         - pip install coveralls
         - coveralls
 
     - stage: test
+      env: TOXENV=py35
+      python: "3.5"
+      after_success: *after_success
+
+    - stage: test
       env: TOXENV=py36
       python: "3.6"
       after_success: *after_success
@@ -32,7 +37,7 @@
 
     - stage: test
       env: TOXENV=py38
-      python: "3.8-dev"
+      python: "3.8"
       after_success: *after_success
 
     - stage: deploy to pypi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.8.0/CHANGELOG.rst 
new/sphinx-autodoc-typehints-1.10.3/CHANGELOG.rst
--- old/sphinx-autodoc-typehints-1.8.0/CHANGELOG.rst    2019-09-12 
08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/CHANGELOG.rst   2019-11-11 
20:10:08.000000000 +0100
@@ -1,3 +1,44 @@
+1.10.3
+======
+
+* Fixed ``TypeError`` (or wrong rendered class name) when an annotation is a 
generic class that has
+  a ``name`` property
+
+
+1.10.2
+======
+
+* Fixed inner classes missing their parent class name(s) when rendered
+
+
+1.10.1
+======
+
+* Fixed ``KeyError`` when encountering mocked annotations 
(``autodoc_mock_imports``)
+
+
+1.10.0
+======
+
+* Rewrote the annotation formatting logic (fixes Python 3.5.2 compatibility 
regressions and an
+  ``AttributeError`` regression introduced in v1.9.0)
+* Fixed decorator classes not being processed as classes
+
+
+1.9.0
+=====
+
+* Added support for typing_extensions_
+* Added the ``typehints_document_rtype`` option (PR by Simon-Martin Schröder)
+* Fixed metaclasses as annotations causing ``TypeError``
+* Fixed rendering of ``typing.Literal``
+* Fixed OSError when generating docs for SQLAlchemy mapped classes
+* Fixed unparametrized generic classes being rendered with their type 
parameters
+  (e.g. ``Dict[~KT, ~VT]``)
+
+.. _typing_extensions: https://pypi.org/project/typing-extensions/
+
+
 1.8.0
 =====
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.8.0/PKG-INFO 
new/sphinx-autodoc-typehints-1.10.3/PKG-INFO
--- old/sphinx-autodoc-typehints-1.8.0/PKG-INFO 2019-09-12 08:34:19.000000000 
+0200
+++ new/sphinx-autodoc-typehints-1.10.3/PKG-INFO        2019-11-11 
20:10:25.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: sphinx-autodoc-typehints
-Version: 1.8.0
+Version: 1.10.3
 Summary: Type hints (PEP 484) support for the Sphinx autodoc extension
 Home-page: UNKNOWN
 Author: Alex Grönholm
@@ -74,6 +74,8 @@
         * ``always_document_param_types`` (default: ``False``): If ``False``, 
do not add type info for
           undocumented parameters.  If ``True``, add stub documentation for 
undocumented parameters to
           be able to add type info.
+        * ``typehints_document_rtype`` (default: ``True``): If ``False``, 
never add an ``:rtype:`` directive.
+          If ``True``, add the ``:rtype:`` directive if no existing 
``:rtype:`` is found.
         
         
         How it works
@@ -153,5 +155,5 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Requires-Python: >=3.5.2
-Provides-Extra: type_comments
 Provides-Extra: test
+Provides-Extra: type_comments
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.8.0/README.rst 
new/sphinx-autodoc-typehints-1.10.3/README.rst
--- old/sphinx-autodoc-typehints-1.8.0/README.rst       2019-09-12 
08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/README.rst      2019-11-11 
20:10:08.000000000 +0100
@@ -63,6 +63,8 @@
 * ``always_document_param_types`` (default: ``False``): If ``False``, do not 
add type info for
   undocumented parameters.  If ``True``, add stub documentation for 
undocumented parameters to
   be able to add type info.
+* ``typehints_document_rtype`` (default: ``True``): If ``False``, never add an 
``:rtype:`` directive.
+  If ``True``, add the ``:rtype:`` directive if no existing ``:rtype:`` is 
found.
 
 
 How it works
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.8.0/setup.cfg 
new/sphinx-autodoc-typehints-1.10.3/setup.cfg
--- old/sphinx-autodoc-typehints-1.8.0/setup.cfg        2019-09-12 
08:34:19.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/setup.cfg       2019-11-11 
20:10:25.000000000 +0100
@@ -33,6 +33,7 @@
        pytest >= 3.1.0
        typing_extensions >= 3.5
        dataclasses; python_version == "3.6"
+       sphobjinv >= 2.0
 type_comments = 
        typed_ast >= 1.4.0; python_version < "3.8"
 
@@ -40,6 +41,7 @@
 max-line-length = 99
 
 [tool:pytest]
+addopts = -rsx --tb=short
 testpaths = tests
 
 [egg_info]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.8.0/sphinx_autodoc_typehints.egg-info/PKG-INFO 
new/sphinx-autodoc-typehints-1.10.3/sphinx_autodoc_typehints.egg-info/PKG-INFO
--- 
old/sphinx-autodoc-typehints-1.8.0/sphinx_autodoc_typehints.egg-info/PKG-INFO   
    2019-09-12 08:34:19.000000000 +0200
+++ 
new/sphinx-autodoc-typehints-1.10.3/sphinx_autodoc_typehints.egg-info/PKG-INFO  
    2019-11-11 20:10:25.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: sphinx-autodoc-typehints
-Version: 1.8.0
+Version: 1.10.3
 Summary: Type hints (PEP 484) support for the Sphinx autodoc extension
 Home-page: UNKNOWN
 Author: Alex Grönholm
@@ -74,6 +74,8 @@
         * ``always_document_param_types`` (default: ``False``): If ``False``, 
do not add type info for
           undocumented parameters.  If ``True``, add stub documentation for 
undocumented parameters to
           be able to add type info.
+        * ``typehints_document_rtype`` (default: ``True``): If ``False``, 
never add an ``:rtype:`` directive.
+          If ``True``, add the ``:rtype:`` directive if no existing 
``:rtype:`` is found.
         
         
         How it works
@@ -153,5 +155,5 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Requires-Python: >=3.5.2
-Provides-Extra: type_comments
 Provides-Extra: test
+Provides-Extra: type_comments
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.8.0/sphinx_autodoc_typehints.egg-info/requires.txt
 
new/sphinx-autodoc-typehints-1.10.3/sphinx_autodoc_typehints.egg-info/requires.txt
--- 
old/sphinx-autodoc-typehints-1.8.0/sphinx_autodoc_typehints.egg-info/requires.txt
   2019-09-12 08:34:19.000000000 +0200
+++ 
new/sphinx-autodoc-typehints-1.10.3/sphinx_autodoc_typehints.egg-info/requires.txt
  2019-11-11 20:10:25.000000000 +0100
@@ -3,6 +3,7 @@
 [test]
 pytest>=3.1.0
 typing_extensions>=3.5
+sphobjinv>=2.0
 
 [test:python_version == "3.6"]
 dataclasses
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.8.0/sphinx_autodoc_typehints.py 
new/sphinx-autodoc-typehints-1.10.3/sphinx_autodoc_typehints.py
--- old/sphinx-autodoc-typehints-1.8.0/sphinx_autodoc_typehints.py      
2019-09-12 08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/sphinx_autodoc_typehints.py     
2019-11-11 20:10:08.000000000 +0100
@@ -2,145 +2,156 @@
 import sys
 import textwrap
 import typing
-from typing import get_type_hints, TypeVar, Any, AnyStr, Generic, Union
+from typing import get_type_hints, TypeVar, Any, AnyStr, Tuple
 
 from sphinx.util import logging
 from sphinx.util.inspect import Signature
 
-try:
-    from typing_extensions import Protocol
-except ImportError:
-    Protocol = None
-
 logger = logging.getLogger(__name__)
-pydata_annotations = {'Any', 'AnyStr', 'Callable', 'ClassVar', 'NoReturn', 
'Optional', 'Tuple',
-                      'Union'}
+pydata_annotations = {'Any', 'AnyStr', 'Callable', 'ClassVar', 'Literal', 
'NoReturn', 'Optional',
+                      'Tuple', 'Union'}
 
 
-def format_annotation(annotation, fully_qualified=False):
-    if inspect.isclass(annotation) and annotation.__module__ == 'builtins':
-        if annotation.__qualname__ == 'NoneType':
-            return '``None``'
+def get_annotation_module(annotation) -> str:
+    # Special cases
+    if annotation is None:
+        return 'builtins'
+
+    if hasattr(annotation, '__module__'):
+        return annotation.__module__
+
+    if hasattr(annotation, '__origin__'):
+        return annotation.__origin__.__module__
+
+    raise ValueError('Cannot determine the module of {}'.format(annotation))
+
+
+def get_annotation_class_name(annotation, module: str) -> str:
+    # Special cases
+    if annotation is None:
+        return 'None'
+    elif annotation is Any:
+        return 'Any'
+    elif annotation is AnyStr:
+        return 'AnyStr'
+    elif inspect.isfunction(annotation) and hasattr(annotation, 
'__supertype__'):
+        return 'NewType'
+
+    if getattr(annotation, '__qualname__', None):
+        return annotation.__qualname__
+    elif getattr(annotation, '_name', None):  # Required for generic aliases 
on Python 3.7+
+        return annotation._name
+    elif getattr(annotation, 'name', None) and module in ('typing', 
'typing_extensions'):
+        # Required for at least Pattern and Match
+        return annotation.name
+
+    origin = getattr(annotation, '__origin__', None)
+    if origin:
+        if getattr(origin, '__qualname__', None):  # Required for Protocol 
subclasses
+            return origin.__qualname__
+        elif getattr(origin, '_name', None):  # Required for Union on Python 
3.7+
+            return origin._name
         else:
-            return ':py:class:`{}`'.format(annotation.__qualname__)
+            return origin.__class__.__qualname__.lstrip('_')  # Required for 
Union on Python < 3.7
 
-    annotation_cls = annotation if inspect.isclass(annotation) else 
type(annotation)
-    if annotation_cls.__module__ == 'typing':
-        class_name = str(annotation).split('[')[0].split('.')[-1]
-        params = None
-        module = 'typing'
-        extra = ''
+    annotation_cls = annotation if inspect.isclass(annotation) else 
annotation.__class__
+    return annotation_cls.__qualname__.lstrip('_')
+
+
+def get_annotation_args(annotation, module: str, class_name: str) -> Tuple:
+    try:
+        original = getattr(sys.modules[module], class_name)
+    except (KeyError, AttributeError):
+        pass
+    else:
+        if annotation is original:
+            return ()  # This is the original, unparametrized type
 
-        origin = getattr(annotation, '__origin__', None)
-        if inspect.isclass(origin):
-            annotation_cls = annotation.__origin__
-            try:
-                mro = annotation_cls.mro()
-                if Generic in mro or (Protocol and Protocol in mro):
-                    module = annotation_cls.__module__
-            except TypeError:
-                pass  # annotation_cls was either the "type" object or 
typing.Type
-
-        if annotation is Any:
-            return ':py:data:`{}typing.Any`'.format("" if fully_qualified else 
"~")
-        elif annotation is AnyStr:
-            return ':py:data:`{}typing.AnyStr`'.format("" if fully_qualified 
else "~")
-        elif isinstance(annotation, TypeVar):
-            return '\\%r' % annotation
-        elif (annotation is Union or getattr(annotation, '__origin__', None) 
is Union or
-              hasattr(annotation, '__union_params__')):
-            if hasattr(annotation, '__union_params__'):
-                params = annotation.__union_params__
-            elif hasattr(annotation, '__args__'):
-                params = annotation.__args__
-
-            if params and len(params) == 2 and (hasattr(params[1], 
'__qualname__') and
-                                                params[1].__qualname__ == 
'NoneType'):
-                class_name = 'Optional'
-                params = (params[0],)
-        elif annotation_cls.__qualname__ == 'Tuple' and hasattr(annotation, 
'__tuple_params__'):
-            params = annotation.__tuple_params__
-            if annotation.__tuple_use_ellipsis__:
-                params += (Ellipsis,)
-        elif annotation_cls.__qualname__ == 'Callable':
-            arg_annotations = result_annotation = None
-            if hasattr(annotation, '__result__'):
-                arg_annotations = annotation.__args__
-                result_annotation = annotation.__result__
-            elif getattr(annotation, '__args__', None):
-                arg_annotations = annotation.__args__[:-1]
-                result_annotation = annotation.__args__[-1]
-
-            if arg_annotations in (Ellipsis, (Ellipsis,)):
-                params = [Ellipsis, result_annotation]
-            elif arg_annotations is not None:
-                params = [
-                    '\\[{}]'.format(
-                        ', '.join(
-                            format_annotation(param, fully_qualified)
-                            for param in arg_annotations)),
-                    result_annotation
-                ]
-        elif str(annotation).startswith('typing.ClassVar[') and 
hasattr(annotation, '__type__'):
-            # < py3.7
-            params = (annotation.__type__,)
-        elif hasattr(annotation, 'type_var'):
-            # Type alias
-            class_name = annotation.name
-            params = (annotation.type_var,)
-        elif getattr(annotation, '__args__', None) is not None:
-            params = annotation.__args__
-        elif hasattr(annotation, '__parameters__'):
-            params = annotation.__parameters__
-
-        if params:
-            extra = '\\[{}]'.format(', '.join(
-                format_annotation(param, fully_qualified) for param in params))
-
-        return '{prefix}`{qualify}{module}.{name}`{extra}'.format(
-            prefix=':py:data:' if class_name in pydata_annotations else 
':py:class:',
-            qualify="" if fully_qualified else "~",
-            module=module,
-            name=class_name,
-            extra=extra
-        )
+    # Special cases
+    if class_name in ('Pattern', 'Match') and hasattr(annotation, 'type_var'): 
 # Python < 3.7
+        return annotation.type_var,
+    elif class_name == 'Callable' and hasattr(annotation, '__result__'):  # 
Python < 3.5.3
+        argtypes = (Ellipsis,) if annotation.__args__ is Ellipsis else 
annotation.__args__
+        return argtypes + (annotation.__result__,)
+    elif class_name == 'Union' and hasattr(annotation, '__union_params__'):  # 
Union on Python 3.5
+        return annotation.__union_params__
+    elif class_name == 'Tuple' and hasattr(annotation, '__tuple_params__'):  # 
Tuple on Python 3.5
+        params = annotation.__tuple_params__
+        if getattr(annotation, '__tuple_use_ellipsis__', False):
+            params += (Ellipsis,)
+
+        return params
+    elif class_name == 'ClassVar' and hasattr(annotation, '__type__'):  # 
ClassVar on Python < 3.7
+        return annotation.__type__,
+    elif class_name == 'NewType' and hasattr(annotation, '__supertype__'):
+        return annotation.__supertype__,
+    elif class_name == 'Literal' and hasattr(annotation, '__values__'):
+        return annotation.__values__
+    elif class_name == 'Generic':
+        return annotation.__parameters__
+
+    return getattr(annotation, '__args__', ())
+
+
+def format_annotation(annotation, fully_qualified: bool = False) -> str:
+    # Special cases
+    if annotation is None or annotation is type(None):  # noqa: E721
+        return '``None``'
     elif annotation is Ellipsis:
         return '...'
-    elif (inspect.isfunction(annotation) and annotation.__module__ == 'typing' 
and
-          hasattr(annotation, '__name__') and hasattr(annotation, 
'__supertype__')):
-        return ':py:func:`{qualify}typing.NewType`\\(:py:data:`~{name}`, 
{extra})'.format(
-            qualify="" if fully_qualified else "~",
-            name=annotation.__name__,
-            extra=format_annotation(annotation.__supertype__, fully_qualified),
-        )
-    elif inspect.isclass(annotation) or inspect.isclass(getattr(annotation, 
'__origin__', None)):
-        if not inspect.isclass(annotation):
-            annotation_cls = annotation.__origin__
-
-        extra = ''
-        mro = annotation_cls.mro()
-        if Generic in mro or (Protocol and Protocol in mro):
-            params = (getattr(annotation, '__parameters__', None) or
-                      getattr(annotation, '__args__', None))
-            if params:
-                extra = '\\[{}]'.format(', '.join(
-                    format_annotation(param, fully_qualified) for param in 
params))
-
-        return ':py:class:`{qualify}{module}.{name}`{extra}'.format(
-            qualify="" if fully_qualified else "~",
-            module=annotation.__module__,
-            name=annotation_cls.__qualname__,
-            extra=extra
-        )
 
-    return str(annotation)
+    # Type variables are also handled specially
+    try:
+        if isinstance(annotation, TypeVar) and annotation is not AnyStr:
+            return '\\' + repr(annotation)
+    except TypeError:
+        pass
+
+    try:
+        module = get_annotation_module(annotation)
+        class_name = get_annotation_class_name(annotation, module)
+        args = get_annotation_args(annotation, module, class_name)
+    except ValueError:
+        return str(annotation)
+
+    # Redirect all typing_extensions types to the stdlib typing module
+    if module == 'typing_extensions':
+        module = 'typing'
+
+    full_name = (module + '.' + class_name) if module != 'builtins' else 
class_name
+    prefix = '' if fully_qualified or full_name == class_name else '~'
+    role = 'data' if class_name in pydata_annotations else 'class'
+    args_format = '\\[{}]'
+    formatted_args = ''
+
+    # Some types require special handling
+    if full_name == 'typing.NewType':
+        args_format = '\\(:py:data:`~{name}`, {{}})'.format(prefix=prefix,
+                                                            
name=annotation.__name__)
+        role = 'func'
+    elif full_name == 'typing.Union' and len(args) == 2 and type(None) in args:
+        full_name = 'typing.Optional'
+        args = tuple(x for x in args if x is not type(None))  # noqa: E721
+    elif full_name == 'typing.Callable' and args and args[0] is not ...:
+        formatted_args = '\\[\\[' + ', '.join(format_annotation(arg) for arg 
in args[:-1]) + ']'
+        formatted_args += ', ' + format_annotation(args[-1]) + ']'
+    elif full_name == 'typing.Literal':
+        formatted_args = '\\[' + ', '.join(repr(arg) for arg in args) + ']'
+
+    if args and not formatted_args:
+        formatted_args = args_format.format(', '.join(format_annotation(arg, 
fully_qualified)
+                                                      for arg in args))
+
+    return ':py:{role}:`{prefix}{full_name}`{formatted_args}'.format(
+        role=role, prefix=prefix, full_name=full_name, 
formatted_args=formatted_args)
 
 
 def process_signature(app, what: str, name: str, obj, options, signature, 
return_annotation):
     if not callable(obj):
         return
 
-    if what in ('class', 'exception'):
+    original_obj = obj
+    if inspect.isclass(obj):
         obj = getattr(obj, '__init__', getattr(obj, '__new__', None))
 
     if not getattr(obj, '__annotations__', None):
@@ -160,7 +171,7 @@
         return
 
     if parameters:
-        if what in ('class', 'exception'):
+        if inspect.isclass(original_obj):
             del parameters[0]
         elif what == 'method':
             outer = inspect.getmodule(obj)
@@ -245,7 +256,7 @@
 
     try:
         obj_ast = ast.parse(textwrap.dedent(inspect.getsource(obj)), 
**parse_kwargs)
-    except TypeError:
+    except (OSError, TypeError):
         return {}
 
     obj_ast = _one_child(obj_ast)
@@ -339,11 +350,12 @@
 
 
 def process_docstring(app, what, name, obj, options, lines):
+    original_obj = obj
     if isinstance(obj, property):
         obj = obj.fget
 
     if callable(obj):
-        if what in ('class', 'exception'):
+        if inspect.isclass(obj):
             obj = getattr(obj, '__init__')
 
         obj = inspect.unwrap(obj)
@@ -376,7 +388,7 @@
                     ':type {}: {}'.format(argname, formatted_annotation)
                 )
 
-        if 'return' in type_hints and what not in ('class', 'exception'):
+        if 'return' in type_hints and not inspect.isclass(original_obj):
             formatted_annotation = format_annotation(
                 type_hints['return'], 
fully_qualified=app.config.typehints_fully_qualified)
 
@@ -388,7 +400,7 @@
                 elif line.startswith(':return:') or 
line.startswith(':returns:'):
                     insert_index = i
 
-            if insert_index is not None:
+            if insert_index is not None and 
app.config.typehints_document_rtype:
                 if insert_index == len(lines):
                     # Ensure that :rtype: doesn't get joined with a paragraph 
of text, which
                     # prevents it being interpreted.
@@ -407,6 +419,7 @@
     app.add_config_value('set_type_checking_flag', False, 'html')
     app.add_config_value('always_document_param_types', False, 'html')
     app.add_config_value('typehints_fully_qualified', False, 'env')
+    app.add_config_value('typehints_document_rtype', True, 'env')
     app.connect('builder-inited', builder_ready)
     app.connect('autodoc-process-signature', process_signature)
     app.connect('autodoc-process-docstring', process_docstring)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.8.0/tests/conftest.py 
new/sphinx-autodoc-typehints-1.10.3/tests/conftest.py
--- old/sphinx-autodoc-typehints-1.8.0/tests/conftest.py        2019-09-12 
08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/tests/conftest.py       2019-11-11 
20:10:08.000000000 +0100
@@ -1,14 +1,30 @@
 import os
+import sys
 import pathlib
 import shutil
 
 import pytest
 from sphinx.testing.path import path
+from sphobjinv import Inventory
 
 pytest_plugins = 'sphinx.testing.fixtures'
 collect_ignore = ['roots']
 
 
[email protected](scope='session')
+def inv(pytestconfig):
+    cache_path = 
'python{v.major}.{v.minor}/objects.inv'.format(v=sys.version_info)
+    inv_dict = pytestconfig.cache.get(cache_path, None)
+    if inv_dict is not None:
+        return Inventory(inv_dict)
+
+    print("Downloading objects.inv")
+    url = 
'https://docs.python.org/{v.major}.{v.minor}/objects.inv'.format(v=sys.version_info)
+    inv = Inventory(url=url)
+    pytestconfig.cache.set(cache_path, inv.json_dict())
+    return inv
+
+
 @pytest.fixture(autouse=True)
 def remove_sphinx_projects(sphinx_test_tempdir):
     # Remove any directory which appears to be a Sphinx project from
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.8.0/tests/roots/test-dummy/dummy_module.py 
new/sphinx-autodoc-typehints-1.10.3/tests/roots/test-dummy/dummy_module.py
--- old/sphinx-autodoc-typehints-1.8.0/tests/roots/test-dummy/dummy_module.py   
2019-09-12 08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/tests/roots/test-dummy/dummy_module.py  
2019-11-11 20:10:08.000000000 +0100
@@ -1,4 +1,5 @@
 import typing
+from mailbox import Mailbox
 from typing import Callable, Union
 
 try:
@@ -237,3 +238,22 @@
 @dataclass
 class DataClass:
     """Class docstring."""
+
+
+class Decorator:
+    """
+    Initializer docstring.
+
+    :param func: function
+    """
+
+    def __init__(self, func: Callable[[int, str], str]):
+        pass
+
+
+def mocked_import(x: Mailbox):
+    """
+    A docstring.
+
+    :param x: function
+    """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.8.0/tests/roots/test-dummy/index.rst 
new/sphinx-autodoc-typehints-1.10.3/tests/roots/test-dummy/index.rst
--- old/sphinx-autodoc-typehints-1.8.0/tests/roots/test-dummy/index.rst 
2019-09-12 08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/tests/roots/test-dummy/index.rst        
2019-11-11 20:10:08.000000000 +0100
@@ -32,3 +32,7 @@
 .. autoclass:: dummy_module.DataClass
     :undoc-members:
     :special-members: __init__
+
+.. autodecorator:: dummy_module.Decorator
+
+.. autofunction:: dummy_module.mocked_import
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.8.0/tests/test_sphinx_autodoc_typehints.py 
new/sphinx-autodoc-typehints-1.10.3/tests/test_sphinx_autodoc_typehints.py
--- old/sphinx-autodoc-typehints-1.8.0/tests/test_sphinx_autodoc_typehints.py   
2019-09-12 08:34:03.000000000 +0200
+++ new/sphinx-autodoc-typehints-1.10.3/tests/test_sphinx_autodoc_typehints.py  
2019-11-11 20:10:08.000000000 +0100
@@ -1,24 +1,23 @@
 import pathlib
-import pytest
+import re
 import sys
 import textwrap
+import typing
 from typing import (
-    Any, AnyStr, Callable, Dict, Generic, Mapping, NewType, Optional, Pattern,
-    Tuple, TypeVar, Union, Type)
-
-from typing_extensions import Protocol
+    Any, AnyStr, Callable, Dict, Generic, Mapping, NewType, Optional, Pattern, 
Match, Tuple,
+    TypeVar, Union, Type)
 
-from sphinx_autodoc_typehints import format_annotation, process_docstring
+import pytest
+import typing_extensions
 
-try:
-    from typing import ClassVar  # not available prior to Python 3.5.3
-except ImportError:
-    ClassVar = None
+from sphinx_autodoc_typehints import (
+    format_annotation, process_docstring, get_annotation_module, 
get_annotation_class_name,
+    get_annotation_args)
 
 try:
-    from typing import NoReturn  # not available prior to Python 3.6.5
+    from typing import IO
 except ImportError:
-    NoReturn = None
+    from typing.io import IO
 
 T = TypeVar('T')
 U = TypeVar('U', covariant=True)
@@ -30,20 +29,24 @@
     def get_type(self):
         return type(self)
 
+    class Inner:
+        pass
+
 
 class B(Generic[T]):
-    pass
+    # This is set to make sure the correct class name ("B") is picked up
+    name = 'Foo'
 
 
 class C(B[str]):
     pass
 
 
-class D(Protocol):
+class D(typing_extensions.Protocol):
     pass
 
 
-class E(Protocol[T]):
+class E(typing_extensions.Protocol[T]):
     pass
 
 
@@ -51,26 +54,64 @@
     __slots__ = ()
 
 
+class Metaclass(type):
+    pass
+
+
[email protected]('annotation, module, class_name, args', [
+    pytest.param(str, 'builtins', 'str', (), id='str'),
+    pytest.param(None, 'builtins', 'None', (), id='None'),
+    pytest.param(Any, 'typing', 'Any', (), id='Any'),
+    pytest.param(AnyStr, 'typing', 'AnyStr', (), id='AnyStr'),
+    pytest.param(Dict, 'typing', 'Dict', (), id='Dict'),
+    pytest.param(Dict[str, int], 'typing', 'Dict', (str, int), 
id='Dict_parametrized'),
+    pytest.param(Dict[T, int], 'typing', 'Dict', (T, int), id='Dict_typevar'),
+    pytest.param(Tuple, 'typing', 'Tuple', (), id='Tuple'),
+    pytest.param(Tuple[str, int], 'typing', 'Tuple', (str, int), 
id='Tuple_parametrized'),
+    pytest.param(Union[str, int], 'typing', 'Union', (str, int), id='Union'),
+    pytest.param(Callable, 'typing', 'Callable', (), id='Callable'),
+    pytest.param(Callable[..., str], 'typing', 'Callable', (..., str), 
id='Callable_returntype'),
+    pytest.param(Callable[[int, str], str], 'typing', 'Callable', (int, str, 
str),
+                 id='Callable_all_types'),
+    pytest.param(Pattern, 'typing', 'Pattern', (), id='Pattern'),
+    pytest.param(Pattern[str], 'typing', 'Pattern', (str,), 
id='Pattern_parametrized'),
+    pytest.param(Match, 'typing', 'Match', (), id='Match'),
+    pytest.param(Match[str], 'typing', 'Match', (str,), 
id='Match_parametrized'),
+    pytest.param(IO, 'typing', 'IO', (), id='IO'),
+    pytest.param(W, 'typing', 'NewType', (str,), id='W'),
+    pytest.param(Metaclass, __name__, 'Metaclass', (), id='Metaclass'),
+    pytest.param(Slotted, __name__, 'Slotted', (), id='Slotted'),
+    pytest.param(A, __name__, 'A', (), id='A'),
+    pytest.param(B, __name__, 'B', (), id='B'),
+    pytest.param(C, __name__, 'C', (), id='C'),
+    pytest.param(D, __name__, 'D', (), id='D'),
+    pytest.param(E, __name__, 'E', (), id='E'),
+    pytest.param(E[int], __name__, 'E', (int,), id='E_parametrized'),
+    pytest.param(A.Inner, __name__, 'A.Inner', (), id='Inner')
+])
+def test_parse_annotation(annotation, module, class_name, args):
+    assert get_annotation_module(annotation) == module
+    assert get_annotation_class_name(annotation, module) == class_name
+    assert get_annotation_args(annotation, module, class_name) == args
+
+
 @pytest.mark.parametrize('annotation, expected_result', [
     (str,                           ':py:class:`str`'),
     (int,                           ':py:class:`int`'),
     (type(None),                    '``None``'),
-    pytest.param(NoReturn,          ':py:data:`~typing.NoReturn`',
-                 marks=[pytest.mark.skipif(NoReturn is None,
-                                           reason='typing.NoReturn is not 
available')]),
-    pytest.param(ClassVar[str],      
':py:data:`~typing.ClassVar`\\[:py:class:`str`]',
-                 marks=[pytest.mark.skipif(ClassVar is None,
-                                           reason='typing.ClassVar is not 
available')]),
+    (type,                          ':py:class:`type`'),
+    (Type,                          ':py:class:`~typing.Type`'),
+    (Type[A],                       
':py:class:`~typing.Type`\\[:py:class:`~%s.A`]' % __name__),
     (Any,                           ':py:data:`~typing.Any`'),
     (AnyStr,                        ':py:data:`~typing.AnyStr`'),
     (Generic[T],                    ':py:class:`~typing.Generic`\\[\\~T]'),
-    (Mapping,                       ':py:class:`~typing.Mapping`\\[\\~KT, 
\\+VT_co]'),
+    (Mapping,                       ':py:class:`~typing.Mapping`'),
     (Mapping[T, int],               ':py:class:`~typing.Mapping`\\[\\~T, 
:py:class:`int`]'),
     (Mapping[str, V],               
':py:class:`~typing.Mapping`\\[:py:class:`str`, \\-V]'),
     (Mapping[T, U],                 ':py:class:`~typing.Mapping`\\[\\~T, 
\\+U]'),
     (Mapping[str, bool],            
':py:class:`~typing.Mapping`\\[:py:class:`str`, '
                                     ':py:class:`bool`]'),
-    (Dict,                          ':py:class:`~typing.Dict`\\[\\~KT, 
\\~VT]'),
+    (Dict,                          ':py:class:`~typing.Dict`'),
     (Dict[T, int],                  ':py:class:`~typing.Dict`\\[\\~T, 
:py:class:`int`]'),
     (Dict[str, V],                  
':py:class:`~typing.Dict`\\[:py:class:`str`, \\-V]'),
     (Dict[T, U],                    ':py:class:`~typing.Dict`\\[\\~T, \\+U]'),
@@ -99,90 +140,60 @@
     (Callable[[int, str], None],    
':py:data:`~typing.Callable`\\[\\[:py:class:`int`, '
                                     ':py:class:`str`], ``None``]'),
     (Callable[[T], T],              ':py:data:`~typing.Callable`\\[\\[\\~T], 
\\~T]'),
-    (Pattern,                       
':py:class:`~typing.Pattern`\\[:py:data:`~typing.AnyStr`]'),
+    (Pattern,                       ':py:class:`~typing.Pattern`'),
     (Pattern[str],                  
':py:class:`~typing.Pattern`\\[:py:class:`str`]'),
+    (IO,                            ':py:class:`~typing.IO`'),
+    (Metaclass,                     ':py:class:`~%s.Metaclass`' % __name__),
     (A,                             ':py:class:`~%s.A`' % __name__),
-    (B,                             ':py:class:`~%s.B`\\[\\~T]' % __name__),
+    (B,                             ':py:class:`~%s.B`' % __name__),
     (B[int],                        ':py:class:`~%s.B`\\[:py:class:`int`]' % 
__name__),
     (C,                             ':py:class:`~%s.C`' % __name__),
     (D,                             ':py:class:`~%s.D`' % __name__),
-    (E,                             ':py:class:`~%s.E`\\[\\~T]' % __name__),
+    (E,                             ':py:class:`~%s.E`' % __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):
+def test_format_annotation(inv, annotation, expected_result):
     result = format_annotation(annotation)
     assert result == expected_result
 
-
[email protected]('annotation, expected_result', [
-    (str,                           ':py:class:`str`'),
-    (int,                           ':py:class:`int`'),
-    (type(None),                    '``None``'),
-    pytest.param(NoReturn,          ':py:data:`typing.NoReturn`',
-                 marks=[pytest.mark.skipif(NoReturn is None,
-                                           reason='typing.NoReturn is not 
available')]),
-    pytest.param(ClassVar[str],      
':py:data:`typing.ClassVar`\\[:py:class:`str`]',
-                 marks=[pytest.mark.skipif(ClassVar is None,
-                                           reason='typing.ClassVar is not 
available')]),
-    (Any,                           ':py:data:`typing.Any`'),
-    (AnyStr,                        ':py:data:`typing.AnyStr`'),
-    (Generic[T],                    ':py:class:`typing.Generic`\\[\\~T]'),
-    (Mapping,                       ':py:class:`typing.Mapping`\\[\\~KT, 
\\+VT_co]'),
-    (Mapping[T, int],               ':py:class:`typing.Mapping`\\[\\~T, 
:py:class:`int`]'),
-    (Mapping[str, V],               
':py:class:`typing.Mapping`\\[:py:class:`str`, \\-V]'),
-    (Mapping[T, U],                 ':py:class:`typing.Mapping`\\[\\~T, 
\\+U]'),
-    (Mapping[str, bool],            
':py:class:`typing.Mapping`\\[:py:class:`str`, '
-                                    ':py:class:`bool`]'),
-    (Dict,                          ':py:class:`typing.Dict`\\[\\~KT, \\~VT]'),
-    (Dict[T, int],                  ':py:class:`typing.Dict`\\[\\~T, 
:py:class:`int`]'),
-    (Dict[str, V],                  
':py:class:`typing.Dict`\\[:py:class:`str`, \\-V]'),
-    (Dict[T, U],                    ':py:class:`typing.Dict`\\[\\~T, \\+U]'),
-    (Dict[str, bool],               
':py:class:`typing.Dict`\\[:py:class:`str`, '
-                                    ':py:class:`bool`]'),
-    (Tuple,                         ':py:data:`typing.Tuple`'),
-    (Tuple[str, bool],              
':py:data:`typing.Tuple`\\[:py:class:`str`, '
-                                    ':py:class:`bool`]'),
-    (Tuple[int, int, int],          
':py:data:`typing.Tuple`\\[:py:class:`int`, '
-                                    ':py:class:`int`, :py:class:`int`]'),
-    (Tuple[str, ...],               
':py:data:`typing.Tuple`\\[:py:class:`str`, ...]'),
-    (Union,                         ':py:data:`typing.Union`'),
-    (Union[str, bool],              
':py:data:`typing.Union`\\[:py:class:`str`, '
-                                    ':py:class:`bool`]'),
-    (Optional[str],                 
':py:data:`typing.Optional`\\[:py:class:`str`]'),
-    (Callable,                      ':py:data:`typing.Callable`'),
-    (Callable[..., int],            ':py:data:`typing.Callable`\\[..., 
:py:class:`int`]'),
-    (Callable[[int], int],          
':py:data:`typing.Callable`\\[\\[:py:class:`int`], '
-                                    ':py:class:`int`]'),
-    (Callable[[int, str], bool],    
':py:data:`typing.Callable`\\[\\[:py:class:`int`, '
-                                    ':py:class:`str`], :py:class:`bool`]'),
-    (Callable[[int, str], None],    
':py:data:`typing.Callable`\\[\\[:py:class:`int`, '
-                                    ':py:class:`str`], ``None``]'),
-    (Callable[[T], T],              ':py:data:`typing.Callable`\\[\\[\\~T], 
\\~T]'),
-    (Pattern,                       
':py:class:`typing.Pattern`\\[:py:data:`typing.AnyStr`]'),
-    (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__),
-    (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__),
-    (W,                             
':py:func:`typing.NewType`\\(:py:data:`~W`, :py:class:`str`)')
+    # Test with the "fully_qualified" flag turned on
+    if 'typing' in expected_result or __name__ in expected_result:
+        expected_result = expected_result.replace('~typing', 'typing')
+        expected_result = expected_result.replace('~' + __name__, __name__)
+        assert format_annotation(annotation, fully_qualified=True) == 
expected_result
+
+    # Test for the correct role (class vs data) using the official Sphinx 
inventory
+    if 'typing' in expected_result:
+        m = re.match('^:py:(?P<role>class|data|func):`~(?P<name>[^`]+)`', 
result)
+        assert m, 'No match'
+        name = m.group('name')
+        expected_role = next((o.role for o in inv.objects if o.name == name), 
None)
+        if expected_role:
+            if expected_role == 'function':
+                expected_role = 'func'
+
+            assert m.group('role') == expected_role
+
+
[email protected]('library', [typing, typing_extensions],
+                         ids=['typing', 'typing_extensions'])
[email protected]('annotation, params, expected_result', [
+    ('ClassVar', int, ":py:data:`~typing.ClassVar`\\[:py:class:`int`]"),
+    ('NoReturn', None, ":py:data:`~typing.NoReturn`"),
+    ('Literal', ('a', 1), ":py:data:`~typing.Literal`\\['a', 1]"),
+    ('Type', None, ':py:class:`~typing.Type`'),
+    ('Type', (A,), ':py:class:`~typing.Type`\\[:py:class:`~%s.A`]' % __name__)
 ])
-def test_format_annotation_fully_qualified(annotation, expected_result):
-    result = format_annotation(annotation, fully_qualified=True)
-    assert result == expected_result
+def test_format_annotation_both_libs(inv, library, annotation, params, 
expected_result):
+    try:
+        annotation_cls = getattr(library, annotation)
+    except AttributeError:
+        pytest.skip('{} not available in the {} module'.format(annotation, 
library.__name__))
 
-
[email protected]('type_param, expected_result', [
-    (None, ':py:class:`~typing.Type`\\[\\+CT'),
-    (A, ':py:class:`~typing.Type`\\[:py:class:`~%s.A`]' % __name__)
-])
-def test_format_annotation_type(type_param, expected_result):
-    annotation = Type[type_param] if type_param else Type
-    result = format_annotation(annotation)
-    assert result.startswith(expected_result)
+    ann = annotation_cls if params is None else annotation_cls[params]
+    result = format_annotation(ann)
+    assert result == expected_result
 
 
 def test_process_docstring_slot_wrapper():
@@ -201,6 +212,7 @@
         sys.path.insert(0, str(test_path))
 
     app.config.always_document_param_types = always_document_param_types
+    app.config.autodoc_mock_imports = ['mailbox']
     app.build()
 
     assert 'build succeeded' in status.getvalue()  # Build succeeded
@@ -209,14 +221,17 @@
     warnings = warning.getvalue().strip()
     assert 'Cannot resolve forward reference in type annotations of ' in 
warnings, warnings
 
+    format_args = {}
     if always_document_param_types:
-        undoc_params = '''
-
-           Parameters:
-              **x** ("int") --'''
+        format_args['undoc_params'] = '\n\n   Parameters:\n      **x** ("int") 
--'
+    else:
+        format_args['undoc_params'] = ""
 
+    if sys.version_info < (3, 6):
+        format_args['dataclass_docstring'] = ('Initialize self.  See 
help(type(self)) for '
+                                              'accurate signature.')
     else:
-        undoc_params = ""
+        format_args['dataclass_docstring'] = 'Return type:\n         "None"'
 
     text_path = pathlib.Path(app.srcdir) / '_build' / 'text' / 'index.txt'
     with text_path.open('r') as f:
@@ -469,16 +484,22 @@
            Class docstring.
 
            __init__()
-        '''.format(undoc_params=undoc_params)).replace('–', '--')
 
-        if sys.version_info < (3, 6):
-            expected_contents += '''
-      Initialize self.  See help(type(self)) for accurate signature.
-'''
-        else:
-            expected_contents += '''
-      Return type:
-         "None"
-'''
+              {dataclass_docstring}
+
+        @dummy_module.Decorator(func)
+
+           Initializer docstring.
+
+           Parameters:
+              **func** ("Callable"[["int", "str"], "str"]) -- function
+
+        dummy_module.mocked_import(x)
 
+           A docstring.
+
+           Parameters:
+              **x** ("Mailbox") -- function
+        ''')
+        expected_contents = 
expected_contents.format(**format_args).replace('–', '--')
         assert text_contents == expected_contents


Reply via email to