Skip to content

Commit e888a44

Browse files
authored
Merge pull request #9026 from tk0miya/5603_autodoc_canonical
Close #5603: autodoc: Allow to refer to a python object using canonical name
2 parents cd75f8f + acf66bc commit e888a44

File tree

5 files changed

+67
-0
lines changed

5 files changed

+67
-0
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ Features added
6666

6767
* #8924: autodoc: Support ``bound`` argument for TypeVar
6868
* #7383: autodoc: Support typehints for properties
69+
* #5603: autodoc: Allow to refer to a python class using its canonical name
70+
when the class has two different names; a canonical name and an alias name
6971
* #7549: autosummary: Enable :confval:`autosummary_generate` by default
7072
* #4826: py domain: Add ``:canonical:`` option to python directives to describe
7173
the location where the object is defined

sphinx/ext/autodoc/__init__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,20 @@ def get_overloaded_signatures(self) -> List[Signature]:
15901590

15911591
return []
15921592

1593+
def get_canonical_fullname(self) -> Optional[str]:
1594+
__modname__ = safe_getattr(self.object, '__module__', self.modname)
1595+
__qualname__ = safe_getattr(self.object, '__qualname__', None)
1596+
if __qualname__ is None:
1597+
__qualname__ = safe_getattr(self.object, '__name__', None)
1598+
if __qualname__ and '<locals>' in __qualname__:
1599+
# No valid qualname found if the object is defined as locals
1600+
__qualname__ = None
1601+
1602+
if __modname__ and __qualname__:
1603+
return '.'.join([__modname__, __qualname__])
1604+
else:
1605+
return None
1606+
15931607
def add_directive_header(self, sig: str) -> None:
15941608
sourcename = self.get_sourcename()
15951609

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

1617+
canonical_fullname = self.get_canonical_fullname()
1618+
if not self.doc_as_attr and canonical_fullname and self.fullname != canonical_fullname:
1619+
self.add_line(' :canonical: %s' % canonical_fullname, sourcename)
1620+
16031621
# add inheritance info, if wanted
16041622
if not self.doc_as_attr and self.options.show_inheritance:
16051623
sourcename = self.get_sourcename()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from target.canonical.original import Bar, Foo
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Foo:
2+
"""docstring"""
3+
4+
def meth(self):
5+
"""docstring"""
6+
7+
8+
def bar():
9+
class Bar:
10+
"""docstring"""
11+
12+
return Bar
13+
14+
15+
Bar = bar()

tests/test_ext_autodoc.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,3 +2474,34 @@ def test_hide_value(app):
24742474
' :meta hide-value:',
24752475
'',
24762476
]
2477+
2478+
2479+
@pytest.mark.sphinx('html', testroot='ext-autodoc')
2480+
def test_canonical(app):
2481+
options = {'members': None,
2482+
'imported-members': None}
2483+
actual = do_autodoc(app, 'module', 'target.canonical', options)
2484+
assert list(actual) == [
2485+
'',
2486+
'.. py:module:: target.canonical',
2487+
'',
2488+
'',
2489+
'.. py:class:: Bar()',
2490+
' :module: target.canonical',
2491+
'',
2492+
' docstring',
2493+
'',
2494+
'',
2495+
'.. py:class:: Foo()',
2496+
' :module: target.canonical',
2497+
' :canonical: target.canonical.original.Foo',
2498+
'',
2499+
' docstring',
2500+
'',
2501+
'',
2502+
' .. py:method:: Foo.meth()',
2503+
' :module: target.canonical',
2504+
'',
2505+
' docstring',
2506+
'',
2507+
]

0 commit comments

Comments
 (0)