'Produce text documentation for a given class object.'

def docclass(self, object, name=None, mod=None, *ignored):

    realname = object.__name__
    name = (name or realname)
    bases = object.__bases__
    def makename(c, m=object.__module__):
        return classname(c, m)
    if (name == realname):
        title = ('class    ' + self.bold(realname))
    else:
        title = ((self.bold(name) + '    =    class    ') + realname)
    if bases:
        parents = map(makename, bases)
        title = (title + ('(%s)' % join(parents, ',    ')))
    doc = getdoc(object)
    contents = ((doc and [(doc + '\n')]) or [])
    push = contents.append
    mro = deque(inspect.getmro(object))
    if (len(mro) > 2):
        push('Method    resolution    order:')
        for base in mro:
            push(('                ' + makename(base)))
        push('')
    class HorizontalRule:
        def __init__(self):
            self.needone = 0
        def maybe(self):
            if self.needone:
                push(('-' * 70))
            self.needone = 1
    hr = HorizontalRule()
    def spill(msg, attrs, predicate):
        (ok, attrs) = _split_list(attrs, predicate)
        if ok:
            hr.maybe()
            push(msg)
            for (name, kind, homecls, value) in ok:
                push(self.document(getattr(object, name), name, mod, object))
        return attrs
    def spilldescriptors(msg, attrs, predicate):
        (ok, attrs) = _split_list(attrs, predicate)
        if ok:
            hr.maybe()
            push(msg)
            for (name, kind, homecls, value) in ok:
                push(self._docdescriptor(name, value, mod))
        return attrs
    def spilldata(msg, attrs, predicate):
        (ok, attrs) = _split_list(attrs, predicate)
        if ok:
            hr.maybe()
            push(msg)
            for (name, kind, homecls, value) in ok:
                if (hasattr(value, '__call__') or inspect.isdatadescriptor(value)):
                    doc = getdoc(value)
                else:
                    doc = None
                push((self.docother(getattr(object, name), name, mod, maxlen=70, doc=doc) + '\n'))
        return attrs
    attrs = filter((lambda data: visiblename(data[0], obj=object)), classify_class_attrs(object))
    while attrs:
        if mro:
            thisclass = mro.popleft()
        else:
            thisclass = attrs[0][2]
        (attrs, inherited) = _split_list(attrs, (lambda t: (t[2] is thisclass)))
        if (thisclass is __builtin__.object):
            attrs = inherited
            continue
        elif (thisclass is object):
            tag = 'defined    here'
        else:
            tag = ('inherited    from    %s' % classname(thisclass, object.__module__))
        attrs.sort()
        attrs = spill(('Methods    %s:\n' % tag), attrs, (lambda t: (t[1] == 'method')))
        attrs = spill(('Class    methods    %s:\n' % tag), attrs, (lambda t: (t[1] == 'class    method')))
        attrs = spill(('Static    methods    %s:\n' % tag), attrs, (lambda t: (t[1] == 'static    method')))
        attrs = spilldescriptors(('Data    descriptors    %s:\n' % tag), attrs, (lambda t: (t[1] == 'data    descriptor')))
        attrs = spilldata(('Data    and    other    attributes    %s:\n' % tag), attrs, (lambda t: (t[1] == 'data')))
        assert (attrs == [])
        attrs = inherited
    contents = '\n'.join(contents)
    if (not contents):
        return (title + '\n')
    return (((title + '\n') + self.indent(rstrip(contents), '    |        ')) + '\n')
