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."""
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())
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):
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))
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)
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()