Skip to content

Commit

Permalink
pythongh-97959: [pydoc] now help() does not show extra notes for `c…
Browse files Browse the repository at this point in the history
…lassmethod`s
  • Loading branch information
sobolevn committed Oct 9, 2022
1 parent 2d2e01a commit 609c795
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
14 changes: 12 additions & 2 deletions Lib/pydoc.py
Expand Up @@ -243,6 +243,14 @@ def _is_bound_method(fn):
return not (inspect.ismodule(self) or (self is None))
return False

def _is_bound_classmethod(method):
"""Returns True for bound classmethods."""
return (
inspect.isclass(method.__self__) and
(getattr(getattr(method.__self__, method.__name__, None), '__func__', None)
is method.__func__)
)


def allmethods(cl):
methods = {}
Expand Down Expand Up @@ -1032,7 +1040,8 @@ def docroutine(self, object, name=None, mod=None,
if _is_bound_method(object):
imclass = object.__self__.__class__
if cl:
if imclass is not cl:
if imclass is not cl and not _is_bound_classmethod(object):
# We ignore `from builtins.type` note for classmethods.
note = ' from ' + self.classlink(imclass, mod)
else:
if object.__self__ is not None:
Expand Down Expand Up @@ -1465,7 +1474,8 @@ def docroutine(self, object, name=None, mod=None, cl=None):
if _is_bound_method(object):
imclass = object.__self__.__class__
if cl:
if imclass is not cl:
if imclass is not cl and not _is_bound_classmethod(object):
# We ignore `from builtins.type` note for classmethods.
note = ' from ' + classname(imclass, mod)
else:
if object.__self__ is not None:
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/pydoc_mod.py
Expand Up @@ -31,6 +31,9 @@ def is_it_true(self):
return self.get_answer()
def __class_getitem__(self, item):
return types.GenericAlias(self, item)
@classmethod
def regular(cls, arg):
"""Doc for class method."""

def doc_func():
"""
Expand Down
39 changes: 36 additions & 3 deletions Lib/test/test_pydoc.py
Expand Up @@ -98,7 +98,10 @@ class C(builtins.object)
| ----------------------------------------------------------------------
| Class methods defined here:
|
| __class_getitem__(item) from builtins.type
| __class_getitem__(item)
|
| regular(arg)
| Doc for class method.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
Expand Down Expand Up @@ -188,7 +191,9 @@ class C(builtins.object)
Return self.get_answer()
say_no(self)
Class methods defined here:
__class_getitem__(item) from builtins.type
__class_getitem__(item)
regular(arg)
Doc for class method.
Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
Expand Down Expand Up @@ -1202,10 +1207,38 @@ def cm(cls, x):
self.assertIn("""
| Class methods defined here:
|
| cm(x) from builtins.type
| cm(x)
| A class method
""", pydoc.plain(pydoc.render_doc(X)))

@requires_docstrings
def test_classmethod_builtins(self):
self.assertIn("""
| Class methods defined here:
|
| from_bytes = <built-in method from_bytes of type object>
| Return the integer represented by the given array of bytes.
|
""", pydoc.plain(pydoc.render_doc(int)))

@requires_docstrings
def test_types_method_type(self):
from types import MethodType

def some(*args, **kwargs):
"""Doc1."""

class X:
name = MethodType(some, 1)

self.assertIn("""
| Methods defined here:
|
| name = some(*args, **kwargs) from builtins.int
| Doc1.
|
""", pydoc.plain(pydoc.render_doc(X)))

@requires_docstrings
def test_getset_descriptor(self):
# Currently these attributes are implemented as getset descriptors
Expand Down
@@ -0,0 +1,2 @@
Now ``help()`` does not show ``from builtins.type`` note for ``classmethod``
definitions.

0 comments on commit 609c795

Please sign in to comment.