def indent( self, text, prefix=' ' ): """Indent text by prepending a given prefix to each line.""" if not text: return '' lines = split( text, '\n' ) lines = map( lambda line, prefix=prefix: prefix + line, lines ) if lines: lines[-1] = rstrip( lines[-1] ) return join( lines, '\n' )
def strongarm(self, obj, name=None, mod=None, funcs={}, classes={}, *ignored): """Produce HTML documentation for a class object.""" realname = obj.__name__ name = name or realname bases = obj.__bases__ obj, name = pydoc.resolve(obj, forceload) contents = [] push = contents.append if name == realname: title = '<a name="%s">class <strong>%s</strong></a>' % (name, realname) else: title = '<strong>%s</strong> = <a name="%s">class %s</a>' % ( name, name, realname) mdict = {} if bases: parents = [] for base in bases: parents.append(self.classlink(base, obj.__module__)) title = title + '(%s)' % pydoc.join(parents, ', ') doc = self.markup(pydoc.getdoc(obj), self.preformat, funcs, classes, mdict) doc = doc and '<tt>%s<br> </tt>' % doc for iname, _ in cdict[name]: fname = fdict[(name, iname)] if iname in elements_dict: push('class <a href="%s">%s</a>: element declaration typecode<br/>'\ %(fname,iname)) pyclass = elements_dict[iname] if pyclass is not None: push('<ul>instance attributes:') push('<li><a href="%s">pyclass</a>: instances serializable to XML<br/></li>'\ %elements_dict[iname]) push('</ul>') elif iname in types_dict: push('class <a href="%s">%s</a>: type definition typecode<br/>' % (fname, iname)) pyclass = types_dict[iname] if pyclass is not None: push('<ul>instance attributes:') push('<li><a href="%s">pyclass</a>: instances serializable to XML<br/></li>'\ %types_dict[iname]) push('</ul>') else: push( 'class <a href="%s">%s</a>: TODO not sure what this is<br/>' % (fname, iname)) contents = ''.join(contents) return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)
def strongarm(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__ object, name = pydoc.resolve(object, forceload) contents = [] push = contents.append if name == realname: title = '<a name="%s">class <strong>%s</strong></a>' % ( name, realname) else: title = '<strong>%s</strong> = <a name="%s">class %s</a>' % ( name, name, realname) mdict = {} if bases: parents = [] for base in bases: parents.append(self.classlink(base, object.__module__)) title = title + '(%s)' % pydoc.join(parents, ', ') doc = self.markup(pydoc.getdoc(object), self.preformat, funcs, classes, mdict) doc = doc and '<tt>%s<br> </tt>' % doc for iname,iclass in cdict[name]: fname = fdict[(name,iname)] if elements_dict.has_key(iname): push('class <a href="%s">%s</a>: element declaration typecode<br/>'\ %(fname,iname)) pyclass = elements_dict[iname] if pyclass is not None: push('<ul>instance attributes:') push('<li><a href="%s">pyclass</a>: instances serializable to XML<br/></li>'\ %elements_dict[iname]) push('</ul>') elif types_dict.has_key(iname): push('class <a href="%s">%s</a>: type definition typecode<br/>' %(fname,iname)) pyclass = types_dict[iname] if pyclass is not None: push('<ul>instance attributes:') push('<li><a href="%s">pyclass</a>: instances serializable to XML<br/></li>'\ %types_dict[iname]) push('</ul>') else: push('class <a href="%s">%s</a>: TODO not sure what this is<br/>' %(fname,iname)) contents = ''.join(contents) return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)
def formattree( self, tree, modname, parent=None, prefix='' ): """Render in text a class tree as returned by inspect.getclasstree().""" result = '' for entry in tree: if type( entry ) is type( () ): c, bases = entry result = result + prefix + classname( c, modname ) if bases and bases != ( parent, ): parents = map( lambda c, m=modname: classname( c, m ), bases ) result = result + '(%s)' % join( parents, ', ' ) result = result + '\n' elif type( entry ) is type( [] ): result = result + self.formattree( entry, modname, c, prefix + ' ' ) return result
def index(self): heading = pydoc.html.heading( '<big><big><strong>Python: Index of Modules</strong></big></big>', '#ffffff', '#7799ee') def bltinlink(name): return '<a href="%s.html">%s</a>' % (name, name) names = filter(lambda x: x != '__main__', sys.builtin_module_names) contents = pydoc.html.multicolumn(names, bltinlink) indices = ['<p>' + pydoc.html.bigsection( 'Built-in Modules', '#ffffff', '#ee77aa', contents)] seen = {} for dir in pydoc.pathdirs(): indices.append(pydoc.html.index(dir, seen)) contents = heading + pydoc.join(indices) + '''<p align=right> <font color="#909090" face="helvetica, arial"><strong> pydoc</strong> by Ka-Ping Yee <[email protected]></font>''' self.SetPage(contents)
def docserver(self, server_name, package_documentation, methods): """Produce HTML documentation for an XML-RPC server.""" fdict = {} for key, value in methods.items(): fdict[key] = '#-' + key fdict[value] = fdict[key] server_name = self.escape(server_name) head = '<big><big><strong>%s</strong></big></big>' % server_name result = self.heading(head, '#ffffff', '#7799ee') doc = self.markup(package_documentation, self.preformat, fdict) doc = doc and '<tt>%s</tt>' % doc result = result + '<p>%s</p>\n' % doc contents = [] method_items = sorted(methods.items()) for key, value in method_items: contents.append(self.docroutine(value, key, funcs=fdict)) result = result + self.bigsection('Methods', '#ffffff', '#eeaa77', pydoc.join(contents)) return result
def index(self): heading = pydoc.html.heading( '<big><big><strong>Python: Index of Modules</strong></big></big>', '#ffffff', '#7799ee') def bltinlink(name): return '<a href="%s.html">%s</a>' % (name, name) names = filter(lambda x: x != '__main__', sys.builtin_module_names) contents = pydoc.html.multicolumn(names, bltinlink) indices = [ '<p>' + pydoc.html.bigsection('Built-in Modules', '#ffffff', '#ee77aa', contents) ] seen = {} for dir in pydoc.pathdirs(): indices.append(pydoc.html.index(dir, seen)) contents = heading + pydoc.join(indices) + '''<p align=right> <font color="#909090" face="helvetica, arial"><strong> pydoc</strong> by Ka-Ping Yee <[email protected]></font>''' self.SetPage(contents)
def docserver(self, server_name, package_documentation, methods): """Produce HTML documentation for an XML-RPC server.""" fdict = {} for key, value in methods.items(): fdict[key] = "#-" + key fdict[value] = fdict[key] head = "<big><big><strong>%s</strong></big></big>" % server_name result = self.heading(head, "#ffffff", "#7799ee") doc = self.markup(package_documentation, self.preformat, fdict) doc = doc and "<tt>%s</tt>" % doc result = result + "<p>%s</p>\n" % doc contents = [] method_items = methods.items() method_items.sort() for key, value in method_items: contents.append(self.docroutine(value, key, funcs=fdict)) result = result + self.bigsection("Methods", "#ffffff", "#eeaa77", pydoc.join(contents)) return result
def docclass( self, object, name=None, mod=None ): """Produce tex 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 = self.texttt( 'class ' + realname ) else: title = self.texttt( 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 # 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)) # push('') # class to pump out a horizontal rule between sections. class HorizontalRule: def __init__( self ): self.needone = 0 def maybe( self ): if self.needone: push( '%' * 40 ) self.needone = 1 hr = HorizontalRule() def spill( msg, attrs, predicate ): ok, attrs = _split_list( attrs, predicate ) if ok: hr.maybe() #push(msg) docstr = [] for name, kind, homecls, value in ok: if name.startswith( '__' ) and name.endswith( '__' ): pass else: docstr.append( self.document( getattr( object, name ), name, mod, object ) ) push( "\n".join( docstr ) ) return attrs def spillproperties( msg, attrs, predicate ): ok, attrs = _split_list( attrs, predicate ) if ok: hr.maybe() push( msg ) for name, kind, homecls, value in ok: push( self._docproperty( 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 push( self.docother( getattr( object, name ), name, mod, 70, doc ) + '\n' ) return attrs attrs = filter( lambda ( name, kind, cls, value ): visiblename( name ), inspect.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__ ) filter( lambda t: not t[0].startswith( '_' ), attrs ) # 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 = spillproperties("Properties %s:\n" % tag, attrs, # lambda t: t[1] == 'property') # 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 self.classdesc( realname, '\n' + self.indent( rstrip( contents ), ' ' ) )
def docmodule( self, object, name=None, mod=None ): """Produce text documentation for a given module object.""" name = object.__name__ # ignore the passed-in name synop, desc = splitdoc( getdoc( object ) ) result = self.section( name, synop ) try: all = object.__all__ except AttributeError: all = None try: file = inspect.getabsfile( object ) except TypeError: file = '(built-in)' result = result + self.paragraph( 'File', file ) if desc: result = result + self.section( 'Description', desc ) classes = [] for key, value in inspect.getmembers( object, inspect.isclass ): # if __all__ exists, believe it. Otherwise use old heuristic. if ( all is not None or ( inspect.getmodule( value ) or object ) is object ): if visiblename( key, all ): classes.append( ( key, value ) ) funcs = [] for key, value in inspect.getmembers( object, inspect.isroutine ): # if __all__ exists, believe it. Otherwise use old heuristic. if ( all is not None or inspect.isbuiltin( value ) or inspect.getmodule( value ) is object ): if visiblename( key, all ): funcs.append( ( key, value ) ) data = [] for key, value in inspect.getmembers( object, isdata ): if visiblename( key, all ): data.append( ( key, value ) ) if hasattr( object, '__path__' ): modpkgs = [] for file in os.listdir( object.__path__[0] ): path = os.path.join( object.__path__[0], file ) modname = inspect.getmodulename( file ) if modname != '__init__': if modname and modname not in modpkgs: modpkgs.append( modname ) elif ispackage( path ): modpkgs.append( file + ' (package)' ) modpkgs.sort() result = result + self.section( 'Package Contents', join( modpkgs, '\n' ) ) if classes: classlist = map( lambda ( key, value ): value, classes ) contents = [] for key, value in classes: contents.append( self.document( value, key, name ) ) result = result + self.paragraph( 'Classes', "\n\\begin{itemize}\n\\item[] "+join( contents, '\n\\item[] ' ) +'\n\\end{itemize}' ) if funcs: contents = [] for key, value in funcs: contents.append( self.document( value, key, name ) ) result = result + self.paragraph( 'Functions', join( contents, '\n' ) ) if data: contents = [] for key, value in data: contents.append( self.docother( value, key, name, 70 ) ) result = result + self.paragraph( 'Data', join( contents, '\n' ) ) if hasattr( object, '__version__' ): version = str( object.__version__ ) if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': version = strip( version[11:-1] ) result = result + self.paragraph( 'Version', version ) if hasattr( object, '__date__' ): result = result + self.paragraph( 'Date', str( object.__date__ ) ) if hasattr( object, '__author__' ): result = result + self.paragraph( 'Author', str( object.__author__ ) ) if hasattr( object, '__credits__' ): result = result + self.paragraph( 'Credits', str( object.__credits__ ) ) return result
def docmodule(self, obj, name=None, mod=None): """Produce markdown documentation for a given module obj.""" name = obj.__name__ # ignore the passed-in name synop, desc = pydoc.splitdoc(pydoc.getdoc(obj)) result = self.section('NAME', name.replace(r'_', r'\_') + (synop and ' - ' + synop)) try: moduleall = obj.__all__ except AttributeError: moduleall = None try: filepath = os.path.dirname(inspect.getabsfile(obj)) except TypeError: filepath = '(built-in)' result = result + self.section('FILE', '`'+filepath+'`') docloc = self.getdocloc(obj) if docloc is not None: result = result + self.section('MODULE DOCS', docloc) if desc: result = result + self.section('DESCRIPTION', desc) if hasattr(obj, '__version__'): version = pydoc._binstr(obj.__version__) if version[:11] == '$Revision: ' and version[-1:] == '$': version = version[11:-1].strip() result = result + self.section('VERSION', version) if hasattr(obj, '__date__'): result = result + self.section('DATE', pydoc._binstr(obj.__date__)) if hasattr(obj, '__author__'): result = result + self.section('AUTHOR', pydoc._binstr(obj.__author__)) if hasattr(obj, '__credits__'): result = result + self.section('CREDITS', pydoc._binstr(obj.__credits__)) classes = [] for key, value in inspect.getmembers(obj, inspect.isclass): # if __all__ exists, believe it. Otherwise use old heuristic. if moduleall is not None or (inspect.getmodule(value) or obj) is obj: if pydoc.visiblename(key, moduleall, obj): classes.append((key, value)) funcs = [] for key, value in inspect.getmembers(obj, inspect.isroutine): # if __all__ exists, believe it. Otherwise use old heuristic. if moduleall is not None or inspect.isbuiltin(value) or inspect.getmodule(value) is obj: if pydoc.visiblename(key, moduleall, obj): funcs.append((key, value)) data = [] for key, value in inspect.getmembers(obj, pydoc.isdata): if pydoc.visiblename(key, moduleall, obj): data.append((key, value)) modules = [] for key, _ in inspect.getmembers(obj, inspect.ismodule): modules.append(key) if modules: modules = sorted(modules) contents = ', '.join(['[%s](https://www.google.com/#q=python+%s)' % (m, m) for m in modules]) + '\n{: .lead}' result = result + self.section('MODULES', contents) modpkgs = [] modpkgs_names = set() if hasattr(obj, '__path__'): for _, modname, ispkg in pkgutil.iter_modules(obj.__path__): modpkgs_names.add(modname) if ispkg: modpkgs.append(modname + ' (package)') else: modpkgs.append(modname) modpkgs.sort() result = result + self.section('PACKAGE CONTENTS', pydoc.join(modpkgs, '\n')) # Detect submodules as sometimes created by C extensions submodules = [] for key, value in inspect.getmembers(obj, inspect.ismodule): if value.__name__.startswith(name + '.') and key not in modpkgs_names: submodules.append(key) if submodules: submodules.sort() result = result + self.section('SUBMODULES', pydoc.join(submodules, '\n')) if funcs: contents = [] for key, value in funcs: contents.append(self.document(value, key, name)) result = result + self.section('FUNCTIONS', pydoc.join(contents, '\n')) if classes: classlist = [x[1] for x in classes] contents = [self.formattree(inspect.getclasstree(classlist, 1), name)] for key, value in classes: contents.append(self.document(value, key, name)) result = result + self.section('CLASSES', pydoc.join(contents, '\n')) if data: contents = [] for key, value in data: contents.append(self.docother(value, key, name)) result = result + self.section('DATA', pydoc.join(contents, '\n')) return result