def get_cls_methods(object, name_prefix=''): """ return [{ name:, doc:, argspec:, flag:, is_property:, }] """ def make_obj(name, kind, cls, value, val): is_property = isinstance(val, property) return dict( name=name_prefix + name, doc=pydoc.getdoc(val), argspec=get_fn_argspec(val), flag='P' if is_property else get_method_flag(kind), is_property=is_property ) # (name, kind, cls, value) methods = [] for name, kind, cls, value in pydoc.classify_class_attrs(object): if cls is object and kind.endswith('method') and not name.startswith('_'): val = getattr(cls, name) if isinstance(val, models.Manager): if val.__class__ is not models.Manager: methods.extend(get_cls_methods(val.__class__, name_prefix='{}.'.format(name))) else: methods.append(make_obj(name, kind, cls, value, val)) return methods
def get_cls_methods(object, name_prefix=''): """ return [{ name:, doc:, argspec:, flag:, is_property:, }] """ def make_obj(name, kind, cls, value, val): is_property = isinstance(val, property) return dict(name=name_prefix + name, doc=pydoc.getdoc(val), argspec=get_fn_argspec(val), flag='P' if is_property else get_method_flag(kind), is_property=is_property) # (name, kind, cls, value) methods = [] for name, kind, cls, value in pydoc.classify_class_attrs(object): if cls is object and kind.endswith( 'method') and not name.startswith('_'): val = getattr(cls, name) if isinstance(val, models.Manager): if val.__class__ is not models.Manager: methods.extend( get_cls_methods(val.__class__, name_prefix='{}.'.format(name))) else: methods.append(make_obj(name, kind, cls, value, val)) return methods
def shape_text(this_cls, doc=pydoc.plaintext): attrs = [(name, kind) for name, kind, cls, _ in pydoc.classify_class_attrs(this_cls) if cls == this_cls] attrs = [(name, kind) for name, kind in attrs if not (name.startswith("__") and name.endswith("__"))] method_names = [name for name, kind in attrs if kind == "method"] content = doc.indent("".join( [doc.document(getattr(this_cls, name)) for name in method_names])) mro = " <- ".join([cls.__name__ for cls in this_cls.mro()]) return "\n".join([mro, content])
def shape_text(this_cls, doc=pydoc.plaintext): attrs = [ (name, kind) for name, kind, cls, _ in pydoc.classify_class_attrs(this_cls) if cls == this_cls ] attrs = [ (name, kind) for name, kind in attrs if not (name.startswith("__") and name.endswith("__")) ] method_names = [name for name, kind in attrs if kind == "method"] content = doc.indent("".join([doc.document(getattr(this_cls, name)) for name in method_names])) mro = " <- ".join([cls.__name__ for cls in this_cls.mro()]) return "\n".join([mro, content])
def shape_text(this_cls, doc=pydoc.plaintext): attrs = [ (name, kind) for name, kind, cls, _ in pydoc.classify_class_attrs(this_cls) if cls == this_cls ] attrs = [ (name, kind) for name, kind in attrs if not (name.startswith("__") and name.endswith("__")) ] attrs = [(name, kind) for name, kind in attrs if not name.startswith("_")] method_names = [name for name, kind in attrs if kind == "method"] method_annotations = [ "@OVERRIDE: " if any(c for c in this_cls.mro()[1:] if hasattr(c, name)) else "" for name in method_names ] method_docs = [ prefix + doc.document(getattr(this_cls, name)) for prefix, name in zip(method_annotations, method_names) ] content = doc.indent("".join(method_docs)) mro = " <- ".join([cls.__name__ for cls in this_cls.mro()]) return "\n".join([mro, content])
def docclass(self, cls, name=None, mod=None): """Produce text documentation for the class object cls.""" # the overall document, as a line-delimited list document = [] # get the object's actual name, defaulting to the passed in name name = name or cls.__name__ # get the object's bases bases = cls.__bases__ # get the object's module mod = cls.__module__ # get the object's MRO mro = [pydoc.classname(base, mod) for base in inspect.getmro(cls)] # get the object's classname, which should be printed classtitle = self.process_class_name(name, bases, mod) document.append(classtitle) document.append(self.underline) # get the object's docstring, which should be printed docstring = self.process_docstring(cls) document.append(docstring) # get all the attributes of the class attrs = [] for name, kind, classname, value in pydoc.classify_class_attrs(cls): if pydoc.visiblename(name): attrs.append((name, kind, classname, value)) # sort them into categories data, descriptors, methods = [], [], [] for attr in attrs: if attr[1] == "data" and not attr[0].startswith("_"): data.append(attr) elif attr[1] == "data descriptor" and not attr[0].startswith("_"): descriptors.append(attr) elif "method" in attr[1] and not attr[2] is builtins.object: methods.append(attr) if data: # start the data section document.append(self.process_subsection(self.bold("data"))) document.append(self.underline) # process your attributes for name, kind, classname, value in data: if hasattr(value, '__call__') or inspect.isdatadescriptor(value): doc = getdoc(value) else: doc = None document.append(self.docother(getattr(cls, name), name, mod, maxlen=70, doc=doc) + '\n') if descriptors: # start the descriptors section document.append(self.process_subsection(self.bold("descriptors"))) document.append(self.underline) # process your descriptors for name, kind, classname, value in descriptors: document.append(self._docdescriptor(name, value, mod)) if methods: # start the methods section document.append(self.process_subsection(self.bold("methods"))) document.append(self.underline) # process your methods for name, kind, classname, value in methods: document.append(self.document(getattr(cls, name), name, mod, cls)) return "\n".join(document)
def docclass(self, cls, name=None, mod=None): """Produce text documentation for the class object cls.""" # the overall document, as a line-delimited list document = [] # get the object's actual name, defaulting to the passed in name name = name or cls.__name__ # get the object's bases bases = cls.__bases__ # get the object's module mod = cls.__module__ # get the object's MRO mro = [pydoc.classname(base, mod) for base in inspect.getmro(cls)] # get the object's classname, which should be printed classtitle = self.process_class_name(name, bases, mod) document.append(classtitle) document.append(self.underline) # get the object's docstring, which should be printed docstring = self.process_docstring(cls) document.append(docstring) # get all the attributes of the class attrs = [] for name, kind, classname, value in pydoc.classify_class_attrs(cls): if pydoc.visiblename(name): attrs.append((name, kind, classname, value)) # sort them into categories data, descriptors, methods = [], [], [] for attr in attrs: if attr[1] == "data" and not attr[0].startswith("_"): data.append(attr) elif attr[1] == "data descriptor" and not attr[0].startswith("_"): descriptors.append(attr) elif "method" in attr[1] and not attr[2] is builtins.object: methods.append(attr) if data: # start the data section document.append(self.process_subsection(self.bold("data"))) document.append(self.underline) # process your attributes for name, kind, classname, value in data: if hasattr(value, '__call__') or inspect.isdatadescriptor(value): doc = getdoc(value) else: doc = None document.append( self.docother( getattr(cls, name), name, mod, maxlen=70, doc=doc) + '\n') if descriptors: # start the descriptors section document.append(self.process_subsection(self.bold("descriptors"))) document.append(self.underline) # process your descriptors for name, kind, classname, value in descriptors: document.append(self._docdescriptor(name, value, mod)) if methods: # start the methods section document.append(self.process_subsection(self.bold("methods"))) document.append(self.underline) # process your methods for name, kind, classname, value in methods: document.append( self.document(getattr(cls, name), name, mod, cls)) return "\n".join(document)
def docclass(self, object, name=None, mod=None, *ignored): """Produce Markdown documentation for a given class object.""" realname = object.__name__ name = name or realname bases = object.__bases__ def makename(c, m=object.__module__): return pydoc.classname(c, m) if name == realname: title = 'class ' + realname else: title = name + ' = class ' + realname if bases: parents = map(makename, bases) title = title + '(%s)' % ', '.join(parents) title = self.header(title, self.hlevel, name, 'class') self.hlevel += 1 doc = pydoc.getdoc(object) contents = doc and [doc + '\n'] or [] push = contents.append # List the mro, if non-trivial. mro = pydoc.deque(inspect.getmro(object)) if len(mro) > 2: push("Method resolution order:\n") for base in mro: push('* ' + makename(base)) push('') # 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('-' * 70 + '\n') self.needone = 1 hr = HorizontalRule() def spill(msg, attrs, predicate): ok, attrs = pydoc._split_list(attrs, predicate) if ok: hr.maybe() push(msg) for name, kind, homecls, value in ok: try: value = getattr(object, name) except Exception: # Some descriptors may meet a failure in their __get__. # (bug #1785) push(self._docdescriptor(name, value, mod)) else: push(self.document(value, name, mod, object)) return attrs def spilldescriptors(msg, attrs, predicate): ok, attrs = pydoc._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 = pydoc._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 = pydoc.getdoc(value) else: doc = None push( self.docother(getattr(object, name), name, mod, maxlen=70, doc=doc) + '\n') return attrs attrs = filter(lambda data: pydoc.visiblename(data[0], obj=object), pydoc.classify_class_attrs(object)) while attrs: if mro: thisclass = mro.popleft() else: thisclass = attrs[0][2] attrs, inherited = pydoc._split_list(attrs, lambda t: t[2] is thisclass) if thisclass is pydoc.__builtin__.object: attrs = inherited continue elif thisclass is object: tag = "defined here" else: tag = "inherited from %s" % pydoc.classname( thisclass, object.__module__) # Sort attrs by name. attrs.sort() # Pump out the attrs, segregated by kind. 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 self.hlevel -= 1 contents = '\n'.join(contents) if not contents: return title return title + contents.rstrip() + '\n'
def docclass(self, object, name=None, mod=None, *ignored): """Produce text documentation for a given class object.""" 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) title += ':' contents = [] push = contents.append doc = getdoc(object) if doc: push(f'"""\n{doc}\n"""') # List the mro, if non-trivial. mro = deque(inspect.getmro(object)) if len(mro) > 2: push("\n## Method resolution order:") for i, base in enumerate(mro, 1): push(f'# {i}) ' + makename(base)) push('') # 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('# ' + '-' * 68) 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: try: value = getattr(object, name) except Exception: # Some descriptors may meet a failure in their __get__. # (bug #1785) push(self._docdescriptor(name, value, mod)) else: push(self.document(value, 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 callable(value) or inspect.isdatadescriptor(value): doc = getdoc(value) else: doc = None try: obj = getattr(object, name) except AttributeError: obj = homecls.__dict__[name] push( self.docother(obj, name, mod, maxlen=70, doc=doc) + '\n') return attrs attrs = [(name, kind, cls, value) for name, kind, cls, value in classify_class_attrs(object) if visiblename(name, obj=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 builtins.object: attrs = inherited continue elif thisclass is object: tag = "defined here" else: tag = "inherited from %s" % classname(thisclass, object.__module__) sort_attributes(attrs, object) # Pump out the attrs, segregated by kind. 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) or 'pass' return '\n' + title + '\n' + self.indent(contents.rstrip(), ' ') + '\n'
def docclass(self, cls, name=None, mod=None): """Produce markdown documentation for the class obj cls.""" # the overall document, as a line-delimited list document = [] # get the obj's actual name, defaulting to the passed in name name = name or cls.__name__ # get the obj's bases bases = cls.__bases__ # get the obj's module mod = cls.__module__ # get the obj's classname, which should be printed classtitle = self.process_class_name(name, bases, mod) document.append(classtitle) # get the obj's docstring, which should be printed docstring = self.process_docstring(cls) document.append(self.process_subsection("description")) document.append(self.underline) document.append(docstring) # get all the attributes of the class attrs = [] for name, kind, classname, value in pydoc.classify_class_attrs(cls): if pydoc.visiblename(name): if kind is not __builtin__.object: if classname == cls: obj = (name, kind, classname, value) attrs.append(obj) # sort them into categories data = [attr for attr in attrs if attr[1] == "data"] descriptors = [attr for attr in attrs if attr[1] == "data descriptor"] methods = [attr for attr in attrs if "method" in attr[1]] # start the data section if data: document.append(self.process_subsection("data")) document.append(self.underline) # process your attributes for name, kind, classname, value in data: document.append(self.document(getattr(cls, name), name, mod, cls)) # start the descriptors section if descriptors: document.append(self.process_subsection("descriptors")) document.append(self.underline) # process your descriptors for _ in descriptors: document.append(self._docdescriptor(name, value, mod)) # start the methods section if methods: document.append(self.process_subsection("methods")) document.append(self.underline) # process your methods for f in methods: if not f[0].startswith("__"): document.append(self.docroutine(f[-1])) return "\n".join(document).replace('\n', '\n> ')
def __get_clazz_attributes(cls, clazz) -> list: return [(name, kind, clz, value) for name, kind, clz, value in pydoc.classify_class_attrs(clazz) if DLibraryDoc.__show_clazz_attribute(clazz, name, clz)]
def update_event(self, inp=-1): self.set_output_val(0, pydoc.classify_class_attrs(self.input(0)))
def docclass(self, cls, name=None, mod=None): """Produce text documentation for the class object cls.""" # the overall document, as a line-delimited list document = [] # get the object's actual name, defaulting to the passed in name name = name or cls.__name__ # get the object's bases bases = cls.__bases__ # get the object's module mod = cls.__module__ # get the object's MRO mro = [pydoc.classname(base, mod) for base in inspect.getmro(cls)] # get the object's classname, which should be printed classtitle = self.process_class_name(name, bases, mod) document.append(classtitle) document.append(self.underline) # get the object's docstring, which should be printed docstring = self.process_docstring(cls) document.append(docstring) # get all the attributes of the class attrs = [] for name, kind, classname, value in pydoc.classify_class_attrs(cls): if pydoc.visiblename(name): #if kind is not builtins.object: if classname == cls: obj = (name, kind, classname, value) attrs.append(obj) # sort them into categories data = [attr for attr in attrs if attr[1] == "data"] descriptors = [attr for attr in attrs if attr[1] == "data descriptor"] methods = [attr for attr in attrs if "method" in attr[1]] # start the data section document.append(self.process_subsection("data")) document.append(self.underline) # process your attributes for name, kind, classname, value in data: document.append(self.document(getattr(cls, name), name, mod, cls)) # start the descriptors section document.append(self.process_subsection("descriptors")) document.append(self.underline) # process your descriptors for desc in descriptors: document.append(self._docdescriptor(name, value, mod)) # start the methods section document.append(self.process_subsection("methods")) document.append(self.underline) # process your methods for f in methods: if not f[0].startswith("__"): document.append(self.docroutine(f[-1])) return "\n".join(document)
def docclass(self, object, name=None, mod=None, *ignored): """Produce text documentation for a given class object.""" 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) contents = [] push = contents.append try: signature = inspect.signature(object) except (ValueError, TypeError): signature = None if signature: argspec = str(signature) if argspec and argspec != '()': push(name + argspec) doc = getdoc(object) if doc: push(self.indent(doc.splitlines()[0])) # List the mro, if non-trivial. mro = deque(inspect.getmro(object)) if len(mro) > 2: push("Method resolution order:") for base in mro: push(' ' + makename(base)) # List the built-in subclasses, if any: subclasses = sorted((str(cls.__name__) for cls in type.__subclasses__(object) if not cls.__name__.startswith("_") and cls.__module__ == "builtins"), key=str.lower) no_of_subclasses = len(subclasses) MAX_SUBCLASSES_TO_DISPLAY = 4 if subclasses: push("Built-in subclasses:") for subclassname in subclasses[:MAX_SUBCLASSES_TO_DISPLAY]: push(' ' + subclassname) if no_of_subclasses > MAX_SUBCLASSES_TO_DISPLAY: push(' ... and ' + str(no_of_subclasses - MAX_SUBCLASSES_TO_DISPLAY) + ' other subclasses') push('') def header(msg): push(f"\n{msg}\n" + ("-" * len(msg))) def spill(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) if ok: header(msg) for name, kind, homecls, value in ok: try: value = getattr(object, name) except Exception: # Some descriptors may meet a failure in their __get__. # (bug #1785) push(self.docdata(value, name, mod)) else: push(self.document(value, name, mod, object)) return attrs def spilldescriptors(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) if ok: header(msg) for name, kind, homecls, value in ok: push(self.docdata(value, name, mod)) return attrs def spilldata(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) if ok: header(msg) for name, kind, homecls, value in ok: if callable(value) or inspect.isdatadescriptor(value): doc = getdoc(value) else: doc = None try: obj = getattr(object, name) except AttributeError: obj = homecls.__dict__[name] push(self.docother(obj, name, mod, maxlen=70, doc=doc)) return attrs attrs = [(name, kind, cls, value) for name, kind, cls, value in classify_class_attrs(object) if visiblename(name, obj=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 object is not builtins.object and thisclass is builtins.object: attrs = inherited continue elif thisclass is object: tag = "defined here" else: tag = "inherited from %s" % classname(thisclass, object.__module__) sort_attributes(attrs, object) # 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 = spilldescriptors("Readonly properties %s" % tag, attrs, lambda t: t[1] == 'readonly property') attrs = spilldescriptors("Data descriptors %s" % tag, attrs, lambda t: t[1] == 'data descriptor') attrs = spilldata("Data and other attributes %s" % 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(contents.rstrip(), ' | ') + '\n'
def get_attrs(obj): all_attrs = filter(lambda data: pydoc.visiblename(data[0], obj=obj), pydoc.classify_class_attrs(obj)) return filter(lambda data: data[2] == obj, all_attrs)
def docclass(self, object, name=None, mod=None, funcs={}, classes={}, *ignored): """Produce HTML documentation for a class object.""" level = 2 # FIXME: use passed level in the future realname = object.__name__ name = name or realname bases = object.__bases__ doc = self.getdoc(object) components = {} def spill(msg, attrs, predicate): # `ok` are attributes to handle, `attrs` is what's left ok, attrs = pydoc._split_list(attrs, predicate) if ok: result = msg for name, kind, homecls, value in ok: try: value = getattr(object, name) except Exception: # Some descriptors may meet a failure in their __get__. # (bug #1785) result += self._docdescriptor(name, value, mod) else: result += self.document(value, name, mod, funcs, classes, mdict, object) # NOTE: this is that important side-effect you're looking for! components['docs'].append(result) return attrs def spilldescriptors(msg, attrs, predicate): # `ok` are attributes to handle, `attrs` is what's left ok, attrs = pydoc._split_list(attrs, predicate) if ok: result = msg for name, kind, homecls, value in ok: result += self._docdescriptor(name, value, mod) # NOTE: this is that important side-effect you're looking for! components['docs'].append(result) return attrs def spilldata(msg, attrs, predicate): # `ok` are attributes to handle, `attrs` is what's left ok, attrs = pydoc._split_list(attrs, predicate) if ok: result = msg for name, kind, homecls, value in ok: base = self.docother(getattr(object, name), name, mod) if (hasattr(value, '__call__') or inspect.isdatadescriptor(value)): doc = getattr(value, "__doc__", None) else: doc = None if doc is None: result += '<dl><dt>%s</dt></dl>\n' % base else: doc = self.markup(self.getdoc(value), self.preformat, funcs, classes, mdict) doc = '<dd>%s</dd>' % doc result += '<dl><dt>%s%s</dl>\n' % (base, doc) # NOTE: this is that important side-effect you're looking for! components['docs'].append(result) return attrs mro = collections.deque(inspect.getmro(object)) if len(mro) > 2: components[ 'mro'] = '<dl class="mro"><dt>Method resolution order:</dt>' for base in mro: components['mro'] += '<dd>%s</dd>' % self.classlink( base, object.__module__) components['mro'] += '</dl>' attrs = filter(lambda data: pydoc.visiblename(data[0], obj=object), pydoc.classify_class_attrs(object)) mdict = {} for key, kind, homecls, value in attrs: mdict[key] = anchor = '#' + name + '-' + key try: value = getattr(object, name) except Exception: # Some descriptors may meet a failure in their __get__. # (bug #1785) pass try: # The value may not be hashable (e.g., a data attr with # a dict or list value). mdict[value] = anchor except TypeError: pass components['docs'] = [] # populated in spill* functions while attrs: if mro: thisclass = mro.popleft() else: thisclass = attrs[0][2] attrs, inherited = pydoc._split_list(attrs, lambda t: t[2] is thisclass) # if thisclass is __builtin__.object: # 2.7 only, no clue why it wasn't just `object` in the first place. if thisclass is __builtin__.object: attrs = inherited continue elif thisclass is object: tag = '' else: tag = 'from %s' % self.classlink(thisclass, object.__module__) # Sort attrs by name. try: attrs.sort(key=lambda t: t[0]) except TypeError: attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) # 2.3 compat attrs = spill('<h4 class="head-methods">Methods %s</h4>' % tag, attrs, lambda t: t[1] == 'method') attrs = spill( '<h4 class="head-class-methods">Class methods %s</h4>' % tag, attrs, lambda t: t[1] == 'class method') attrs = spill( '<h4 class="head-static-methods">Static methods %s</h4>' % tag, attrs, lambda t: t[1] == 'static method') attrs = spilldescriptors( '<h4 class="head-desc">Descriptors %s</h4>' % tag, attrs, lambda t: t[1] == 'data descriptor') attrs = spilldata( '<h4 class="head-attrs">Attributes %s</h4>' % tag, attrs, lambda t: t[1] == 'data') assert attrs == [] attrs = inherited if name == realname: title = '<a name="%s" href="#%s">class <span class="class-name">%s</span></a>' % ( name, name, realname) else: title = '<span class="class-name">%s</span> = <a name="%s" href="#%s">class %s</a>' % ( name, name, name, realname) if bases: parents = [] for base in bases: parents.append(self.classlink(base, object.__module__)) title = title + '(%s)' % ', '.join(parents) result = '<dt class="class">%s</dt>' % self.heading(level, title) result += '<dd class="class">' result += '<dd>\n%s\n</dd>' % doc if 'mro' in components: result += ' <div class="mro">%(mro)s</div>' % components result += '\n '.join(components['docs']) result += '</dd>' return result
def docclass(self, object, name=None, mod=None, funcs={}, classes={}, *ignored): """Produce HTML documentation for a class object.""" realname = object.__name__ name = name or realname bases = object.__bases__ contents = [] 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() # List the mro, if non-trivial. mro = deque(inspect.getmro(object)) if len(mro) > 2: hr.maybe() push('<dl><dt>Method resolution order:</dt>\n') for base in mro: push('<dd>%s</dd>\n' % self.classlink(base, object.__module__)) push('</dl>\n') def spill(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) if ok: hr.maybe() push(msg) for name, kind, homecls, value in ok: try: value = getattr(object, name) except Exception: # Some descriptors may meet a failure # in their __get__. # (bug aroberge/mod_pydoc#1785) push(self._docdescriptor(name, value, mod)) else: push( self.document(value, name, mod, funcs, classes, mdict, object)) push('\n') 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: base = self.docother(getattr(object, name), name, mod) if callable(value) or inspect.isdatadescriptor(value): doc = getattr(value, "__doc__", None) else: doc = None if doc is None: push('<dl><dt>%s</dt><dd></dd></dl>\n' % base) else: doc = self.markup(getdoc(value), self.preformat, funcs, classes, mdict) doc = '<dd><code>%s</code></dd>' % doc push('<dl><dt>%s%s</dt></dl>\n' % (base, doc)) push('\n') return attrs attrs = [(name, kind, cls, value) for name, kind, cls, value in classify_class_attrs(object) if visiblename(name, obj=object)] mdict = {} for key, kind, homecls, value in attrs: mdict[key] = anchor = '#' + name + '-' + key try: value = getattr(object, name) except Exception: # Some descriptors may meet a failure in their __get__. # (bug #1785) pass try: # The value may not be hashable (e.g., a data attr with # a dict or list value). mdict[value] = anchor except TypeError: pass 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 builtins.object: attrs = inherited continue elif thisclass is object: tag = 'defined here' else: tag = 'inherited from %s' % self.classlink( thisclass, object.__module__) tag += ':<br>\n' # Sort attrs by name. attrs.sort(key=lambda t: t[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 = spilldescriptors('Data descriptors %s' % tag, attrs, lambda t: t[1] == 'data descriptor') attrs = spilldata('Data and other attributes %s' % tag, attrs, lambda t: t[1] == 'data') assert attrs == [] attrs = inherited contents = ''.join(contents) if name == realname: title = '<span id="%s" class="signature"> class %s</span>' % ( name, realname) else: title = ( '%s = <span id="%s" class="signature">class %s</span>' % (name, name, realname)) if bases: parents = [] for base in bases: parents.append(self.classlink(base, object.__module__)) title = title + '(%s)' % ', '.join(parents) doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict) doc = doc and '<code>%s<br> </code>' % doc return self.html_section(title, contents, 3, doc, css_class="docclass")