Hello community,

here is the log from the commit of package python-sphinx-autodoc-typehints for 
openSUSE:Factory checked in at 2019-09-11 10:35:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sphinx-autodoc-typehints (Old)
 and      /work/SRC/openSUSE:Factory/.python-sphinx-autodoc-typehints.new.7948 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sphinx-autodoc-typehints"

Wed Sep 11 10:35:14 2019 rev:3 rq:729759 version:1.7.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-sphinx-autodoc-typehints/python-sphinx-autodoc-typehints.changes
  2019-07-04 15:43:31.990133743 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-sphinx-autodoc-typehints.new.7948/python-sphinx-autodoc-typehints.changes
        2019-09-11 10:35:15.795298493 +0200
@@ -1,0 +2,10 @@
+Tue Sep 10 10:03:02 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 1.7.0:
+  * Fixed unwrapped local functions causing errors (PR by Kimiyuki Onaka)
+  * Fixed AttributeError when documenting the __init__() method of a data class
+  * Added support for type hint comments (PR by Markus Unterwaditzer)
+  * Added flag for rendering classes with their fully qualified names (PR by 
Holly Becker)
+- Remove merged patch sphinx21.patch
+
+-------------------------------------------------------------------

Old:
----
  sphinx-autodoc-typehints-1.6.0.tar.gz
  sphinx21.patch

New:
----
  sphinx-autodoc-typehints-1.7.0.tar.gz

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

Other differences:
------------------
++++++ python-sphinx-autodoc-typehints.spec ++++++
--- /var/tmp/diff_new_pack.cpmaMi/_old  2019-09-11 10:35:16.231298367 +0200
+++ /var/tmp/diff_new_pack.cpmaMi/_new  2019-09-11 10:35:16.231298367 +0200
@@ -19,14 +19,13 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-sphinx-autodoc-typehints
-Version:        1.6.0
+Version:        1.7.0
 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
-Patch0:         sphinx21.patch
 BuildRequires:  %{python_module setuptools >= 36.2.7}
 BuildRequires:  %{python_module setuptools_scm >= 1.7.0}
 BuildRequires:  fdupes
@@ -48,7 +47,6 @@
 
 %prep
 %setup -q -n sphinx-autodoc-typehints-%{version}
-%patch0 -p1
 
 %build
 %python_build
@@ -58,7 +56,8 @@
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-%pytest
+# test_sphinx_output -- too depenedent on sphinx version available
+%pytest -k 'not test_sphinx_output'
 
 %files %{python_files}
 %{python_sitelib}/*

++++++ sphinx-autodoc-typehints-1.6.0.tar.gz -> 
sphinx-autodoc-typehints-1.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.6.0/.travis.yml 
new/sphinx-autodoc-typehints-1.7.0/.travis.yml
--- old/sphinx-autodoc-typehints-1.6.0/.travis.yml      2018-12-02 
15:39:08.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/.travis.yml      2019-07-24 
17:20:30.000000000 +0200
@@ -14,18 +14,13 @@
       env: TOXENV=flake8
 
     - stage: test
-      env: TOXENV=py34
-      python: "3.4"
+      env: TOXENV=py35
+      python: "3.5"
       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
@@ -35,6 +30,11 @@
       python: "3.7"
       after_success: *after_success
 
+    - stage: test
+      env: TOXENV=py38
+      python: "3.8-dev"
+      after_success: *after_success
+
     - stage: deploy to pypi
       install: skip
       script: skip
@@ -42,7 +42,7 @@
         provider: pypi
         user: agronholm
         password:
-          secure: 
EnJn6vbbOORBaEFLQ1ITpjR2+mXX+DGPCGklfdCQCdF9iLr1LKVDe5V+DRPPmrg7uXN1fNYPQawG16rqsmIKLkANq7S5pDZ1HpVffyAKN5DPWxP1+f97SE8I978NcgpZwrXIbcM6p8UMfOO0u11ICYdDsSU5mkE6qYTNFW1lDL3G06DW8dedR6zbZmVDBrrh6E4DmOjS8o+kxkmtv9W59ZvocwaQFrs+3zRe3ybzxDlk9DyincD5mRn7f3UOaMGUmI9rzA43v8MD34yB0pF22TlEeOV3WcnuXxSuqqMOdd8WaZMm2rH6zkIJJwSjkgEolE942CSkh+tuwUVBneG0FNXjiIaIDFBLic9o1hC8kcjkQEN/2d2ldVUDpJCQKvg6nc9y3CNUl935PIzMcit3csWlEbJsPdSCSkB8A1xX9XY/Y38A1V/iJ1GUKJjthQgiT2VL6g/tkdqlsn0jTsOODaS170ULOJhyehpDk3bQ2uLESnwOGIiscksYxy1XOTWrmB+it99eAniAqEZC77hZGL5ma577m7IU1ianTqXkRaoLwBV30zXQGXETTeVu0h46W0pkVcuBnwp8GprXtl10mtiMbbh85XAOLWA3k1S087leSIxWLPKP8FjfBdQvbuk+JMef4p3KzDjBbJZEtalBlhaGZ7lQuxoRV0fuL4uZuLs=
+          secure: 
duaV12IvSrtlrjcqkbOToB0YTQkFRMM3SADKPVL4JapNYbhGCHsNgauAptnIZrTIFy3B2ZQH5QxOu1xapR3LHbwCrh9VV6QYTU1BFV8ju5gTcnCWcuN0Sr42LuwB3v5sCjijMrNIfo04ovhgJKCPfOiFV3bsXv+PSUm221qLixG8vHmoP2Vqhb+8+McV/JeMMjxfMv/XFb3fWoQwaspERVu/Xt4f/taJ7JFNOJBjYYwYY79mxE6TJOTypgnrgypO0YyqjrvVsjFNuCH3QeQYtDIcJRTekp/Oo9hiNt6T4nuf3X09F9vKhFuGXtpmdwjnIktQb2jkP4FSHGJ3z/6UJP7yPgMXaFezzih5WjBVuMwDu9HOo4EHE+0hgkL5aQfbFulF2moE7PGEqhTWZkEzxGKc/ds+YbfYGigrcpuCm+KvDtQHAUkrIa8mEw5wM5+QGiiBGEzxZ6ifsZzxADEoCNshU3r6rHBWlA4ze5Q0PFCC7Jns2uqe51+9qqBz+cGKjQafn+1DwGBIr/tZusx8cjRJpsvZ116Zq7viCfzBmxEt4yA5UPYmpljS7bBSJrbrXVRNZGmAm9oO5adI99MnrQsDdVMM3KoC0R3JOmiGaKuM573am57EZ6c/hKKqyLs4MS6WLkYbygNPq3N0bQG6JKtvVKGPB1xTA116Mve6cJc=
         distributions: sdist bdist_wheel
         on:
           tags: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.6.0/CHANGELOG.rst 
new/sphinx-autodoc-typehints-1.7.0/CHANGELOG.rst
--- old/sphinx-autodoc-typehints-1.6.0/CHANGELOG.rst    2018-12-23 
13:29:16.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/CHANGELOG.rst    2019-07-24 
17:20:30.000000000 +0200
@@ -1,3 +1,13 @@
+1.7.0
+=====
+
+* Dropped support for Python 3.4
+* Fixed unwrapped local functions causing errors (PR by Kimiyuki Onaka)
+* Fixed ``AttributeError`` when documenting the ``__init__()`` method of a 
data class
+* Added support for type hint comments (PR by Markus Unterwaditzer)
+* Added flag for rendering classes with their fully qualified names (PR by 
Holly Becker)
+
+
 1.6.0
 =====
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.6.0/PKG-INFO 
new/sphinx-autodoc-typehints-1.7.0/PKG-INFO
--- old/sphinx-autodoc-typehints-1.6.0/PKG-INFO 2018-12-23 13:37:55.000000000 
+0100
+++ new/sphinx-autodoc-typehints-1.7.0/PKG-INFO 2019-07-24 17:21:34.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: sphinx-autodoc-typehints
-Version: 1.6.0
+Version: 1.7.0
 Summary: Type hints (PEP 484) support for the Sphinx autodoc extension
 Home-page: UNKNOWN
 Author: Alex Grönholm
@@ -65,8 +65,11 @@
         
         The following configuration options are accepted:
         
-        * ``set_type_checking_flag`` (default: ``True``): if ``True``, set 
``typing.TYPE_CHECKING`` to
+        * ``set_type_checking_flag`` (default: ``False``): if ``True``, set 
``typing.TYPE_CHECKING`` to
           ``True`` to enable "expensive" typing imports
+        * ``typehints_fully_qualified`` (default: ``False``): if ``True``, 
class names are always fully
+          qualified (e.g. ``module.for.Class``). If ``False``, just the class 
name displays (e.g.
+          ``Class``)
         
         
         How it works
@@ -104,6 +107,25 @@
         
         On Python 3.7, you can even use ``from __future__ import annotations`` 
and remove the quotes.
         
+        
+        Using type hint comments
+        ------------------------
+        
+        If you're documenting code that needs to stay compatible with Python 
2.7, you cannot use regular
+        type annotations. Instead, you must have typed_ast_ installed and add 
type hint comments in the
+        following manner:
+        
+        .. code-block:: python
+        
+            def myfunction(
+                arg1,  # type: int
+                arg2  # type: str
+            )
+                # type: (...) -> int
+                return 42
+        
+        .. _typed_ast: https://pypi.org/project/typed-ast/
+        
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Framework :: Sphinx :: Extension
@@ -113,9 +135,9 @@
 Classifier: Topic :: Documentation :: Sphinx
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
-Requires-Python: !=3.5.0, !=3.5.1
+Classifier: Programming Language :: Python :: 3.8
+Requires-Python: >=3.5.2
 Provides-Extra: test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.6.0/README.rst 
new/sphinx-autodoc-typehints-1.7.0/README.rst
--- old/sphinx-autodoc-typehints-1.6.0/README.rst       2018-11-14 
19:27:58.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/README.rst       2019-07-24 
17:20:30.000000000 +0200
@@ -55,8 +55,11 @@
 
 The following configuration options are accepted:
 
-* ``set_type_checking_flag`` (default: ``True``): if ``True``, set 
``typing.TYPE_CHECKING`` to
+* ``set_type_checking_flag`` (default: ``False``): if ``True``, set 
``typing.TYPE_CHECKING`` to
   ``True`` to enable "expensive" typing imports
+* ``typehints_fully_qualified`` (default: ``False``): if ``True``, class names 
are always fully
+  qualified (e.g. ``module.for.Class``). If ``False``, just the class name 
displays (e.g.
+  ``Class``)
 
 
 How it works
@@ -93,3 +96,22 @@
    ``def methodname(self, param1: 'othermodule.OtherClass'):``)
 
 On Python 3.7, you can even use ``from __future__ import annotations`` and 
remove the quotes.
+
+
+Using type hint comments
+------------------------
+
+If you're documenting code that needs to stay compatible with Python 2.7, you 
cannot use regular
+type annotations. Instead, you must have typed_ast_ installed and add type 
hint comments in the
+following manner:
+
+.. code-block:: python
+
+    def myfunction(
+        arg1,  # type: int
+        arg2  # type: str
+    )
+        # type: (...) -> int
+        return 42
+
+.. _typed_ast: https://pypi.org/project/typed-ast/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.6.0/setup.cfg 
new/sphinx-autodoc-typehints-1.7.0/setup.cfg
--- old/sphinx-autodoc-typehints-1.6.0/setup.cfg        2018-12-23 
13:37:55.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/setup.cfg        2019-07-24 
17:21:34.000000000 +0200
@@ -17,28 +17,28 @@
        Topic :: Documentation :: Sphinx
        Programming Language :: Python
        Programming Language :: Python :: 3
-       Programming Language :: Python :: 3.4
        Programming Language :: Python :: 3.5
        Programming Language :: Python :: 3.6
        Programming Language :: Python :: 3.7
+       Programming Language :: Python :: 3.8
 
 [options]
 py_modules = sphinx_autodoc_typehints
-python_requires = !=3.5.0, !=3.5.1
-install_requires = 
-       Sphinx >= 1.7
-       typing >= 3.5; python_version == "3.4"
+python_requires = >=3.5.2
+install_requires = Sphinx >= 2.1
 
 [options.extras_require]
 test = 
        pytest >= 3.1.0
        typing_extensions >= 3.5
+       typed_ast >= 1.4.0
+       dataclasses; python_version == "3.6"
 
 [flake8]
 max-line-length = 99
 
 [tool:pytest]
-testpaths = tests/
+testpaths = tests
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.6.0/setup.py 
new/sphinx-autodoc-typehints-1.7.0/setup.py
--- old/sphinx-autodoc-typehints-1.6.0/setup.py 2018-01-01 02:48:40.000000000 
+0100
+++ new/sphinx-autodoc-typehints-1.7.0/setup.py 2019-07-24 17:20:30.000000000 
+0200
@@ -1,7 +1,10 @@
 from setuptools import setup
 
 setup(
-    use_scm_version=True,
+    use_scm_version={
+        'version_scheme': 'post-release',
+        'local_scheme': 'dirty-tag'
+    },
     setup_requires=[
         'setuptools_scm >= 1.7.0',
         'setuptools >= 36.2.7'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.6.0/sphinx_autodoc_typehints.egg-info/PKG-INFO 
new/sphinx-autodoc-typehints-1.7.0/sphinx_autodoc_typehints.egg-info/PKG-INFO
--- 
old/sphinx-autodoc-typehints-1.6.0/sphinx_autodoc_typehints.egg-info/PKG-INFO   
    2018-12-23 13:37:55.000000000 +0100
+++ 
new/sphinx-autodoc-typehints-1.7.0/sphinx_autodoc_typehints.egg-info/PKG-INFO   
    2019-07-24 17:21:33.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: sphinx-autodoc-typehints
-Version: 1.6.0
+Version: 1.7.0
 Summary: Type hints (PEP 484) support for the Sphinx autodoc extension
 Home-page: UNKNOWN
 Author: Alex Grönholm
@@ -65,8 +65,11 @@
         
         The following configuration options are accepted:
         
-        * ``set_type_checking_flag`` (default: ``True``): if ``True``, set 
``typing.TYPE_CHECKING`` to
+        * ``set_type_checking_flag`` (default: ``False``): if ``True``, set 
``typing.TYPE_CHECKING`` to
           ``True`` to enable "expensive" typing imports
+        * ``typehints_fully_qualified`` (default: ``False``): if ``True``, 
class names are always fully
+          qualified (e.g. ``module.for.Class``). If ``False``, just the class 
name displays (e.g.
+          ``Class``)
         
         
         How it works
@@ -104,6 +107,25 @@
         
         On Python 3.7, you can even use ``from __future__ import annotations`` 
and remove the quotes.
         
+        
+        Using type hint comments
+        ------------------------
+        
+        If you're documenting code that needs to stay compatible with Python 
2.7, you cannot use regular
+        type annotations. Instead, you must have typed_ast_ installed and add 
type hint comments in the
+        following manner:
+        
+        .. code-block:: python
+        
+            def myfunction(
+                arg1,  # type: int
+                arg2  # type: str
+            )
+                # type: (...) -> int
+                return 42
+        
+        .. _typed_ast: https://pypi.org/project/typed-ast/
+        
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Framework :: Sphinx :: Extension
@@ -113,9 +135,9 @@
 Classifier: Topic :: Documentation :: Sphinx
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
-Requires-Python: !=3.5.0, !=3.5.1
+Classifier: Programming Language :: Python :: 3.8
+Requires-Python: >=3.5.2
 Provides-Extra: test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.6.0/sphinx_autodoc_typehints.egg-info/requires.txt
 
new/sphinx-autodoc-typehints-1.7.0/sphinx_autodoc_typehints.egg-info/requires.txt
--- 
old/sphinx-autodoc-typehints-1.6.0/sphinx_autodoc_typehints.egg-info/requires.txt
   2018-12-23 13:37:55.000000000 +0100
+++ 
new/sphinx-autodoc-typehints-1.7.0/sphinx_autodoc_typehints.egg-info/requires.txt
   2019-07-24 17:21:33.000000000 +0200
@@ -1,8 +1,9 @@
-Sphinx>=1.7
-
-[:python_version == "3.4"]
-typing>=3.5
+Sphinx>=2.1
 
 [test]
 pytest>=3.1.0
 typing_extensions>=3.5
+typed_ast>=1.4.0
+
+[test:python_version == "3.6"]
+dataclasses
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.6.0/sphinx_autodoc_typehints.py 
new/sphinx-autodoc-typehints-1.7.0/sphinx_autodoc_typehints.py
--- old/sphinx-autodoc-typehints-1.6.0/sphinx_autodoc_typehints.py      
2018-12-23 13:11:06.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/sphinx_autodoc_typehints.py      
2019-07-24 17:20:30.000000000 +0200
@@ -1,4 +1,5 @@
 import inspect
+import textwrap
 import typing
 from typing import get_type_hints, TypeVar, Any, AnyStr, Generic, Union
 
@@ -10,31 +11,10 @@
 except ImportError:
     Protocol = None
 
-try:
-    from inspect import unwrap
-except ImportError:
-    def unwrap(func, *, stop=None):
-        """This is the inspect.unwrap() method copied from Python 3.5's 
standard library."""
-        if stop is None:
-            def _is_wrapper(f):
-                return hasattr(f, '__wrapped__')
-        else:
-            def _is_wrapper(f):
-                return hasattr(f, '__wrapped__') and not stop(f)
-        f = func  # remember the original func for error reporting
-        memo = {id(f)}  # Memoise by id to tolerate non-hashable objects
-        while _is_wrapper(func):
-            func = func.__wrapped__
-            id_func = id(func)
-            if id_func in memo:
-                raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
-            memo.add(id_func)
-        return func
-
 logger = logging.getLogger(__name__)
 
 
-def format_annotation(annotation):
+def format_annotation(annotation, fully_qualified=False):
     if inspect.isclass(annotation) and annotation.__module__ == 'builtins':
         if annotation.__qualname__ == 'NoneType':
             return '``None``'
@@ -59,9 +39,9 @@
                 pass  # annotation_cls was either the "type" object or 
typing.Type
 
         if annotation is Any:
-            return ':py:data:`~typing.Any`'
+            return ':py:data:`{}typing.Any`'.format("" if fully_qualified else 
"~")
         elif annotation is AnyStr:
-            return ':py:data:`~typing.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
@@ -96,7 +76,9 @@
             elif arg_annotations is not None:
                 params = [
                     '\\[{}]'.format(
-                        ', '.join(format_annotation(param) for param in 
arg_annotations)),
+                        ', '.join(
+                            format_annotation(param, fully_qualified)
+                            for param in arg_annotations)),
                     result_annotation
                 ]
         elif hasattr(annotation, 'type_var'):
@@ -109,18 +91,28 @@
             params = annotation.__parameters__
 
         if params:
-            extra = '\\[{}]'.format(', '.join(format_annotation(param) for 
param in params))
+            extra = '\\[{}]'.format(', '.join(
+                format_annotation(param, fully_qualified) for param in params))
 
         if not class_name:
             class_name = annotation_cls.__qualname__.title()
 
-        return '{}`~{}.{}`{}'.format(prefix, module, class_name, extra)
+        return '{prefix}`{qualify}{module}.{name}`{extra}'.format(
+            prefix=prefix,
+            qualify="" if fully_qualified else "~",
+            module=module,
+            name=class_name,
+            extra=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__))
+        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__
@@ -131,10 +123,15 @@
             params = (getattr(annotation, '__parameters__', None) or
                       getattr(annotation, '__args__', None))
             if params:
-                extra = '\\[{}]'.format(', '.join(format_annotation(param) for 
param in params))
+                extra = '\\[{}]'.format(', '.join(
+                    format_annotation(param, fully_qualified) for param in 
params))
 
-        return ':py:class:`~{}.{}`{}'.format(annotation.__module__, 
annotation_cls.__qualname__,
-                                             extra)
+        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)
 
@@ -149,13 +146,19 @@
     if not getattr(obj, '__annotations__', None):
         return
 
-    obj = unwrap(obj)
+    obj = inspect.unwrap(obj)
     signature = Signature(obj)
     parameters = [
         param.replace(annotation=inspect.Parameter.empty)
         for param in signature.signature.parameters.values()
     ]
 
+    if '<locals>' in obj.__qualname__:
+        logger.warning(
+            'Cannot treat a function defined as a local function: "%s"  (use 
@functools.wraps)',
+            name)
+        return
+
     if parameters:
         if what in ('class', 'exception'):
             del parameters[0]
@@ -172,7 +175,7 @@
                 class_name = obj.__qualname__.split('.')[-2]
                 method_name = "_{c}{m}".format(c=class_name, m=method_name)
 
-            method_object = outer.__dict__[method_name]
+            method_object = outer.__dict__[method_name] if outer else obj
             if not isinstance(method_object, (classmethod, staticmethod)):
                 del parameters[0]
 
@@ -183,6 +186,111 @@
     return signature.format_args().replace('\\', '\\\\'), None
 
 
+def get_all_type_hints(obj, name):
+    rv = {}
+
+    try:
+        rv = get_type_hints(obj)
+    except (AttributeError, TypeError):
+        # Introspecting a slot wrapper will raise TypeError
+        pass
+    except NameError as exc:
+        logger.warning('Cannot resolve forward reference in type annotations 
of "%s": %s',
+                       name, exc)
+        rv = obj.__annotations__
+
+    if rv:
+        return rv
+
+    rv = backfill_type_hints(obj, name)
+
+    try:
+        obj.__annotations__ = rv
+    except AttributeError:
+        return rv
+
+    try:
+        rv = get_type_hints(obj)
+    except (AttributeError, TypeError):
+        pass
+    except NameError as exc:
+        logger.warning('Cannot resolve forward reference in type annotations 
of "%s": %s',
+                       name, exc)
+        rv = obj.__annotations__
+
+    return rv
+
+
+def backfill_type_hints(obj, name):
+    rv = {}
+
+    try:
+        import typed_ast.ast3 as ast
+    except ImportError:
+        return rv
+
+    def _one_child(module):
+        children = list(ast.iter_child_nodes(module))
+
+        if len(children) != 1:
+            logger.warning(
+                'Did not get exactly one node from AST for "%s", got %s', 
name, len(children))
+            return
+
+        return children[0]
+
+    try:
+        obj_ast = ast.parse(textwrap.dedent(inspect.getsource(obj)))
+    except TypeError:
+        return rv
+
+    obj_ast = _one_child(obj_ast)
+    if obj_ast is None:
+        return rv
+
+    try:
+        type_comment = obj_ast.type_comment
+    except AttributeError:
+        return rv
+
+    if not type_comment:
+        return rv
+
+    try:
+        comment_args_str, comment_returns = type_comment.split(' -> ')
+    except ValueError:
+        logger.warning('Unparseable type hint comment for "%s": Expected to 
contain ` -> `', name)
+        return rv
+
+    if comment_returns:
+        rv['return'] = comment_returns
+
+    if comment_args_str not in ('()', '(...)'):
+        logger.warning(
+            'Only supporting `type: (...) -> rv`-style type hint comments, '
+            'skipping types for "%s"', name
+        )
+        return rv
+
+    try:
+        args = list(ast.iter_child_nodes(obj_ast.args))
+    except AttributeError:
+        logger.warning('No args found on "%s"', name)
+        return rv
+
+    for arg in args:
+        comment = getattr(arg, 'type_comment', None)
+        if not comment:
+            continue
+
+        if not hasattr(arg, 'arg'):
+            continue
+
+        rv[arg.arg] = comment
+
+    return rv
+
+
 def process_docstring(app, what, name, obj, options, lines):
     if isinstance(obj, property):
         obj = obj.fget
@@ -191,22 +299,15 @@
         if what in ('class', 'exception'):
             obj = getattr(obj, '__init__')
 
-        obj = unwrap(obj)
-        try:
-            type_hints = get_type_hints(obj)
-        except (AttributeError, TypeError):
-            # Introspecting a slot wrapper will raise TypeError
-            return
-        except NameError as exc:
-            logger.warning('Cannot resolve forward reference in type 
annotations of "%s": %s',
-                           name, exc)
-            type_hints = obj.__annotations__
+        obj = inspect.unwrap(obj)
+        type_hints = get_all_type_hints(obj, name)
 
         for argname, annotation in type_hints.items():
             if argname.endswith('_'):
                 argname = '{}\\_'.format(argname[:-1])
 
-            formatted_annotation = format_annotation(annotation)
+            formatted_annotation = format_annotation(
+                annotation, 
fully_qualified=app.config.typehints_fully_qualified)
 
             if argname == 'return':
                 if what in ('class', 'exception'):
@@ -244,6 +345,7 @@
 
 def setup(app):
     app.add_config_value('set_type_checking_flag', False, 'html')
+    app.add_config_value('typehints_fully_qualified', False, '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.6.0/tests/roots/test-dummy/dummy_module.py 
new/sphinx-autodoc-typehints-1.7.0/tests/roots/test-dummy/dummy_module.py
--- old/sphinx-autodoc-typehints-1.6.0/tests/roots/test-dummy/dummy_module.py   
2018-12-01 22:52:14.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/tests/roots/test-dummy/dummy_module.py   
2019-07-24 17:20:30.000000000 +0200
@@ -1,5 +1,19 @@
 import typing
 
+try:
+    from dataclasses import dataclass
+except ImportError:
+    def dataclass(cls):
+        return cls
+
+
+def get_local_function():
+    def wrapper(self) -> str:
+        """
+        Wrapper
+        """
+    return wrapper
+
 
 class Class:
     """
@@ -88,6 +102,8 @@
             :param x: foo
             """
 
+    locally_defined_callable_field = get_local_function()
+
 
 class DummyException(Exception):
     """
@@ -126,3 +142,49 @@
 
     :param x: foo
     """
+
+
+
+def function_with_typehint_comment(
+    x,  # type: int
+    y   # type: str
+):
+    # type: (...) -> None
+    """
+    Function docstring.
+
+    :param x: foo
+    :param y: bar
+    """
+
+
+class ClassWithTypehints(object):
+    """
+    Class docstring.
+
+    :param x: foo
+    """
+
+    def __init__(
+        self,
+        x  # type: int
+    ):
+        # type: (...) -> None
+        pass
+
+    def foo(
+        self,
+        x  # type: str
+    ):
+        # type: (...) -> int
+        """
+        Method docstring.
+
+        :param x: foo
+        """
+        return 42
+
+
+@dataclass
+class DataClass:
+    """Class docstring."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.6.0/tests/roots/test-dummy/index.rst 
new/sphinx-autodoc-typehints-1.7.0/tests/roots/test-dummy/index.rst
--- old/sphinx-autodoc-typehints-1.6.0/tests/roots/test-dummy/index.rst 
2018-12-01 22:51:51.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/tests/roots/test-dummy/index.rst 
2019-07-24 17:20:30.000000000 +0200
@@ -16,3 +16,12 @@
 .. autofunction:: dummy_module.function_with_escaped_default
 
 .. autofunction:: dummy_module.function_with_unresolvable_annotation
+
+.. autofunction:: dummy_module.function_with_typehint_comment
+
+.. autoclass:: dummy_module.ClassWithTypehints
+   :members:
+
+.. autoclass:: dummy_module.DataClass
+    :undoc-members:
+    :special-members: __init__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-autodoc-typehints-1.6.0/tests/test_sphinx_autodoc_typehints.py 
new/sphinx-autodoc-typehints-1.7.0/tests/test_sphinx_autodoc_typehints.py
--- old/sphinx-autodoc-typehints-1.6.0/tests/test_sphinx_autodoc_typehints.py   
2018-12-23 13:11:06.000000000 +0100
+++ new/sphinx-autodoc-typehints-1.7.0/tests/test_sphinx_autodoc_typehints.py   
2019-07-24 17:20:30.000000000 +0200
@@ -99,6 +99,60 @@
     assert result == expected_result
 
 
[email protected]('annotation, expected_result', [
+    (str,                           ':py:class:`str`'),
+    (int,                           ':py:class:`int`'),
+    (type(None),                    '``None``'),
+    (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:class:`typing.Tuple`'),
+    (Tuple[str, bool],              
':py:class:`typing.Tuple`\\[:py:class:`str`, '
+                                    ':py:class:`bool`]'),
+    (Tuple[int, int, int],          
':py:class:`typing.Tuple`\\[:py:class:`int`, '
+                                    ':py:class:`int`, :py:class:`int`]'),
+    (Tuple[str, ...],               
':py:class:`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`)')
+])
+def test_format_annotation_fully_qualified(annotation, expected_result):
+    result = format_annotation(annotation, fully_qualified=True)
+    assert result == expected_result
+
+
 @pytest.mark.parametrize('type_param, expected_result', [
     (None, ':py:class:`~typing.Type`\\[\\+CT'),
     (A, ':py:class:`~typing.Type`\\[:py:class:`~%s.A`]' % __name__)
@@ -134,7 +188,7 @@
     text_path = pathlib.Path(app.srcdir) / '_build' / 'text' / 'index.txt'
     with text_path.open('r') as f:
         text_contents = f.read().replace('–', '--')
-        assert text_contents == textwrap.dedent('''\
+        expected_contents = textwrap.dedent('''\
         Dummy Module
         ************
 
@@ -231,7 +285,7 @@
               Return type:
                  "str"
 
-           a_property
+           property a_property
 
               Property docstring
 
@@ -252,6 +306,13 @@
               Return type:
                  "str"
 
+           locally_defined_callable_field() -> str
+
+              Wrapper
+
+              Return type:
+                 "str"
+
         exception dummy_module.DummyException(message)
 
            Exception docstring
@@ -289,4 +350,51 @@
 
            Parameters:
               **x** (*a.b.c*) – foo
+
+        dummy_module.function_with_typehint_comment(x, y)
+
+           Function docstring.
+
+           Parameters:
+              * **x** ("int") – foo
+
+              * **y** ("str") – bar
+
+           Return type:
+              "None"
+
+        class dummy_module.ClassWithTypehints(x)
+
+           Class docstring.
+
+           Parameters:
+              **x** ("int") -- foo
+
+           foo(x)
+
+              Method docstring.
+
+              Parameters:
+                 **x** ("str") -- foo
+
+              Return type:
+                 "int"
+
+        class dummy_module.DataClass
+
+           Class docstring.
+
+           __init__()
         ''').replace('–', '--')
+
+        if sys.version_info < (3, 6):
+            expected_contents += '''
+      Initialize self.  See help(type(self)) for accurate signature.
+'''
+        else:
+            expected_contents += '''
+      Return type:
+         "None"
+'''
+
+        assert text_contents == expected_contents
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-autodoc-typehints-1.6.0/tox.ini 
new/sphinx-autodoc-typehints-1.7.0/tox.ini
--- old/sphinx-autodoc-typehints-1.6.0/tox.ini  2018-03-18 21:26:23.000000000 
+0100
+++ new/sphinx-autodoc-typehints-1.7.0/tox.ini  2019-07-24 17:20:30.000000000 
+0200
@@ -1,6 +1,6 @@
 [tox]
 minversion = 2.5.0
-envlist = py34, py35, py36, py37, flake8
+envlist = py35, py36, py37, py38, flake8
 skip_missing_interpreters = true
 
 [testenv]


Reply via email to