Skip to content

gh-97959: [pydoc] now help() does not show extra notes for classmethods #98120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Lib/pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,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 @@ -1048,7 +1056,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 @@ -1471,7 +1480,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,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 @@ -191,7 +194,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 @@ -1322,10 +1327,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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Now ``help()`` does not show ``from builtins.type`` note for ``classmethod``
definitions.