Issue #10446: Several changes to module documentation generated by pydoc:
1. Online reference manual link is now version-specific and the 'MODULE DOCS' section renamed to 'MODULE REFERENCE'. 2. 'FILE' section is moved to the end of the file. 3. Special names processed by pydoc such as __version__ or __credits__ are now excluded from the DATA section. 4. Defined __all__ to prevent pydoc from exposing undocumented details about itself. 5. Removed Python 2.3 compatibility code.
This commit is contained in:
parent
f609654b0e
commit
a47bbf5a4b
|
@ -63,7 +63,9 @@ documents precisely the version of the module you would get if you started the
|
||||||
Python interpreter and typed ``import spam``.
|
Python interpreter and typed ``import spam``.
|
||||||
|
|
||||||
Module docs for core modules are assumed to reside in
|
Module docs for core modules are assumed to reside in
|
||||||
http://docs.python.org/library/. This can be overridden by setting the
|
``http://docs.python.org/X.Y/library/`` where ``X`` and ``Y`` are the
|
||||||
:envvar:`PYTHONDOCS` environment variable to a different URL or to a local
|
major and minor version numbers of the Python interpreter. This can
|
||||||
directory containing the Library Reference Manual pages.
|
be overridden by setting the :envvar:`PYTHONDOCS` environment variable
|
||||||
|
to a different URL or to a local directory containing the Library
|
||||||
|
Reference Manual pages.
|
||||||
|
|
||||||
|
|
55
Lib/pydoc.py
55
Lib/pydoc.py
|
@ -26,13 +26,13 @@ to a file named "<name>.html".
|
||||||
|
|
||||||
Module docs for core modules are assumed to be in
|
Module docs for core modules are assumed to be in
|
||||||
|
|
||||||
http://docs.python.org/library/
|
http://docs.python.org/X.Y/library/
|
||||||
|
|
||||||
This can be overridden by setting the PYTHONDOCS environment variable
|
This can be overridden by setting the PYTHONDOCS environment variable
|
||||||
to a different URL or to a local directory containing the Library
|
to a different URL or to a local directory containing the Library
|
||||||
Reference Manual pages.
|
Reference Manual pages.
|
||||||
"""
|
"""
|
||||||
|
__all__ = ['help']
|
||||||
__author__ = "Ka-Ping Yee <ping@lfw.org>"
|
__author__ = "Ka-Ping Yee <ping@lfw.org>"
|
||||||
__date__ = "26 February 2001"
|
__date__ = "26 February 2001"
|
||||||
|
|
||||||
|
@ -54,14 +54,7 @@ Richard Chamberlain, for the first implementation of textdoc.
|
||||||
import sys, imp, os, re, inspect, builtins, pkgutil
|
import sys, imp, os, re, inspect, builtins, pkgutil
|
||||||
from reprlib import Repr
|
from reprlib import Repr
|
||||||
from traceback import extract_tb as _extract_tb
|
from traceback import extract_tb as _extract_tb
|
||||||
try:
|
from collections import deque
|
||||||
from collections import deque
|
|
||||||
except ImportError:
|
|
||||||
# Python 2.3 compatibility
|
|
||||||
class deque(list):
|
|
||||||
def popleft(self):
|
|
||||||
return self.pop(0)
|
|
||||||
|
|
||||||
# --------------------------------------------------------- common routines
|
# --------------------------------------------------------- common routines
|
||||||
|
|
||||||
def pathdirs():
|
def pathdirs():
|
||||||
|
@ -159,7 +152,8 @@ def visiblename(name, all=None):
|
||||||
# Certain special names are redundant.
|
# Certain special names are redundant.
|
||||||
_hidden_names = ('__builtins__', '__doc__', '__file__', '__path__',
|
_hidden_names = ('__builtins__', '__doc__', '__file__', '__path__',
|
||||||
'__module__', '__name__', '__slots__', '__package__',
|
'__module__', '__name__', '__slots__', '__package__',
|
||||||
'__cached__')
|
'__cached__', '__author__', '__credits__', '__date__',
|
||||||
|
'__version__')
|
||||||
if name in _hidden_names: return 0
|
if name in _hidden_names: return 0
|
||||||
# Private names are hidden, but special names are displayed.
|
# Private names are hidden, but special names are displayed.
|
||||||
if name.startswith('__') and name.endswith('__'): return 1
|
if name.startswith('__') and name.endswith('__'): return 1
|
||||||
|
@ -306,6 +300,11 @@ def safeimport(path, forceload=0, cache={}):
|
||||||
# ---------------------------------------------------- formatter base class
|
# ---------------------------------------------------- formatter base class
|
||||||
|
|
||||||
class Doc:
|
class Doc:
|
||||||
|
|
||||||
|
PYTHONDOCS = os.environ.get("PYTHONDOCS",
|
||||||
|
"http://docs.python.org/%d.%d/library"
|
||||||
|
% sys.version_info[:2])
|
||||||
|
|
||||||
def document(self, object, name=None, *args):
|
def document(self, object, name=None, *args):
|
||||||
"""Generate documentation for an object."""
|
"""Generate documentation for an object."""
|
||||||
args = (object, name) + args
|
args = (object, name) + args
|
||||||
|
@ -340,10 +339,10 @@ class Doc:
|
||||||
except TypeError:
|
except TypeError:
|
||||||
file = '(built-in)'
|
file = '(built-in)'
|
||||||
|
|
||||||
docloc = os.environ.get("PYTHONDOCS",
|
docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
|
||||||
"http://docs.python.org/library")
|
|
||||||
basedir = os.path.join(sys.exec_prefix, "lib",
|
basedir = os.path.join(sys.exec_prefix, "lib",
|
||||||
"python"+sys.version[0:3])
|
"python%d.%d" % sys.version_info[:2])
|
||||||
if (isinstance(object, type(os)) and
|
if (isinstance(object, type(os)) and
|
||||||
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
|
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
|
||||||
'marshal', 'posix', 'signal', 'sys',
|
'marshal', 'posix', 'signal', 'sys',
|
||||||
|
@ -607,7 +606,7 @@ class HTMLDoc(Doc):
|
||||||
head = head + ' (%s)' % ', '.join(info)
|
head = head + ' (%s)' % ', '.join(info)
|
||||||
docloc = self.getdocloc(object)
|
docloc = self.getdocloc(object)
|
||||||
if docloc is not None:
|
if docloc is not None:
|
||||||
docloc = '<br><a href="%(docloc)s">Module Docs</a>' % locals()
|
docloc = '<br><a href="%(docloc)s">Module Reference</a>' % locals()
|
||||||
else:
|
else:
|
||||||
docloc = ''
|
docloc = ''
|
||||||
result = self.heading(
|
result = self.heading(
|
||||||
|
@ -1016,21 +1015,16 @@ class TextDoc(Doc):
|
||||||
name = object.__name__ # ignore the passed-in name
|
name = object.__name__ # ignore the passed-in name
|
||||||
synop, desc = splitdoc(getdoc(object))
|
synop, desc = splitdoc(getdoc(object))
|
||||||
result = self.section('NAME', name + (synop and ' - ' + synop))
|
result = self.section('NAME', name + (synop and ' - ' + synop))
|
||||||
|
all = getattr(object, '__all__', None)
|
||||||
try:
|
|
||||||
all = object.__all__
|
|
||||||
except AttributeError:
|
|
||||||
all = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
file = inspect.getabsfile(object)
|
|
||||||
except TypeError:
|
|
||||||
file = '(built-in)'
|
|
||||||
result = result + self.section('FILE', file)
|
|
||||||
|
|
||||||
docloc = self.getdocloc(object)
|
docloc = self.getdocloc(object)
|
||||||
if docloc is not None:
|
if docloc is not None:
|
||||||
result = result + self.section('MODULE DOCS', docloc)
|
result = result + self.section('MODULE REFERENCE', docloc + """
|
||||||
|
|
||||||
|
The following documentation is automatically generated from the Python source
|
||||||
|
files. It may be incomplete, incorrect or include features that are considered
|
||||||
|
implementation detail and may vary between Python implementations. When in
|
||||||
|
doubt, consult the module reference at the location listed above.
|
||||||
|
""")
|
||||||
|
|
||||||
if desc:
|
if desc:
|
||||||
result = result + self.section('DESCRIPTION', desc)
|
result = result + self.section('DESCRIPTION', desc)
|
||||||
|
@ -1109,6 +1103,11 @@ class TextDoc(Doc):
|
||||||
result = result + self.section('AUTHOR', str(object.__author__))
|
result = result + self.section('AUTHOR', str(object.__author__))
|
||||||
if hasattr(object, '__credits__'):
|
if hasattr(object, '__credits__'):
|
||||||
result = result + self.section('CREDITS', str(object.__credits__))
|
result = result + self.section('CREDITS', str(object.__credits__))
|
||||||
|
try:
|
||||||
|
file = inspect.getabsfile(object)
|
||||||
|
except TypeError:
|
||||||
|
file = '(built-in)'
|
||||||
|
result = result + self.section('FILE', file)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def docclass(self, object, name=None, mod=None):
|
def docclass(self, object, name=None, mod=None):
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
__author__ = "Benjamin Peterson"
|
__author__ = "Benjamin Peterson"
|
||||||
__credits__ = "Nobody"
|
__credits__ = "Nobody"
|
||||||
__version__ = "1.2.3.4"
|
__version__ = "1.2.3.4"
|
||||||
|
__xyz__ = "X, Y and Z"
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
"""Hello and goodbye"""
|
"""Hello and goodbye"""
|
||||||
|
|
|
@ -22,9 +22,6 @@ if hasattr(pydoc_mod, "__loader__"):
|
||||||
expected_text_pattern = """
|
expected_text_pattern = """
|
||||||
NAME
|
NAME
|
||||||
test.pydoc_mod - This is a test module for test_pydoc
|
test.pydoc_mod - This is a test module for test_pydoc
|
||||||
|
|
||||||
FILE
|
|
||||||
%s
|
|
||||||
%s
|
%s
|
||||||
CLASSES
|
CLASSES
|
||||||
builtins.object
|
builtins.object
|
||||||
|
@ -72,9 +69,7 @@ FUNCTIONS
|
||||||
nodoc_func()
|
nodoc_func()
|
||||||
|
|
||||||
DATA
|
DATA
|
||||||
__author__ = 'Benjamin Peterson'
|
__xyz__ = 'X, Y and Z'
|
||||||
__credits__ = 'Nobody'
|
|
||||||
__version__ = '1.2.3.4'
|
|
||||||
|
|
||||||
VERSION
|
VERSION
|
||||||
1.2.3.4
|
1.2.3.4
|
||||||
|
@ -84,6 +79,9 @@ AUTHOR
|
||||||
|
|
||||||
CREDITS
|
CREDITS
|
||||||
Nobody
|
Nobody
|
||||||
|
|
||||||
|
FILE
|
||||||
|
%s
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
expected_html_pattern = """
|
expected_html_pattern = """
|
||||||
|
@ -167,9 +165,7 @@ war</tt></dd></dl>
|
||||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
|
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
|
||||||
\x20\x20\x20\x20
|
\x20\x20\x20\x20
|
||||||
<tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td>
|
<tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td>
|
||||||
<td width="100%%"><strong>__author__</strong> = 'Benjamin Peterson'<br>
|
<td width="100%%"><strong>__xyz__</strong> = 'X, Y and Z'</td></tr></table><p>
|
||||||
<strong>__credits__</strong> = 'Nobody'<br>
|
|
||||||
<strong>__version__</strong> = '1.2.3.4'</td></tr></table><p>
|
|
||||||
<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||||
<tr bgcolor="#7799ee">
|
<tr bgcolor="#7799ee">
|
||||||
<td colspan=3 valign=bottom> <br>
|
<td colspan=3 valign=bottom> <br>
|
||||||
|
@ -259,7 +255,7 @@ class PyDocDocTest(unittest.TestCase):
|
||||||
def test_text_doc(self):
|
def test_text_doc(self):
|
||||||
result, doc_loc = get_pydoc_text(pydoc_mod)
|
result, doc_loc = get_pydoc_text(pydoc_mod)
|
||||||
expected_text = expected_text_pattern % \
|
expected_text = expected_text_pattern % \
|
||||||
(inspect.getabsfile(pydoc_mod), doc_loc)
|
(doc_loc, inspect.getabsfile(pydoc_mod))
|
||||||
if result != expected_text:
|
if result != expected_text:
|
||||||
print_diffs(expected_text, result)
|
print_diffs(expected_text, result)
|
||||||
self.fail("outputs are not equal, see diff above")
|
self.fail("outputs are not equal, see diff above")
|
||||||
|
|
Loading…
Reference in New Issue