bpo-34966: Improve support of method aliases in pydoc. (GH-9823)

Pydoc now does not duplicate docstrings for aliases of inherited methods.
This commit is contained in:
Serhiy Storchaka 2018-11-08 08:48:11 +02:00 committed by GitHub
parent 6843ffe453
commit a44d34e179
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 4 deletions

View File

@ -958,8 +958,7 @@ class HTMLDoc(Doc):
if name == realname: if name == realname:
title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname) title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
else: else:
if (cl and realname in cl.__dict__ and if cl and inspect.getattr_static(cl, realname, []) is object:
cl.__dict__[realname] is object):
reallink = '<a href="#%s">%s</a>' % ( reallink = '<a href="#%s">%s</a>' % (
cl.__name__ + '-' + realname, realname) cl.__name__ + '-' + realname, realname)
skipdocs = 1 skipdocs = 1
@ -1393,8 +1392,7 @@ location listed above.
if name == realname: if name == realname:
title = self.bold(realname) title = self.bold(realname)
else: else:
if (cl and realname in cl.__dict__ and if cl and inspect.getattr_static(cl, realname, []) is object:
cl.__dict__[realname] is object):
skipdocs = 1 skipdocs = 1
title = self.bold(name) + ' = ' + realname title = self.bold(name) + ' = ' + realname
argspec = None argspec = None

View File

@ -417,6 +417,7 @@ class PydocBaseTest(unittest.TestCase):
class PydocDocTest(unittest.TestCase): class PydocDocTest(unittest.TestCase):
maxDiff = None
@unittest.skipIf(sys.flags.optimize >= 2, @unittest.skipIf(sys.flags.optimize >= 2,
"Docstrings are omitted with -O2 and above") "Docstrings are omitted with -O2 and above")
@ -766,6 +767,104 @@ class PydocDocTest(unittest.TestCase):
methods = pydoc.allmethods(TestClass) methods = pydoc.allmethods(TestClass)
self.assertDictEqual(methods, expected) self.assertDictEqual(methods, expected)
def test_method_aliases(self):
class A:
def tkraise(self, aboveThis=None):
"""Raise this widget in the stacking order."""
lift = tkraise
def a_size(self):
"""Return size"""
class B(A):
def itemconfigure(self, tagOrId, cnf=None, **kw):
"""Configure resources of an item TAGORID."""
itemconfig = itemconfigure
b_size = A.a_size
doc = pydoc.render_doc(B)
# clean up the extra text formatting that pydoc performs
doc = re.sub('\b.', '', doc)
self.assertEqual(doc, '''\
Python Library Documentation: class B in module %s
class B(A)
| Method resolution order:
| B
| A
| builtins.object
|\x20\x20
| Methods defined here:
|\x20\x20
| b_size = a_size(self)
|\x20\x20
| itemconfig = itemconfigure(self, tagOrId, cnf=None, **kw)
|\x20\x20
| itemconfigure(self, tagOrId, cnf=None, **kw)
| Configure resources of an item TAGORID.
|\x20\x20
| ----------------------------------------------------------------------
| Methods inherited from A:
|\x20\x20
| a_size(self)
| Return size
|\x20\x20
| lift = tkraise(self, aboveThis=None)
|\x20\x20
| tkraise(self, aboveThis=None)
| Raise this widget in the stacking order.
|\x20\x20
| ----------------------------------------------------------------------
| Data descriptors inherited from A:
|\x20\x20
| __dict__
| dictionary for instance variables (if defined)
|\x20\x20
| __weakref__
| list of weak references to the object (if defined)
''' % __name__)
doc = pydoc.render_doc(B, renderer=pydoc.HTMLDoc())
self.assertEqual(doc, '''\
Python Library Documentation: class B in module %s
<p>
<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="B">class <strong>B</strong></a>(A)</font></td></tr>
\x20\x20\x20\x20
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%%"><dl><dt>Method resolution order:</dt>
<dd>B</dd>
<dd>A</dd>
<dd><a href="builtins.html#object">builtins.object</a></dd>
</dl>
<hr>
Methods defined here:<br>
<dl><dt><a name="B-b_size"><strong>b_size</strong></a> = <a href="#B-a_size">a_size</a>(self)</dt></dl>
<dl><dt><a name="B-itemconfig"><strong>itemconfig</strong></a> = <a href="#B-itemconfigure">itemconfigure</a>(self, tagOrId, cnf=None, **kw)</dt></dl>
<dl><dt><a name="B-itemconfigure"><strong>itemconfigure</strong></a>(self, tagOrId, cnf=None, **kw)</dt><dd><tt>Configure&nbsp;resources&nbsp;of&nbsp;an&nbsp;item&nbsp;TAGORID.</tt></dd></dl>
<hr>
Methods inherited from A:<br>
<dl><dt><a name="B-a_size"><strong>a_size</strong></a>(self)</dt><dd><tt>Return&nbsp;size</tt></dd></dl>
<dl><dt><a name="B-lift"><strong>lift</strong></a> = <a href="#B-tkraise">tkraise</a>(self, aboveThis=None)</dt></dl>
<dl><dt><a name="B-tkraise"><strong>tkraise</strong></a>(self, aboveThis=None)</dt><dd><tt>Raise&nbsp;this&nbsp;widget&nbsp;in&nbsp;the&nbsp;stacking&nbsp;order.</tt></dd></dl>
<hr>
Data descriptors inherited from A:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table>\
''' % __name__)
class PydocImportTest(PydocBaseTest): class PydocImportTest(PydocBaseTest):

View File

@ -0,0 +1,3 @@
:mod:`pydoc` now supports aliases not only to methods defined in
the end class, but also to inherited methods. The docstring is not
duplicated for aliases.