Patch #711902: Cause pydoc to show data descriptor __doc__ strings.
diff --git a/Doc/lib/libinspect.tex b/Doc/lib/libinspect.tex
index a1293f0..cc41f2f 100644
--- a/Doc/lib/libinspect.tex
+++ b/Doc/lib/libinspect.tex
@@ -161,6 +161,31 @@
   Return true if the object is a user-defined or built-in function or method.
 \end{funcdesc}
 
+\begin{funcdesc}{ismethoddescriptor}{object}
+  Return true if the object is a method descriptor, but not if ismethod() or 
+  isclass() or isfunction() are true.
+
+  This is new as of Python 2.2, and, for example, is true of int.__add__.
+  An object passing this test has a __get__ attribute but not a __set__
+  attribute, but beyond that the set of attributes varies.  __name__ is
+  usually sensible, and __doc__ often is.
+
+  Methods implemented via descriptors that also pass one of the other
+  tests return false from the ismethoddescriptor() test, simply because
+  the other tests promise more -- you can, e.g., count on having the
+  im_func attribute (etc) when an object passes ismethod().
+\end{funcdesc}
+
+\begin{funcdesc}{isdatadescriptor}{object}
+  Return true if the object is a data descriptor.
+
+  Data descriptors have both a __get__ and a __set__ attribute.  Examples are
+  properties (defined in Python) and getsets and members (defined in C).
+  Typically, data descriptors will also have __name__ and __doc__ attributes 
+  (properties, getsets, and members have both of these attributes), but this 
+  is not guaranteed.
+\end{funcdesc}
+
 \subsection{Retrieving source code
             \label{inspect-source}}
 
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 4baebe0..a2ea739 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -78,6 +78,16 @@
             and not isfunction(object)
             and not isclass(object))
 
+def isdatadescriptor(object):
+    """Return true if the object is a data descriptor.
+
+    Data descriptors have both a __get__ and a __set__ attribute.  Examples are
+    properties (defined in Python) and getsets and members (defined in C).
+    Typically, data descriptors will also have __name__ and __doc__ attributes
+    (properties, getsets, and members have both of these attributes), but this
+    is not guaranteed."""
+    return (hasattr(object, "__set__") and hasattr(object, "__get__"))
+
 def isfunction(object):
     """Return true if the object is a user-defined function.
 
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 7f0addd..8e5064a 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -686,7 +686,7 @@
                 push(msg)
                 for name, kind, homecls, value in ok:
                     base = self.docother(getattr(object, name), name, mod)
-                    if callable(value):
+                    if callable(value) or inspect.isdatadescriptor(value):
                         doc = getattr(value, "__doc__", None)
                     else:
                         doc = None
@@ -1087,7 +1087,7 @@
                 hr.maybe()
                 push(msg)
                 for name, kind, homecls, value in ok:
-                    if callable(value):
+                    if callable(value) or inspect.isdatadescriptor(value):
                         doc = getattr(value, "__doc__", None)
                     else:
                         doc = None
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index d253f26..33e0b0d 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -61,6 +61,7 @@
 # isbuiltin, isroutine, getmembers, getdoc, getfile, getmodule,
 # getsourcefile, getcomments, getsource, getclasstree, getargspec,
 # getargvalues, formatargspec, formatargvalues, currentframe, stack, trace
+# isdatadescriptor
 
 from test.test_support import TestFailed, TESTFN
 import sys, imp, os, string
@@ -104,6 +105,8 @@
 istest(inspect.ismethod, 'git.argue')
 istest(inspect.ismodule, 'mod')
 istest(inspect.istraceback, 'tb')
+istest(inspect.isdatadescriptor, '__builtins__.file.closed')
+istest(inspect.isdatadescriptor, '__builtins__.file.softspace')
 test(inspect.isroutine(mod.spam), 'isroutine(mod.spam)')
 test(inspect.isroutine([].count), 'isroutine([].count)')
 
diff --git a/Misc/NEWS b/Misc/NEWS
index a9063e2..05c9ce2 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,9 @@
 Library
 -------
 
+- inspect.is{method|data}descriptor was added, to allow pydoc display
+  __doc__ of data descriptors.
+
 - Fixed socket speed loss caused by use of the _socketobject wrapper class
   in socket.py.