Skip to content

Commit

Permalink
Merge pull request #9026 from tk0miya/5603_autodoc_canonical
Browse files Browse the repository at this point in the history
Close #5603: autodoc: Allow to refer to a python object using canonical name
  • Loading branch information
tk0miya committed Mar 27, 2021
2 parents cd75f8f + acf66bc commit e888a44
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -66,6 +66,8 @@ Features added

* #8924: autodoc: Support ``bound`` argument for TypeVar
* #7383: autodoc: Support typehints for properties
* #5603: autodoc: Allow to refer to a python class using its canonical name
when the class has two different names; a canonical name and an alias name
* #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
Expand Down
18 changes: 18 additions & 0 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -1590,6 +1590,20 @@ def get_overloaded_signatures(self) -> List[Signature]:

return []

def get_canonical_fullname(self) -> Optional[str]:
__modname__ = safe_getattr(self.object, '__module__', self.modname)
__qualname__ = safe_getattr(self.object, '__qualname__', None)
if __qualname__ is None:
__qualname__ = safe_getattr(self.object, '__name__', None)
if __qualname__ and '<locals>' in __qualname__:
# No valid qualname found if the object is defined as locals
__qualname__ = None

if __modname__ and __qualname__:
return '.'.join([__modname__, __qualname__])
else:
return None

def add_directive_header(self, sig: str) -> None:
sourcename = self.get_sourcename()

Expand All @@ -1600,6 +1614,10 @@ def add_directive_header(self, sig: str) -> None:
if self.analyzer and '.'.join(self.objpath) in self.analyzer.finals:
self.add_line(' :final:', sourcename)

canonical_fullname = self.get_canonical_fullname()
if not self.doc_as_attr and canonical_fullname and self.fullname != canonical_fullname:
self.add_line(' :canonical: %s' % canonical_fullname, sourcename)

# add inheritance info, if wanted
if not self.doc_as_attr and self.options.show_inheritance:
sourcename = self.get_sourcename()
Expand Down
1 change: 1 addition & 0 deletions tests/roots/test-ext-autodoc/target/canonical/__init__.py
@@ -0,0 +1 @@
from target.canonical.original import Bar, Foo
15 changes: 15 additions & 0 deletions tests/roots/test-ext-autodoc/target/canonical/original.py
@@ -0,0 +1,15 @@
class Foo:
"""docstring"""

def meth(self):
"""docstring"""


def bar():
class Bar:
"""docstring"""

return Bar


Bar = bar()
31 changes: 31 additions & 0 deletions tests/test_ext_autodoc.py
Expand Up @@ -2474,3 +2474,34 @@ def test_hide_value(app):
' :meta hide-value:',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_canonical(app):
options = {'members': None,
'imported-members': None}
actual = do_autodoc(app, 'module', 'target.canonical', options)
assert list(actual) == [
'',
'.. py:module:: target.canonical',
'',
'',
'.. py:class:: Bar()',
' :module: target.canonical',
'',
' docstring',
'',
'',
'.. py:class:: Foo()',
' :module: target.canonical',
' :canonical: target.canonical.original.Foo',
'',
' docstring',
'',
'',
' .. py:method:: Foo.meth()',
' :module: target.canonical',
'',
' docstring',
'',
]

0 comments on commit e888a44

Please sign in to comment.