mirror of https://github.com/python/cpython.git
More work on class display:
+ Minor code cleanup, generalization and simplification. + "Do something" to make the attribute aggregation more apparent: - In text mode, stick a "* " at the front of subgroup header lines. - In GUI mode, display a horizontal rule between subgroups. For GUI mode, this is a huge improvement, at least under IE.
This commit is contained in:
parent
b47879b239
commit
fa26f7cc39
102
Lib/pydoc.py
102
Lib/pydoc.py
|
@ -128,14 +128,21 @@ def allmethods(cl):
|
||||||
methods[key] = getattr(cl, key)
|
methods[key] = getattr(cl, key)
|
||||||
return methods
|
return methods
|
||||||
|
|
||||||
def _split_class_attrs(attrs, predicate):
|
def _split_list(s, predicate):
|
||||||
|
"""Split sequence s via predicate, and return pair ([true], [false]).
|
||||||
|
|
||||||
|
The return value is a 2-tuple of lists,
|
||||||
|
([x for x in s if predicate(x)],
|
||||||
|
[x for x in s if not predicate(x)])
|
||||||
|
"""
|
||||||
|
|
||||||
yes = []
|
yes = []
|
||||||
no = []
|
no = []
|
||||||
for tuple in attrs:
|
for x in s:
|
||||||
if predicate(tuple):
|
if predicate(x):
|
||||||
yes.append(tuple)
|
yes.append(x)
|
||||||
else:
|
else:
|
||||||
no.append(tuple)
|
no.append(x)
|
||||||
return yes, no
|
return yes, no
|
||||||
|
|
||||||
# ----------------------------------------------------- module manipulation
|
# ----------------------------------------------------- module manipulation
|
||||||
|
@ -608,9 +615,20 @@ def docclass(self, object, name=None, mod=None, funcs={}, classes={}):
|
||||||
contents = []
|
contents = []
|
||||||
push = contents.append
|
push = contents.append
|
||||||
|
|
||||||
|
# Cute little class to pump out a horizontal rule between sections.
|
||||||
|
class HorizontalRule:
|
||||||
|
def __init__(self):
|
||||||
|
self.needone = 0
|
||||||
|
def maybe(self):
|
||||||
|
if self.needone:
|
||||||
|
push('<hr>\n')
|
||||||
|
self.needone = 1
|
||||||
|
hr = HorizontalRule()
|
||||||
|
|
||||||
def spill(msg, attrs, predicate):
|
def spill(msg, attrs, predicate):
|
||||||
ok, attrs = _split_class_attrs(attrs, predicate)
|
ok, attrs = _split_list(attrs, predicate)
|
||||||
if ok:
|
if ok:
|
||||||
|
hr.maybe()
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
push(self.document(getattr(object, name), name, mod,
|
push(self.document(getattr(object, name), name, mod,
|
||||||
|
@ -621,17 +639,19 @@ def spill(msg, attrs, predicate):
|
||||||
# pydoc can't make any reasonable sense of properties on its own,
|
# 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
|
# and it doesn't appear that the getter, setter and del'er methods
|
||||||
# are discoverable. For now, just pump out their names.
|
# are discoverable. For now, just pump out their names.
|
||||||
def spillproperties(msg, attrs):
|
def spillproperties(msg, attrs, predicate):
|
||||||
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property')
|
ok, attrs = _split_list(attrs, predicate)
|
||||||
if ok:
|
if ok:
|
||||||
|
hr.maybe()
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
push('<dl><dt><strong>%s</strong></dl>\n' % name)
|
push('<dl><dt><strong>%s</strong></dl>\n' % name)
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
def spilldata(msg, attrs):
|
def spilldata(msg, attrs, predicate):
|
||||||
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data')
|
ok, attrs = _split_list(attrs, predicate)
|
||||||
if ok:
|
if ok:
|
||||||
|
hr.maybe()
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
base = self.docother(getattr(object, name), name, mod)
|
base = self.docother(getattr(object, name), name, mod)
|
||||||
|
@ -658,18 +678,17 @@ def spilldata(msg, attrs):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# All attrs defined in this class come first.
|
# Sort attrs by name of defining class.
|
||||||
attrs, inherited = _split_class_attrs(attrs,
|
attrs.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__))
|
||||||
lambda t: t[2] is object)
|
|
||||||
# Sort inherited attrs by name of defining class.
|
thisclass = object # list attrs defined here first
|
||||||
inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__))
|
while attrs:
|
||||||
|
attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
|
||||||
|
|
||||||
thisclass = object
|
|
||||||
while attrs or inherited:
|
|
||||||
if thisclass is object:
|
if thisclass is object:
|
||||||
tag = "defined here"
|
tag = "defined here"
|
||||||
else:
|
else:
|
||||||
tag = "inherited from class %s" % self.classlink(thisclass,
|
tag = "inherited from %s" % self.classlink(thisclass,
|
||||||
object.__module__)
|
object.__module__)
|
||||||
tag += ':<br>\n'
|
tag += ':<br>\n'
|
||||||
|
|
||||||
|
@ -683,8 +702,10 @@ def spilldata(msg, attrs):
|
||||||
lambda t: t[1] == 'class method')
|
lambda t: t[1] == 'class method')
|
||||||
attrs = spill("Static methods %s" % tag, attrs,
|
attrs = spill("Static methods %s" % tag, attrs,
|
||||||
lambda t: t[1] == 'static method')
|
lambda t: t[1] == 'static method')
|
||||||
attrs = spillproperties("Properties %s" % tag, attrs)
|
attrs = spillproperties("Properties %s" % tag, attrs,
|
||||||
attrs = spilldata("Data %s" % tag, attrs)
|
lambda t: t[1] == 'property')
|
||||||
|
attrs = spilldata("Data %s" % tag, attrs,
|
||||||
|
lambda t: t[1] == 'data')
|
||||||
assert attrs == []
|
assert attrs == []
|
||||||
|
|
||||||
# Split off the attributes inherited from the next class (note
|
# Split off the attributes inherited from the next class (note
|
||||||
|
@ -692,8 +713,6 @@ def spilldata(msg, attrs):
|
||||||
if inherited:
|
if inherited:
|
||||||
attrs = inherited
|
attrs = inherited
|
||||||
thisclass = attrs[0][2]
|
thisclass = attrs[0][2]
|
||||||
attrs, inherited = _split_class_attrs(attrs,
|
|
||||||
lambda t: t[2] is thisclass)
|
|
||||||
|
|
||||||
contents = ''.join(contents)
|
contents = ''.join(contents)
|
||||||
|
|
||||||
|
@ -973,7 +992,7 @@ def makename(c, m=object.__module__): return classname(c, m)
|
||||||
push = contents.append
|
push = contents.append
|
||||||
|
|
||||||
def spill(msg, attrs, predicate):
|
def spill(msg, attrs, predicate):
|
||||||
ok, attrs = _split_class_attrs(attrs, predicate)
|
ok, attrs = _split_list(attrs, predicate)
|
||||||
if ok:
|
if ok:
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
|
@ -984,16 +1003,16 @@ def spill(msg, attrs, predicate):
|
||||||
# pydoc can't make any reasonable sense of properties on its own,
|
# 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
|
# and it doesn't appear that the getter, setter and del'er methods
|
||||||
# are discoverable. For now, just pump out their names.
|
# are discoverable. For now, just pump out their names.
|
||||||
def spillproperties(msg, attrs):
|
def spillproperties(msg, attrs, predicate):
|
||||||
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property')
|
ok, attrs = _split_list(attrs, predicate)
|
||||||
if ok:
|
if ok:
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
push(name + '\n')
|
push(name + '\n')
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
def spilldata(msg, attrs):
|
def spilldata(msg, attrs, predicate):
|
||||||
ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data')
|
ok, attrs = _split_list(attrs, predicate)
|
||||||
if ok:
|
if ok:
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
|
@ -1004,32 +1023,33 @@ def spilldata(msg, attrs):
|
||||||
|
|
||||||
attrs = inspect.classify_class_attrs(object)
|
attrs = inspect.classify_class_attrs(object)
|
||||||
|
|
||||||
# All attrs defined in this class come first.
|
# Sort attrs by name of defining class.
|
||||||
attrs, inherited = _split_class_attrs(attrs,
|
attrs.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__))
|
||||||
lambda t: t[2] is object)
|
|
||||||
# Sort inherited attrs by name of defining class.
|
thisclass = object # list attrs defined here first
|
||||||
inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__))
|
while attrs:
|
||||||
|
attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
|
||||||
|
|
||||||
thisclass = object
|
|
||||||
while attrs or inherited:
|
|
||||||
if thisclass is object:
|
if thisclass is object:
|
||||||
tag = "defined here"
|
tag = "defined here"
|
||||||
else:
|
else:
|
||||||
tag = "inherited from class %s" % classname(thisclass,
|
tag = "inherited from %s" % classname(thisclass,
|
||||||
object.__module__)
|
object.__module__)
|
||||||
|
|
||||||
# Sort attrs by name.
|
# Sort attrs by name.
|
||||||
attrs.sort(lambda t1, t2: cmp(t1[0], t2[0]))
|
attrs.sort(lambda t1, t2: cmp(t1[0], t2[0]))
|
||||||
|
|
||||||
# Pump out the attrs, segregated by kind.
|
# Pump out the attrs, segregated by kind.
|
||||||
attrs = spill("Methods %s:\n" % tag, attrs,
|
attrs = spill("* Methods %s:\n" % tag, attrs,
|
||||||
lambda t: t[1] == 'method')
|
lambda t: t[1] == 'method')
|
||||||
attrs = spill("Class methods %s:\n" % tag, attrs,
|
attrs = spill("* Class methods %s:\n" % tag, attrs,
|
||||||
lambda t: t[1] == 'class method')
|
lambda t: t[1] == 'class method')
|
||||||
attrs = spill("Static methods %s:\n" % tag, attrs,
|
attrs = spill("* Static methods %s:\n" % tag, attrs,
|
||||||
lambda t: t[1] == 'static method')
|
lambda t: t[1] == 'static method')
|
||||||
attrs = spillproperties("Properties %s:\n" % tag, attrs)
|
attrs = spillproperties("* Properties %s:\n" % tag, attrs,
|
||||||
attrs = spilldata("Data %s:\n" % tag, attrs)
|
lambda t: t[1] == 'property')
|
||||||
|
attrs = spilldata("* Data %s:\n" % tag, attrs,
|
||||||
|
lambda t: t[1] == 'data')
|
||||||
assert attrs == []
|
assert attrs == []
|
||||||
|
|
||||||
# Split off the attributes inherited from the next class (note
|
# Split off the attributes inherited from the next class (note
|
||||||
|
@ -1037,8 +1057,6 @@ def spilldata(msg, attrs):
|
||||||
if inherited:
|
if inherited:
|
||||||
attrs = inherited
|
attrs = inherited
|
||||||
thisclass = attrs[0][2]
|
thisclass = attrs[0][2]
|
||||||
attrs, inherited = _split_class_attrs(attrs,
|
|
||||||
lambda t: t[2] is thisclass)
|
|
||||||
|
|
||||||
contents = '\n'.join(contents)
|
contents = '\n'.join(contents)
|
||||||
if not contents:
|
if not contents:
|
||||||
|
|
Loading…
Reference in New Issue