Fix #6785: py domain: :py:attr: is able to refer properties again

This commit is contained in:
Takeshi KOMIYA 2020-01-25 13:55:27 +09:00
parent f8fc6075ba
commit 33fcd393ab
4 changed files with 41 additions and 11 deletions

View File

@ -41,6 +41,7 @@ Features added
is required) is required)
* SphinxTranslator now calls visitor/departure method for super node class if * SphinxTranslator now calls visitor/departure method for super node class if
visitor/departure method for original node class not found visitor/departure method for original node class not found
* #6785: py domain: ``:py:attr:`` is able to refer properties again
Bugs fixed Bugs fixed
---------- ----------

View File

@ -1011,6 +1011,11 @@ class PythonDomain(Domain):
searchmode = 1 if node.hasattr('refspecific') else 0 searchmode = 1 if node.hasattr('refspecific') else 0
matches = self.find_obj(env, modname, clsname, target, matches = self.find_obj(env, modname, clsname, target,
type, searchmode) type, searchmode)
if not matches and type == 'attr':
# fallback to meth (for property)
matches = self.find_obj(env, modname, clsname, target, 'meth', searchmode)
if not matches: if not matches:
return None return None
elif len(matches) > 1: elif len(matches) > 1:

View File

@ -18,6 +18,12 @@ module
* Link to :py:meth:`module_a.submodule.ModTopLevel.mod_child_1` * Link to :py:meth:`module_a.submodule.ModTopLevel.mod_child_1`
.. py:method:: ModTopLevel.prop
:property:
* Link to :py:attr:`prop attribute <.prop>`
* Link to :py:meth:`prop method <.prop>`
.. py:currentmodule:: None .. py:currentmodule:: None
.. py:class:: ModNoModule .. py:class:: ModNoModule

View File

@ -105,19 +105,22 @@ def test_domain_py_xrefs(app, status, warning):
'mod_child_2', 'meth') 'mod_child_2', 'meth')
assert_refnode(refnodes[4], 'module_a.submodule', 'ModTopLevel', assert_refnode(refnodes[4], 'module_a.submodule', 'ModTopLevel',
'module_a.submodule.ModTopLevel.mod_child_1', 'meth') 'module_a.submodule.ModTopLevel.mod_child_1', 'meth')
assert_refnode(refnodes[5], 'module_b.submodule', None, assert_refnode(refnodes[5], 'module_a.submodule', 'ModTopLevel',
'prop', 'attr')
assert_refnode(refnodes[6], 'module_a.submodule', 'ModTopLevel',
'prop', 'meth')
assert_refnode(refnodes[7], 'module_b.submodule', None,
'ModTopLevel', 'class') 'ModTopLevel', 'class')
assert_refnode(refnodes[6], 'module_b.submodule', 'ModTopLevel', assert_refnode(refnodes[8], 'module_b.submodule', 'ModTopLevel',
'ModNoModule', 'class') 'ModNoModule', 'class')
assert_refnode(refnodes[7], False, False, 'int', 'class') assert_refnode(refnodes[9], False, False, 'int', 'class')
assert_refnode(refnodes[8], False, False, 'tuple', 'class') assert_refnode(refnodes[10], False, False, 'tuple', 'class')
assert_refnode(refnodes[9], False, False, 'str', 'class') assert_refnode(refnodes[11], False, False, 'str', 'class')
assert_refnode(refnodes[10], False, False, 'float', 'class') assert_refnode(refnodes[12], False, False, 'float', 'class')
assert_refnode(refnodes[11], False, False, 'list', 'class') assert_refnode(refnodes[13], False, False, 'list', 'class')
assert_refnode(refnodes[11], False, False, 'list', 'class') assert_refnode(refnodes[14], False, False, 'ModTopLevel', 'class')
assert_refnode(refnodes[12], False, False, 'ModTopLevel', 'class') assert_refnode(refnodes[15], False, False, 'index', 'doc', domain='std')
assert_refnode(refnodes[13], False, False, 'index', 'doc', domain='std') assert len(refnodes) == 16
assert len(refnodes) == 14
doctree = app.env.get_doctree('module_option') doctree = app.env.get_doctree('module_option')
refnodes = list(doctree.traverse(addnodes.pending_xref)) refnodes = list(doctree.traverse(addnodes.pending_xref))
@ -161,6 +164,21 @@ def test_domain_py_objects(app, status, warning):
assert objects['NestedParentB.child_1'] == ('roles', 'method') assert objects['NestedParentB.child_1'] == ('roles', 'method')
@pytest.mark.sphinx('html', testroot='domain-py')
def test_resolve_xref_for_properties(app, status, warning):
app.builder.build_all()
content = (app.outdir / 'module.html').text()
assert ('Link to <a class="reference internal" href="#module_a.submodule.ModTopLevel.prop"'
' title="module_a.submodule.ModTopLevel.prop">'
'<code class="xref py py-attr docutils literal notranslate"><span class="pre">'
'prop</span> <span class="pre">attribute</span></code></a>' in content)
assert ('Link to <a class="reference internal" href="#module_a.submodule.ModTopLevel.prop"'
' title="module_a.submodule.ModTopLevel.prop">'
'<code class="xref py py-meth docutils literal notranslate"><span class="pre">'
'prop</span> <span class="pre">method</span></code></a>' in content)
@pytest.mark.sphinx('dummy', testroot='domain-py') @pytest.mark.sphinx('dummy', testroot='domain-py')
def test_domain_py_find_obj(app, status, warning): def test_domain_py_find_obj(app, status, warning):