]> granicus.if.org Git - python/commitdiff
After much thrashing, I believe this is a truly minimal patch to teach
authorTim Peters <tim.peters@gmail.com>
Thu, 20 Sep 2001 05:13:38 +0000 (05:13 +0000)
committerTim Peters <tim.peters@gmail.com>
Thu, 20 Sep 2001 05:13:38 +0000 (05:13 +0000)
pydoc how to do something sensible with 2.2 descriptors.  To see the
difference, browse __builtin__ via pydoc before and after the patch.

Lib/inspect.py
Lib/pydoc.py

index 5bb6a83f1947aa3a694a4cfe179d5efaa556819a..c4c15f51dd33c08df583eb074e9f164cc071c7eb 100644 (file)
@@ -57,6 +57,23 @@ def ismethod(object):
         im_self         instance to which this method is bound, or None"""
     return isinstance(object, types.MethodType)
 
+def ismethoddescriptor(object):
+    """Return true if the object is a method descriptor, and ismethod false.
+
+    This is new in 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 the ismethod() test
+    return false from the ismethoddescriptor() test, simply because
+    ismethod() is more informative -- you can, e.g., count on having the
+    im_func attribute (etc) when an object passes the latter."""
+    return (hasattr(object, "__get__")
+            and not hasattr(object, "__set__") # else it's a data descriptor
+            and not ismethod(object)           # mutual exclusion
+            and not isclass(object))
+
 def isfunction(object):
     """Return true if the object is a user-defined function.
 
@@ -127,7 +144,10 @@ def isbuiltin(object):
 
 def isroutine(object):
     """Return true if the object is any kind of function or method."""
-    return isbuiltin(object) or isfunction(object) or ismethod(object)
+    return (isbuiltin(object)
+            or isfunction(object)
+            or ismethod(object)
+            or ismethoddescriptor(object))
 
 def getmembers(object, predicate=None):
     """Return all members of an object as (name, value) pairs sorted by name.
index 4c7471afbc02c10c80b34c8207692e3787e6c70f..b8050318b04c8e00257b3469a251eac0793b8380 100755 (executable)
@@ -115,9 +115,12 @@ def stripid(text):
             return re.sub(pattern, '>', text)
     return text
 
+def _is_some_method(object):
+    return inspect.ismethod(object) or inspect.ismethoddescriptor(object)
+
 def allmethods(cl):
     methods = {}
-    for key, value in inspect.getmembers(cl, inspect.ismethod):
+    for key, value in inspect.getmembers(cl, _is_some_method):
         methods[key] = 1
     for base in cl.__bases__:
         methods.update(allmethods(base)) # all your base are belong to us
@@ -656,7 +659,7 @@ TT { font-family: lucidatypewriter, lucida console, courier }
                 reallink = realname
             title = '<a name="%s"><strong>%s</strong></a> = %s' % (
                 anchor, name, reallink)
-        if inspect.isbuiltin(object):
+        if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object):
             argspec = '(...)'
         else:
             args, varargs, varkw, defaults = inspect.getargspec(object)
@@ -913,7 +916,7 @@ class TextDoc(Doc):
                 cl.__dict__[realname] is object):
                 skipdocs = 1
             title = self.bold(name) + ' = ' + realname
-        if inspect.isbuiltin(object):
+        if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object):
             argspec = '(...)'
         else:
             args, varargs, varkw, defaults = inspect.getargspec(object)