Patch #936774: unify the display of data descriptors, including slots,

properties, and custom descriptors.

* removed special handling of properties

* added special handling of data descriptors - All data descriptors are grouped
  together in a section. For each item, the attribute name and doc string, if
  present, is displayed.

* disabled display of __slots__ attribute - since slots are descriptors, they
  are listed in the section described above

Thanks to John Belmonte for the patch!
This commit is contained in:
Johannes Gijsbers 2005-01-08 20:16:43 +00:00
parent 9a98364ba3
commit 9ddb300598
1 changed files with 27 additions and 37 deletions

View File

@ -154,7 +154,7 @@ def visiblename(name, all=None):
"""Decide whether to show documentation on a variable.""" """Decide whether to show documentation on a variable."""
# Certain special names are redundant. # Certain special names are redundant.
if name in ['__builtins__', '__doc__', '__file__', '__path__', if name in ['__builtins__', '__doc__', '__file__', '__path__',
'__module__', '__name__']: return 0 '__module__', '__name__', '__slots__']: return 0
# Private names are hidden, but special names are displayed. # Private names are hidden, but special names are displayed.
if name.startswith('__') and name.endswith('__'): return 1 if name.startswith('__') and name.endswith('__'): return 1
if all is not None: if all is not None:
@ -163,6 +163,14 @@ def visiblename(name, all=None):
else: else:
return not name.startswith('_') return not name.startswith('_')
def classify_class_attrs(object):
"""Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
def fixup((name, kind, cls, value)):
if inspect.isdatadescriptor(value):
kind = 'data descriptor'
return name, kind, cls, value
return map(fixup, inspect.classify_class_attrs(object))
# ----------------------------------------------------- module manipulation # ----------------------------------------------------- module manipulation
def ispackage(path): def ispackage(path):
@ -718,13 +726,13 @@ class HTMLDoc(Doc):
push('\n') push('\n')
return attrs return attrs
def spillproperties(msg, attrs, predicate): def spilldescriptors(msg, attrs, predicate):
ok, attrs = _split_list(attrs, predicate) ok, attrs = _split_list(attrs, predicate)
if ok: if ok:
hr.maybe() hr.maybe()
push(msg) push(msg)
for name, kind, homecls, value in ok: for name, kind, homecls, value in ok:
push(self._docproperty(name, value, mod)) push(self._docdescriptor(name, value, mod))
return attrs return attrs
def spilldata(msg, attrs, predicate): def spilldata(msg, attrs, predicate):
@ -749,7 +757,7 @@ class HTMLDoc(Doc):
return attrs return attrs
attrs = filter(lambda (name, kind, cls, value): visiblename(name), attrs = filter(lambda (name, kind, cls, value): visiblename(name),
inspect.classify_class_attrs(object)) classify_class_attrs(object))
mdict = {} mdict = {}
for key, kind, homecls, value in attrs: for key, kind, homecls, value in attrs:
mdict[key] = anchor = '#' + name + '-' + key mdict[key] = anchor = '#' + name + '-' + key
@ -788,8 +796,8 @@ class HTMLDoc(Doc):
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 = spilldescriptors('Data descriptors %s' % tag, attrs,
lambda t: t[1] == 'property') lambda t: t[1] == 'data descriptor')
attrs = spilldata('Data and other attributes %s' % tag, attrs, attrs = spilldata('Data and other attributes %s' % tag, attrs,
lambda t: t[1] == 'data') lambda t: t[1] == 'data')
assert attrs == [] assert attrs == []
@ -871,7 +879,7 @@ class HTMLDoc(Doc):
doc = doc and '<dd><tt>%s</tt></dd>' % doc doc = doc and '<dd><tt>%s</tt></dd>' % doc
return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc) return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
def _docproperty(self, name, value, mod): def _docdescriptor(self, name, value, mod):
results = [] results = []
push = results.append push = results.append
@ -880,20 +888,13 @@ class HTMLDoc(Doc):
if value.__doc__ is not None: if value.__doc__ is not None:
doc = self.markup(value.__doc__, self.preformat) doc = self.markup(value.__doc__, self.preformat)
push('<dd><tt>%s</tt></dd>\n' % doc) push('<dd><tt>%s</tt></dd>\n' % doc)
for attr, tag in [('fget', '<em>get</em>'),
('fset', '<em>set</em>'),
('fdel', '<em>delete</em>')]:
func = getattr(value, attr)
if func is not None:
base = self.document(func, tag, mod)
push('<dd>%s</dd>\n' % base)
push('</dl>\n') push('</dl>\n')
return ''.join(results) return ''.join(results)
def docproperty(self, object, name=None, mod=None, cl=None): def docproperty(self, object, name=None, mod=None, cl=None):
"""Produce html documentation for a property.""" """Produce html documentation for a property."""
return self._docproperty(name, object, mod) return self._docdescriptor(name, object, mod)
def docother(self, object, name=None, mod=None, *ignored): def docother(self, object, name=None, mod=None, *ignored):
"""Produce HTML documentation for a data object.""" """Produce HTML documentation for a data object."""
@ -1143,13 +1144,13 @@ class TextDoc(Doc):
name, mod, object)) name, mod, object))
return attrs return attrs
def spillproperties(msg, attrs, predicate): def spilldescriptors(msg, attrs, predicate):
ok, attrs = _split_list(attrs, predicate) ok, attrs = _split_list(attrs, predicate)
if ok: if ok:
hr.maybe() hr.maybe()
push(msg) push(msg)
for name, kind, homecls, value in ok: for name, kind, homecls, value in ok:
push(self._docproperty(name, value, mod)) push(self._docdescriptor(name, value, mod))
return attrs return attrs
def spilldata(msg, attrs, predicate): def spilldata(msg, attrs, predicate):
@ -1167,7 +1168,7 @@ class TextDoc(Doc):
return attrs return attrs
attrs = filter(lambda (name, kind, cls, value): visiblename(name), attrs = filter(lambda (name, kind, cls, value): visiblename(name),
inspect.classify_class_attrs(object)) classify_class_attrs(object))
while attrs: while attrs:
if mro: if mro:
thisclass = mro.popleft() thisclass = mro.popleft()
@ -1195,8 +1196,8 @@ class TextDoc(Doc):
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 = spilldescriptors("Data descriptors %s:\n" % tag, attrs,
lambda t: t[1] == 'property') lambda t: t[1] == 'data descriptor')
attrs = spilldata("Data and other attributes %s:\n" % tag, attrs, attrs = spilldata("Data and other attributes %s:\n" % tag, attrs,
lambda t: t[1] == 'data') lambda t: t[1] == 'data')
assert attrs == [] assert attrs == []
@ -1254,33 +1255,22 @@ class TextDoc(Doc):
doc = getdoc(object) or '' doc = getdoc(object) or ''
return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n') return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n')
def _docproperty(self, name, value, mod): def _docdescriptor(self, name, value, mod):
results = [] results = []
push = results.append push = results.append
if name: if name:
push(name) push(self.bold(name))
need_blank_after_doc = 0 push('\n')
doc = getdoc(value) or '' doc = getdoc(value) or ''
if doc: if doc:
push(self.indent(doc)) push(self.indent(doc))
need_blank_after_doc = 1 push('\n')
for attr, tag in [('fget', '<get>'), return ''.join(results)
('fset', '<set>'),
('fdel', '<delete>')]:
func = getattr(value, attr)
if func is not None:
if need_blank_after_doc:
push('')
need_blank_after_doc = 0
base = self.document(func, tag, mod)
push(self.indent(base))
return '\n'.join(results)
def docproperty(self, object, name=None, mod=None, cl=None): def docproperty(self, object, name=None, mod=None, cl=None):
"""Produce text documentation for a property.""" """Produce text documentation for a property."""
return self._docproperty(name, object, mod) return self._docdescriptor(name, object, mod)
def docother(self, object, name=None, mod=None, maxlen=None, doc=None): def docother(self, object, name=None, mod=None, maxlen=None, doc=None):
"""Produce text documentation for a data object.""" """Produce text documentation for a data object."""