summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2021-03-15 13:04:01 +0900
committerGitHub <noreply@github.com>2021-03-15 13:04:01 +0900
commitf8e7ecf10bad8196e29da5c32ba3a20136063ced (patch)
tree1f5258e294a675ec6f36489e34a1158f141ac70e
parente03d0aeba0eccad6ef1ea5ef37f517bf3229f5d7 (diff)
parent75f5122996ea7eb340d31bb3006efde7d2a351f6 (diff)
downloadsphinx-git-f8e7ecf10bad8196e29da5c32ba3a20136063ced.tar.gz
Merge pull request #8983 from tk0miya/7523_autodoc_property
Fix #7383: autodoc: Support typehints for properties
-rw-r--r--CHANGES1
-rw-r--r--sphinx/ext/autodoc/__init__.py16
-rw-r--r--tests/roots/test-ext-autodoc/target/properties.py6
-rw-r--r--tests/test_ext_autodoc.py9
-rw-r--r--tests/test_ext_autodoc_autoclass.py21
-rw-r--r--tests/test_ext_autodoc_autoproperty.py28
-rw-r--r--tests/test_ext_autodoc_configs.py12
7 files changed, 77 insertions, 16 deletions
diff --git a/CHANGES b/CHANGES
index 4ce709fac..f449442bb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -63,6 +63,7 @@ Features added
--------------
* #8924: autodoc: Support ``bound`` argument for TypeVar
+* #7383: autodoc: Support typehints for properties
* #7549: autosummary: Enable :confval:`autosummary_generate` by default
* #4826: py domain: Add ``:canonical:`` option to python directives to describe
the location where the object is defined
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index 2abe41234..2410ccec3 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -2528,7 +2528,6 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): #
Specialized Documenter subclass for properties.
"""
objtype = 'property'
- directivetype = 'method'
member_order = 60
# before AttributeDocumenter
@@ -2551,7 +2550,20 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): #
sourcename = self.get_sourcename()
if inspect.isabstractmethod(self.object):
self.add_line(' :abstractmethod:', sourcename)
- self.add_line(' :property:', sourcename)
+
+ if safe_getattr(self.object, 'fget', None):
+ try:
+ signature = inspect.signature(self.object.fget,
+ type_aliases=self.config.autodoc_type_aliases)
+ if signature.return_annotation is not Parameter.empty:
+ objrepr = stringify_typehint(signature.return_annotation)
+ self.add_line(' :type: ' + objrepr, sourcename)
+ except TypeError as exc:
+ logger.warning(__("Failed to get a function signature for %s: %s"),
+ self.fullname, exc)
+ return None
+ except ValueError:
+ raise
class NewTypeAttributeDocumenter(AttributeDocumenter):
diff --git a/tests/roots/test-ext-autodoc/target/properties.py b/tests/roots/test-ext-autodoc/target/properties.py
new file mode 100644
index 000000000..409fc2b5d
--- /dev/null
+++ b/tests/roots/test-ext-autodoc/target/properties.py
@@ -0,0 +1,6 @@
+class Foo:
+ """docstring"""
+
+ @property
+ def prop(self) -> int:
+ """docstring"""
diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py
index d9986e9ca..7c6f4e0d6 100644
--- a/tests/test_ext_autodoc.py
+++ b/tests/test_ext_autodoc.py
@@ -1033,9 +1033,8 @@ def test_autodoc_descriptor(app):
' Descriptor instance docstring.',
'',
'',
- ' .. py:method:: Class.prop',
+ ' .. py:property:: Class.prop',
' :module: target.descriptor',
- ' :property:',
'',
' Property.',
''
@@ -1055,9 +1054,8 @@ def test_autodoc_cached_property(app):
' :module: target.cached_property',
'',
'',
- ' .. py:method:: Foo.prop',
+ ' .. py:property:: Foo.prop',
' :module: target.cached_property',
- ' :property:',
'',
]
@@ -1516,10 +1514,9 @@ def test_abstractmethods(app):
' :module: target.abstractmethods',
'',
'',
- ' .. py:method:: Base.prop',
+ ' .. py:property:: Base.prop',
' :module: target.abstractmethods',
' :abstractmethod:',
- ' :property:',
'',
'',
' .. py:method:: Base.staticmeth()',
diff --git a/tests/test_ext_autodoc_autoclass.py b/tests/test_ext_autodoc_autoclass.py
index 538b36881..940263387 100644
--- a/tests/test_ext_autodoc_autoclass.py
+++ b/tests/test_ext_autodoc_autoclass.py
@@ -200,6 +200,27 @@ def test_decorators(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_properties(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.properties.Foo', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: Foo()',
+ ' :module: target.properties',
+ '',
+ ' docstring',
+ '',
+ '',
+ ' .. py:property:: Foo.prop',
+ ' :module: target.properties',
+ ' :type: int',
+ '',
+ ' docstring',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_slots_attribute(app):
options = {"members": None}
actual = do_autodoc(app, 'class', 'target.slots.Bar', options)
diff --git a/tests/test_ext_autodoc_autoproperty.py b/tests/test_ext_autodoc_autoproperty.py
new file mode 100644
index 000000000..ee25aa8b7
--- /dev/null
+++ b/tests/test_ext_autodoc_autoproperty.py
@@ -0,0 +1,28 @@
+"""
+ test_ext_autodoc_autoproperty
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Test the autodoc extension. This tests mainly the Documenters; the auto
+ directives are tested in a test source file translated by test_build.
+
+ :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import pytest
+
+from .test_ext_autodoc import do_autodoc
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_properties(app):
+ actual = do_autodoc(app, 'property', 'target.properties.Foo.prop')
+ assert list(actual) == [
+ '',
+ '.. py:property:: Foo.prop',
+ ' :module: target.properties',
+ ' :type: int',
+ '',
+ ' docstring',
+ '',
+ ]
diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py
index 06bf39c24..cc34143ca 100644
--- a/tests/test_ext_autodoc_configs.py
+++ b/tests/test_ext_autodoc_configs.py
@@ -261,16 +261,14 @@ def test_autodoc_docstring_signature(app):
' indented line',
'',
'',
- ' .. py:method:: DocstringSig.prop1',
+ ' .. py:property:: DocstringSig.prop1',
' :module: target',
- ' :property:',
'',
' First line of docstring',
'',
'',
- ' .. py:method:: DocstringSig.prop2',
+ ' .. py:property:: DocstringSig.prop2',
' :module: target',
- ' :property:',
'',
' First line of docstring',
' Second line of docstring',
@@ -305,17 +303,15 @@ def test_autodoc_docstring_signature(app):
' indented line',
'',
'',
- ' .. py:method:: DocstringSig.prop1',
+ ' .. py:property:: DocstringSig.prop1',
' :module: target',
- ' :property:',
'',
' DocstringSig.prop1(self)',
' First line of docstring',
'',
'',
- ' .. py:method:: DocstringSig.prop2',
+ ' .. py:property:: DocstringSig.prop2',
' :module: target',
- ' :property:',
'',
' First line of docstring',
' Second line of docstring',