https://github.com/python/cpython/commit/78a50ee10ef73296eba98899d496bff3915ddc41
commit: 78a50ee10ef73296eba98899d496bff3915ddc41
branch: main
author: Stan Ulbrych <[email protected]>
committer: hugovk <[email protected]>
date: 2025-12-14T14:59:05+02:00
summary:
gh-76007: `pydoc`: Catch `DeprecationWarning` for stdlib module `__version__`
attributes (#139997)
files:
A Misc/NEWS.d/next/Library/2025-10-12-12-43-56.gh-issue-76007.PyGM14.rst
M Lib/pydoc.py
M Lib/test/test_pydoc/test_pydoc.py
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index ee4457d9d3a932..c8d4aa7a88325b 100644
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -450,6 +450,7 @@ class Doc:
PYTHONDOCS = os.environ.get("PYTHONDOCS",
"https://docs.python.org/%d.%d/library"
% sys.version_info[:2])
+ STDLIB_DIR = sysconfig.get_path('stdlib')
def document(self, object, name=None, *args):
"""Generate documentation for an object."""
@@ -475,23 +476,12 @@ def fail(self, object, name=None, *args):
docmodule = docclass = docroutine = docother = docproperty = docdata = fail
- def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')):
+ def getdocloc(self, object, basedir=None):
"""Return the location of module docs or None"""
-
- try:
- file = inspect.getabsfile(object)
- except TypeError:
- file = '(built-in)'
-
+ basedir = self.STDLIB_DIR if basedir is None else basedir
docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
- basedir = os.path.normcase(basedir)
- if (isinstance(object, type(os)) and
- (object.__name__ in ('errno', 'exceptions', 'gc',
- 'marshal', 'posix', 'signal', 'sys',
- '_thread', 'zipimport') or
- (file.startswith(basedir) and
- not file.startswith(os.path.join(basedir, 'site-packages')))) and
+ if (self._is_stdlib_module(object, basedir) and
object.__name__ not in ('xml.etree', 'test.test_pydoc.pydoc_mod')):
if docloc.startswith(("http://", "https://")):
docloc = "{}/{}.html".format(docloc.rstrip("/"),
object.__name__.lower())
@@ -501,6 +491,36 @@ def getdocloc(self, object,
basedir=sysconfig.get_path('stdlib')):
docloc = None
return docloc
+ def _get_version(self, object):
+ if self._is_stdlib_module(object):
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", DeprecationWarning)
+ version = getattr(object, '__version__', None)
+ else:
+ version = getattr(object, '__version__', None)
+ return '' if version is None else str(version)
+
+ def _is_stdlib_module(self, object, basedir=None):
+ basedir = self.STDLIB_DIR if basedir is None else basedir
+
+ try:
+ file = inspect.getabsfile(object)
+ except TypeError:
+ file = '(built-in)'
+
+ if sysconfig.is_python_build():
+ srcdir = sysconfig.get_config_var('srcdir')
+ if srcdir:
+ basedir = os.path.join(srcdir, 'Lib')
+
+ basedir = os.path.normcase(basedir)
+ return (isinstance(object, type(os)) and
+ (object.__name__ in ('errno', 'exceptions', 'gc',
+ 'marshal', 'posix', 'signal', 'sys',
+ '_thread', 'zipimport')
+ or (file.startswith(basedir) and
+ not file.startswith(os.path.join(basedir, 'site-packages')))))
+
# -------------------------------------------- HTML documentation generator
class HTMLRepr(Repr):
@@ -760,8 +780,8 @@ def docmodule(self, object, name=None, mod=None, *ignored):
except TypeError:
filelink = '(built-in)'
info = []
- if hasattr(object, '__version__'):
- version = str(object.__version__)
+
+ if version := self._get_version(object):
if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
version = version[11:-1].strip()
info.append('version %s' % self.escape(version))
@@ -1296,8 +1316,7 @@ def docmodule(self, object, name=None, mod=None,
*ignored):
contents.append(self.docother(value, key, name, maxlen=70))
result = result + self.section('DATA', '\n'.join(contents))
- if hasattr(object, '__version__'):
- version = str(object.__version__)
+ if version := self._get_version(object):
if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
version = version[11:-1].strip()
result = result + self.section('VERSION', version)
diff --git a/Lib/test/test_pydoc/test_pydoc.py
b/Lib/test/test_pydoc/test_pydoc.py
index c640416327efbf..89480423d32bc7 100644
--- a/Lib/test/test_pydoc/test_pydoc.py
+++ b/Lib/test/test_pydoc/test_pydoc.py
@@ -2305,6 +2305,32 @@ def
test_sys_path_adjustment_when_curdir_already_included(self):
trailing_argv0dir = trailing_curdir + [self.argv0dir]
self.assertIsNone(self._get_revised_path(trailing_argv0dir))
+ def test__get_version(self):
+ import json
+ import warnings
+
+ class MyModule:
+ __name__ = 'my_module'
+
+ @property
+ def __version__(self):
+ warnings._deprecated("__version__", remove=(3, 20))
+ return "1.2.3"
+
+ module = MyModule()
+ doc = pydoc.Doc()
+ with warnings.catch_warnings(record=True) as w: # TODO: remove in 3.20
+ warnings.simplefilter("always")
+ version = doc._get_version(json)
+ self.assertEqual(version, "2.0.9")
+ self.assertEqual(len(w), 0)
+
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always")
+ version = doc._get_version(module)
+ self.assertEqual(version, "1.2.3")
+ self.assertEqual(len(w), 1)
+
def setUpModule():
thread_info = threading_helper.threading_setup()
diff --git
a/Misc/NEWS.d/next/Library/2025-10-12-12-43-56.gh-issue-76007.PyGM14.rst
b/Misc/NEWS.d/next/Library/2025-10-12-12-43-56.gh-issue-76007.PyGM14.rst
new file mode 100644
index 00000000000000..3a0914f38228bf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-10-12-12-43-56.gh-issue-76007.PyGM14.rst
@@ -0,0 +1,2 @@
+:mod:`pydoc`: Fix :exc:`DeprecationWarning` being raised when generating doc
for
+:term:`stdlib` modules.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]