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]