From 7257b24140ac1b39fb8cfd4610134ec79575a396 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 19 Sep 2025 15:54:06 +0300 Subject: [PATCH] gh-139076: Fix regression in pydoc not showing extension functions (GH-139077) Fix a bug in the pydoc module that was hiding functions in a Python module if they were implemented in an extension module and the module did not have __all__. --- Lib/pydoc.py | 2 ++ Lib/test/test_pydoc/pydocfodder.py | 3 +++ Lib/test/test_pydoc/test_pydoc.py | 13 +++++++++++++ .../2025-09-17-21-54-53.gh-issue-139076.2eX9lG.rst | 3 +++ 4 files changed, 21 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-09-17-21-54-53.gh-issue-139076.2eX9lG.rst diff --git a/Lib/pydoc.py b/Lib/pydoc.py index d508fb70ea42..989fbd517d8d 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -884,6 +884,7 @@ class HTMLDoc(Doc): for key, value in inspect.getmembers(object, inspect.isroutine): # if __all__ exists, believe it. Otherwise use a heuristic. if (all is not None + or inspect.isbuiltin(value) or (inspect.getmodule(value) or object) is object): if visiblename(key, all, object): funcs.append((key, value)) @@ -1328,6 +1329,7 @@ location listed above. for key, value in inspect.getmembers(object, inspect.isroutine): # if __all__ exists, believe it. Otherwise use a heuristic. if (all is not None + or inspect.isbuiltin(value) or (inspect.getmodule(value) or object) is object): if visiblename(key, all, object): funcs.append((key, value)) diff --git a/Lib/test/test_pydoc/pydocfodder.py b/Lib/test/test_pydoc/pydocfodder.py index 3cc2d5bd57fe..412aa3743e43 100644 --- a/Lib/test/test_pydoc/pydocfodder.py +++ b/Lib/test/test_pydoc/pydocfodder.py @@ -87,6 +87,8 @@ class B(A): object_repr = object.__repr__ get = {}.get # same name dict_get = {}.get + from math import sin + B.B_classmethod_ref = B.B_classmethod @@ -186,3 +188,4 @@ __repr__ = object.__repr__ # same name object_repr = object.__repr__ get = {}.get # same name dict_get = {}.get +from math import sin # noqa: F401 diff --git a/Lib/test/test_pydoc/test_pydoc.py b/Lib/test/test_pydoc/test_pydoc.py index 3b50ead00bdd..40cdee5c6c3d 100644 --- a/Lib/test/test_pydoc/test_pydoc.py +++ b/Lib/test/test_pydoc/test_pydoc.py @@ -1951,9 +1951,11 @@ class PydocFodderTest(unittest.TestCase): if not support.MISSING_C_DOCSTRINGS: self.assertIn(' | get(key, default=None, /) method of builtins.dict instance', lines) self.assertIn(' | dict_get = get(key, default=None, /) method of builtins.dict instance', lines) + self.assertIn(' | sin(x, /)', lines) else: self.assertIn(' | get(...) method of builtins.dict instance', lines) self.assertIn(' | dict_get = get(...) method of builtins.dict instance', lines) + self.assertIn(' | sin(...)', lines) lines = self.getsection(result, f' | Class methods {where}:', ' | ' + '-'*70) self.assertIn(' | B_classmethod(x)', lines) @@ -2039,6 +2041,11 @@ class PydocFodderTest(unittest.TestCase): self.assertIn(' __repr__(...) unbound builtins.object method', lines) self.assertIn(' object_repr = __repr__(...) unbound builtins.object method', lines) + # builtin functions + if not support.MISSING_C_DOCSTRINGS: + self.assertIn(' sin(x, /)', lines) + else: + self.assertIn(' sin(...)', lines) def test_html_doc_routines_in_module(self): doc = pydoc.HTMLDoc() @@ -2079,6 +2086,12 @@ class PydocFodderTest(unittest.TestCase): self.assertIn(' __repr__(...) unbound builtins.object method', lines) self.assertIn(' object_repr = __repr__(...) unbound builtins.object method', lines) + # builtin functions + if not support.MISSING_C_DOCSTRINGS: + self.assertIn(' sin(x, /)', lines) + else: + self.assertIn(' sin(...)', lines) + @unittest.skipIf( is_wasm32, diff --git a/Misc/NEWS.d/next/Library/2025-09-17-21-54-53.gh-issue-139076.2eX9lG.rst b/Misc/NEWS.d/next/Library/2025-09-17-21-54-53.gh-issue-139076.2eX9lG.rst new file mode 100644 index 000000000000..5e0ae6ed73ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-17-21-54-53.gh-issue-139076.2eX9lG.rst @@ -0,0 +1,3 @@ +Fix a bug in the :mod:`pydoc` module that was hiding functions in a Python +module if they were implemented in an extension module and the module did +not have ``__all__``. -- 2.47.3