Hi, I wrote a short script for autogenerating API from sources, the output are .rst files that sphinx can parse and generate the docs in the modules/index sections.
Unfortunately, if the docstrings are not written in rst, it's not going to work properly. Also it uses python inspection (it's easy to implement), instead of parsing the source files directly. I am putting it here in case you find it useful. I wrote it for sympy originally, but we are not using it yet, because the output contains too much noise. Please let me know if you improve it/fix it. :) Ondrej
#! /usr/bin/python2.5 # You need to run python2.5 with this, because python2.4 has some weird # Exception hierarchy classes that causes Exceptions to be ignored by this # script import types import os import sys def isclass(x): from inspect import isclass as _isclass return _isclass(x) def ismethod(x): from inspect import ismethod as _ismethod if _ismethod(x) or isinstance(x, (types.MethodType, types.FunctionType, types.UnboundMethodType)) or str(type(x)) in [ "<type 'classmethod'>", "<type 'staticmethod'>"]: return True else: return False def get_method_name(x): if hasattr(x, "__name__"): return x.__name__ # This is a static method, don't know how to read the name. return None def get_method_args(x): from inspect import getsource try: s = getsource(x) except TypeError: return "" s = s[s.find("("):s.find(":")] assert s is not None return s def getdoc(x): from inspect import getdoc as _getdoc s = _getdoc(x) return s class Parser(object): def __init__(self): self.modules = {} def generate_doc(self, module, outdir="/tmp/", importpath = ""): """ Takes the "module" string and generates a rst for this module. modules is just the name, like "sympy", i.e. without a path. """ print "Generating API documentation ... (this may take a while)" sys.path.insert(0, importpath) m = __import__(module) self.main_module = module self.handle_module(m) print " saving..." for x in self.modules: if x.startswith(module): f = open(outdir+x+".txt", "w") f.write(self.modules[x]) print "API generated in %s." % (outdir) def handle_module(self, mod): mname = mod.__name__ if mname in self.modules: # we already handled this module return self.modules[mname] = "" # if you want to get the top level modules without "sympy.", uncomment # this: #if mname.startswith(self.main_module): # #strip the "sympy.": # s = ".. module:: %s\n\n" % mname[len(self.main_module)+1:] #else: # s = ".. module:: %s\n\n" % mname s = "=" * len(mname) + "\n" s += mname + "\n" s += "=" * len(mname) + "\n" + "\n" s += ".. module:: %s\n\n" % mname if hasattr(mod, __file__): s += "filename: %s\n" % mod.__file__ for x in mod.__dict__.values(): if isinstance(x, types.ModuleType): self.handle_module(x) elif x is None: pass elif isinstance(x, (int, float, str, list, dict)): # skip these pass elif str(type(x)) == "<type 'classobj'>": # old style classes pass elif hasattr(x, "__class__"): s += self.handle_class(x) else: print " Ignored:", type(x), x self.modules[mod.__name__] = s def handle_class(self, cls): if hasattr(cls, "__name__"): s = "\n.. class:: %s\n" % cls.__name__ else: return "" # Uncomment this to generate class docstrings too: # unfortunately, sphinx fails to read them, so we need to fix sympy # first. #doc = getdoc(cls) #if doc is not None: # s += doc # s += "\n" if hasattr(cls, "__dict__"): for x in cls.__dict__.values(): if isinstance(x, types.ModuleType): self.handle_module(x) elif str(type(x)) == "<type 'classobj'>": # old style classes pass elif x is None: pass elif ismethod(x): s += self.handle_method(x) elif str(type(x)) == "<type 'property'>": pass elif isinstance(x, (int, float, str, list, tuple, dict)): # skip these pass elif hasattr(x, "__class__"): # ignore nested classes pass else: print " Ignored in class:", type(x), x return s def handle_method(self, m): mname = get_method_name(m) if mname is None: s = "" else: s = "\n.. method:: %s%s\n\n" % (mname, get_method_args(m)) doc = getdoc(m) if doc is not None: s += doc s += "\n" return s Parser().generate_doc("sympy", importpath = "..", outdir="api/modules/")
_______________________________________________ Doc-SIG maillist - Doc-SIG@python.org http://mail.python.org/mailman/listinfo/doc-sig