[Python-checkins] cpython (merge 3.2 -> default): Issue #11666: Teach pydoc to display full help for named tuples

raymond.hettinger python-checkins at python.org
Fri Mar 25 22:16:48 CET 2011


http://hg.python.org/cpython/rev/374982e17f36
changeset:   68936:374982e17f36
parent:      68934:03c7a83bbdd3
parent:      68935:daa408ad7440
user:        Raymond Hettinger <python at rcn.com>
date:        Fri Mar 25 14:16:13 2011 -0700
summary:
  Issue #11666: Teach pydoc to display full help for named tuples

files:
  Lib/pydoc.py           |  21 ++++++++++++---------
  Lib/test/test_pydoc.py |  12 +++++++++++-
  Misc/NEWS              |   3 +++
  3 files changed, 26 insertions(+), 10 deletions(-)


diff --git a/Lib/pydoc.py b/Lib/pydoc.py
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -165,7 +165,7 @@
             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 @@
         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 @@
             # 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 @@
             # 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 @@
 
         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 @@
             # 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 @@
 
         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
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -12,9 +12,10 @@
 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 @@
         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):
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -105,6 +105,9 @@
 
 - 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.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list