diff options
-rwxr-xr-x | Lib/pydoc.py | 21 | ||||
-rw-r--r-- | Lib/test/test_pydoc.py | 12 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
3 files changed, 26 insertions, 10 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 9f8f120..739b440 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -165,7 +165,7 @@ def _split_list(s, predicate): no.append(x) return yes, no -def visiblename(name, all=None): +def visiblename(name, all=None, obj=None): """Decide whether to show documentation on a variable.""" # Certain special names are redundant. if name in {'__builtins__', '__doc__', '__file__', '__path__', @@ -175,6 +175,9 @@ def visiblename(name, all=None): return 0 # Private names are hidden, but special names are displayed. if name.startswith('__') and name.endswith('__'): return 1 + # Namedtuples have public fields and methods with a single leading underscore + if name.startswith('_') and hasattr(obj, '_fields'): + return True if all is not None: # only document that which the programmer exported in __all__ return name in all @@ -642,7 +645,7 @@ class HTMLDoc(Doc): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): - if visiblename(key, all): + if visiblename(key, all, object): classes.append((key, value)) cdict[key] = cdict[value] = '#' + key for key, value in classes: @@ -658,13 +661,13 @@ class HTMLDoc(Doc): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or inspect.isbuiltin(value) or inspect.getmodule(value) is object): - if visiblename(key, all): + if visiblename(key, all, object): funcs.append((key, value)) fdict[key] = '#-' + key if inspect.isfunction(value): fdict[value] = fdict[key] data = [] for key, value in inspect.getmembers(object, isdata): - if visiblename(key, all): + if visiblename(key, all, object): data.append((key, value)) doc = self.markup(getdoc(object), self.preformat, fdict, cdict) @@ -789,7 +792,7 @@ class HTMLDoc(Doc): attrs = [(name, kind, cls, value) for name, kind, cls, value in classify_class_attrs(object) - if visiblename(name)] + if visiblename(name, obj=object)] mdict = {} for key, kind, homecls, value in attrs: @@ -1056,18 +1059,18 @@ doubt, consult the module reference at the location listed above. # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): - if visiblename(key, all): + if visiblename(key, all, object): classes.append((key, value)) funcs = [] for key, value in inspect.getmembers(object, inspect.isroutine): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or inspect.isbuiltin(value) or inspect.getmodule(value) is object): - if visiblename(key, all): + if visiblename(key, all, object): funcs.append((key, value)) data = [] for key, value in inspect.getmembers(object, isdata): - if visiblename(key, all): + if visiblename(key, all, object): data.append((key, value)) modpkgs = [] @@ -1206,7 +1209,7 @@ doubt, consult the module reference at the location listed above. attrs = [(name, kind, cls, value) for name, kind, cls, value in classify_class_attrs(object) - if visiblename(name)] + if visiblename(name, obj=object)] while attrs: if mro: diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 0ecf6a5..4a83dff 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -12,9 +12,10 @@ import unittest import xml.etree import textwrap from io import StringIO +from collections import namedtuple from contextlib import contextmanager from test.support import TESTFN, forget, rmtree, EnvironmentVarGuard, \ - reap_children, captured_output + reap_children, captured_output, captured_stdout from test import pydoc_mod @@ -379,6 +380,15 @@ class PydocDocTest(unittest.TestCase): finally: pydoc.getpager = getpager_old + def test_namedtuple_public_underscore(self): + NT = namedtuple('NT', ['abc', 'def'], rename=True) + with captured_stdout() as help_io: + help(NT) + helptext = help_io.getvalue() + self.assertIn('_1', helptext) + self.assertIn('_replace', helptext) + self.assertIn('_asdict', helptext) + class TestDescriptions(unittest.TestCase): @@ -105,6 +105,9 @@ Library - Issue #11628: cmp_to_key generated class should use __slots__. +- Issue #11666: let help() display named tuple attributes and methods + that start with a leading underscore. + - Issue #5537: Fix time2isoz() and time2netscape() functions of httplib.cookiejar for expiration year greater than 2038 on 32-bit systems. |