summaryrefslogtreecommitdiffstats
path: root/Lib/pydoc.py
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-09-24 04:47:19 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-09-24 04:47:19 (GMT)
commitb47879b239dc51e9c5df04578f06ae6aab4567f4 (patch)
tree750a0eba1731790457e065501354d340f86b0e3b /Lib/pydoc.py
parent2f60073d2dd37a471ca3c7df0a694230b32d1a57 (diff)
downloadcpython-b47879b239dc51e9c5df04578f06ae6aab4567f4.zip
cpython-b47879b239dc51e9c5df04578f06ae6aab4567f4.tar.gz
cpython-b47879b239dc51e9c5df04578f06ae6aab4567f4.tar.bz2
Try to do for pydoc's GUI mode what the earlier checkin did for text
mode (identify the source class for class attrs; segregate attrs according to source class, and whether class method, static method, property, plain method, or data; display data attrs; display docstrings for data attrs when possible). Alas, this is mondo ugly, and I'm no HTML guy. Part of the problem is that pydoc's GUI mode has always been ugly under IE, largely because <small> under IE renders docstrings unreadably small (while sometimes non-docstring text is painfully large). Another part is that these segregated listings of attrs would *probably* look much better as bulleted lists. Alas, when I tried that, the bullets all ended up on lines by themselves, before the method names; this is apparently because pydoc (ab?)uses definition lists for format effects, and at least under IE if a definition list is the first chunk of a list item, it gets rendered on a line after the <li> bullet. An HTML wizard would certainly be welcomed here.
Diffstat (limited to 'Lib/pydoc.py')
-rwxr-xr-xLib/pydoc.py101
1 files changed, 92 insertions, 9 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 915b37b..8cc1205 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -604,15 +604,98 @@ TT { font-family: lucidatypewriter, lucida console, courier }
realname = object.__name__
name = name or realname
bases = object.__bases__
- contents = ''
- methods, mdict = allmethods(object).items(), {}
- methods.sort()
- for key, value in methods:
- mdict[key] = mdict[value] = '#' + name + '-' + key
- for key, value in methods:
- contents = contents + self.document(
- value, key, mod, funcs, classes, mdict, object)
+ contents = []
+ push = contents.append
+
+ def spill(msg, attrs, predicate):
+ ok, attrs = _split_class_attrs(attrs, predicate)
+ if ok:
+ push(msg)
+ for name, kind, homecls, value in ok:
+ push(self.document(getattr(object, name), name, mod,
+ funcs, classes, mdict, object))
+ push('\n')
+ return attrs
+
+ # pydoc can't make any reasonable sense of properties on its own,
+ # and it doesn't appear that the getter, setter and del'er methods
+ # are discoverable. For now, just pump out their names.
+ def spillproperties(msg, attrs):
+ ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property')
+ if ok:
+ push(msg)
+ for name, kind, homecls, value in ok:
+ push('<dl><dt><strong>%s</strong></dl>\n' % name)
+ return attrs
+
+ def spilldata(msg, attrs):
+ ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data')
+ if ok:
+ push(msg)
+ for name, kind, homecls, value in ok:
+ base = self.docother(getattr(object, name), name, mod)
+ doc = getattr(value, "__doc__", None)
+ if doc is None:
+ push('<dl><dt>%s</dl>\n' % base)
+ else:
+ doc = self.markup(getdoc(value), self.preformat,
+ funcs, classes, mdict)
+ doc = '<dd>' + self.small('<tt>%s</tt>' % doc)
+ push('<dl><dt>%s%s</dl>\n' % (base, doc))
+ push('\n')
+ return attrs
+
+ attrs = inspect.classify_class_attrs(object)
+ mdict = {}
+ for key, kind, homecls, value in attrs:
+ mdict[key] = anchor = '#' + name + '-' + key
+ value = getattr(object, key)
+ try:
+ # The value may not be hashable (e.g., a data attr with
+ # a dict or list value).
+ mdict[value] = anchor
+ except TypeError:
+ pass
+
+ # All attrs defined in this class come first.
+ attrs, inherited = _split_class_attrs(attrs,
+ lambda t: t[2] is object)
+ # Sort inherited attrs by name of defining class.
+ inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__))
+
+ thisclass = object
+ while attrs or inherited:
+ if thisclass is object:
+ tag = "defined here"
+ else:
+ tag = "inherited from class %s" % self.classlink(thisclass,
+ object.__module__)
+ tag += ':<br>\n'
+
+ # Sort attrs by name.
+ attrs.sort(lambda t1, t2: cmp(t1[0], t2[0]))
+
+ # Pump out the attrs, segregated by kind.
+ attrs = spill("Methods %s" % tag, attrs,
+ lambda t: t[1] == 'method')
+ attrs = spill("Class methods %s" % tag, attrs,
+ lambda t: t[1] == 'class method')
+ attrs = spill("Static methods %s" % tag, attrs,
+ lambda t: t[1] == 'static method')
+ attrs = spillproperties("Properties %s" % tag, attrs)
+ attrs = spilldata("Data %s" % tag, attrs)
+ assert attrs == []
+
+ # Split off the attributes inherited from the next class (note
+ # that inherited remains sorted by class name).
+ if inherited:
+ attrs = inherited
+ thisclass = attrs[0][2]
+ attrs, inherited = _split_class_attrs(attrs,
+ lambda t: t[2] is thisclass)
+
+ contents = ''.join(contents)
if name == realname:
title = '<a name="%s">class <strong>%s</strong></a>' % (
@@ -908,7 +991,7 @@ class TextDoc(Doc):
for name, kind, homecls, value in ok:
push(name + '\n')
return attrs
-
+
def spilldata(msg, attrs):
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data')
if ok: