After much thrashing, I believe this is a truly minimal patch to teach

pydoc how to do something sensible with 2.2 descriptors.  To see the
difference, browse __builtin__ via pydoc before and after the patch.
This commit is contained in:
Tim Peters 2001-09-20 05:13:38 +00:00
parent 3069d50c18
commit 536d2262f7
2 changed files with 27 additions and 4 deletions

View file

@ -57,6 +57,23 @@ def ismethod(object):
im_self instance to which this method is bound, or None""" im_self instance to which this method is bound, or None"""
return isinstance(object, types.MethodType) 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): def isfunction(object):
"""Return true if the object is a user-defined function. """Return true if the object is a user-defined function.
@ -127,7 +144,10 @@ def isbuiltin(object):
def isroutine(object): def isroutine(object):
"""Return true if the object is any kind of function or method.""" """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): def getmembers(object, predicate=None):
"""Return all members of an object as (name, value) pairs sorted by name. """Return all members of an object as (name, value) pairs sorted by name.

View file

@ -115,9 +115,12 @@ def stripid(text):
return re.sub(pattern, '>', text) return re.sub(pattern, '>', text)
return text return text
def _is_some_method(object):
return inspect.ismethod(object) or inspect.ismethoddescriptor(object)
def allmethods(cl): def allmethods(cl):
methods = {} methods = {}
for key, value in inspect.getmembers(cl, inspect.ismethod): for key, value in inspect.getmembers(cl, _is_some_method):
methods[key] = 1 methods[key] = 1
for base in cl.__bases__: for base in cl.__bases__:
methods.update(allmethods(base)) # all your base are belong to us methods.update(allmethods(base)) # all your base are belong to us
@ -656,7 +659,7 @@ TT { font-family: lucidatypewriter, lucida console, courier }
reallink = realname reallink = realname
title = '<a name="%s"><strong>%s</strong></a> = %s' % ( title = '<a name="%s"><strong>%s</strong></a> = %s' % (
anchor, name, reallink) anchor, name, reallink)
if inspect.isbuiltin(object): if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object):
argspec = '(...)' argspec = '(...)'
else: else:
args, varargs, varkw, defaults = inspect.getargspec(object) args, varargs, varkw, defaults = inspect.getargspec(object)
@ -913,7 +916,7 @@ class TextDoc(Doc):
cl.__dict__[realname] is object): cl.__dict__[realname] is object):
skipdocs = 1 skipdocs = 1
title = self.bold(name) + ' = ' + realname title = self.bold(name) + ' = ' + realname
if inspect.isbuiltin(object): if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object):
argspec = '(...)' argspec = '(...)'
else: else:
args, varargs, varkw, defaults = inspect.getargspec(object) args, varargs, varkw, defaults = inspect.getargspec(object)