Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b47879b

Browse files
committed
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.
1 parent 2f60073 commit b47879b

1 file changed

Lines changed: 92 additions & 9 deletions

File tree

Lib/pydoc.py

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -604,15 +604,98 @@ def docclass(self, object, name=None, mod=None, funcs={}, classes={}):
604604
realname = object.__name__
605605
name = name or realname
606606
bases = object.__bases__
607-
contents = ''
608607

609-
methods, mdict = allmethods(object).items(), {}
610-
methods.sort()
611-
for key, value in methods:
612-
mdict[key] = mdict[value] = '#' + name + '-' + key
613-
for key, value in methods:
614-
contents = contents + self.document(
615-
value, key, mod, funcs, classes, mdict, object)
608+
contents = []
609+
push = contents.append
610+
611+
def spill(msg, attrs, predicate):
612+
ok, attrs = _split_class_attrs(attrs, predicate)
613+
if ok:
614+
push(msg)
615+
for name, kind, homecls, value in ok:
616+
push(self.document(getattr(object, name), name, mod,
617+
funcs, classes, mdict, object))
618+
push('\n')
619+
return attrs
620+
621+
# pydoc can't make any reasonable sense of properties on its own,
622+
# and it doesn't appear that the getter, setter and del'er methods
623+
# are discoverable. For now, just pump out their names.
624+
def spillproperties(msg, attrs):
625+
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property')
626+
if ok:
627+
push(msg)
628+
for name, kind, homecls, value in ok:
629+
push('<dl><dt><strong>%s</strong></dl>\n' % name)
630+
return attrs
631+
632+
def spilldata(msg, attrs):
633+
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data')
634+
if ok:
635+
push(msg)
636+
for name, kind, homecls, value in ok:
637+
base = self.docother(getattr(object, name), name, mod)
638+
doc = getattr(value, "__doc__", None)
639+
if doc is None:
640+
push('<dl><dt>%s</dl>\n' % base)
641+
else:
642+
doc = self.markup(getdoc(value), self.preformat,
643+
funcs, classes, mdict)
644+
doc = '<dd>' + self.small('<tt>%s</tt>' % doc)
645+
push('<dl><dt>%s%s</dl>\n' % (base, doc))
646+
push('\n')
647+
return attrs
648+
649+
attrs = inspect.classify_class_attrs(object)
650+
mdict = {}
651+
for key, kind, homecls, value in attrs:
652+
mdict[key] = anchor = '#' + name + '-' + key
653+
value = getattr(object, key)
654+
try:
655+
# The value may not be hashable (e.g., a data attr with
656+
# a dict or list value).
657+
mdict[value] = anchor
658+
except TypeError:
659+
pass
660+
661+
# All attrs defined in this class come first.
662+
attrs, inherited = _split_class_attrs(attrs,
663+
lambda t: t[2] is object)
664+
# Sort inherited attrs by name of defining class.
665+
inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__))
666+
667+
thisclass = object
668+
while attrs or inherited:
669+
if thisclass is object:
670+
tag = "defined here"
671+
else:
672+
tag = "inherited from class %s" % self.classlink(thisclass,
673+
object.__module__)
674+
tag += ':<br>\n'
675+
676+
# Sort attrs by name.
677+
attrs.sort(lambda t1, t2: cmp(t1[0], t2[0]))
678+
679+
# Pump out the attrs, segregated by kind.
680+
attrs = spill("Methods %s" % tag, attrs,
681+
lambda t: t[1] == 'method')
682+
attrs = spill("Class methods %s" % tag, attrs,
683+
lambda t: t[1] == 'class method')
684+
attrs = spill("Static methods %s" % tag, attrs,
685+
lambda t: t[1] == 'static method')
686+
attrs = spillproperties("Properties %s" % tag, attrs)
687+
attrs = spilldata("Data %s" % tag, attrs)
688+
assert attrs == []
689+
690+
# Split off the attributes inherited from the next class (note
691+
# that inherited remains sorted by class name).
692+
if inherited:
693+
attrs = inherited
694+
thisclass = attrs[0][2]
695+
attrs, inherited = _split_class_attrs(attrs,
696+
lambda t: t[2] is thisclass)
697+
698+
contents = ''.join(contents)
616699

617700
if name == realname:
618701
title = '<a name="%s">class <strong>%s</strong></a>' % (
@@ -908,7 +991,7 @@ def spillproperties(msg, attrs):
908991
for name, kind, homecls, value in ok:
909992
push(name + '\n')
910993
return attrs
911-
994+
912995
def spilldata(msg, attrs):
913996
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data')
914997
if ok:

0 commit comments

Comments
 (0)