*** /home/noam/cvs/python/Lib/pydoc.py Sat Jun 19 23:52:58 2004 --- pydoc.py Sun Jun 20 00:10:26 2004 *************** *** 238,251 **** file.close() return module ! def safeimport(path, forceload=0, cache={}): """Import a module; handle errors; return None if the module isn't found. If the module *is* found but an exception occurs, it's wrapped in an ErrorDuringImport exception and reraised. Unlike __import__, if a package path is specified, the module at the end of the path is returned, not the package at the beginning. If the optional 'forceload' argument ! is 1, we reload the module from disk (unless it's a dynamic extension).""" if forceload and path in sys.modules: # This is the only way to be sure. Checking the mtime of the file # isn't good enough (e.g. what if the module contains a class that --- 238,254 ---- file.close() return module ! def safeimport(path, forceload=0, finddirs=None, cache={}): """Import a module; handle errors; return None if the module isn't found. If the module *is* found but an exception occurs, it's wrapped in an ErrorDuringImport exception and reraised. Unlike __import__, if a package path is specified, the module at the end of the path is returned, not the package at the beginning. If the optional 'forceload' argument ! is 1, we reload the module from disk (unless it's a dynamic extension). ! ! dirs may be a list of directories to look for the module. If it is None, ! the module is found in the usual way.""" if forceload and path in sys.modules: # This is the only way to be sure. Checking the mtime of the file # isn't good enough (e.g. what if the module contains a class that *************** *** 260,266 **** cache[path] = sys.modules[path] # prevent module from clearing del sys.modules[path] try: ! module = __import__(path) except: # Did the error occur before or after the module was found? (exc, value, tb) = info = sys.exc_info() --- 263,280 ---- cache[path] = sys.modules[path] # prevent module from clearing del sys.modules[path] try: ! if finddirs: ! parts = path.split('.') ! for i, part in enumerate(parts): ! f, pathname, description = imp.find_module(part, finddirs) ! module = imp.load_module('.'.join(parts[:i+1]), f, pathname, ! description) ! finddirs = getattr(module, "__path__", None) ! else: ! module = __import__(path) ! for part in path.split('.')[1:]: ! try: module = getattr(module, part) ! except AttributeError: return None except: # Did the error occur before or after the module was found? (exc, value, tb) = info = sys.exc_info() *************** *** 277,291 **** else: # Some other error occurred during the importing process. raise ErrorDuringImport(path, sys.exc_info()) - for part in split(path, '.')[1:]: - try: module = getattr(module, part) - except AttributeError: return None return module # ---------------------------------------------------- formatter base class class Doc: ! def document(self, object, name=None, *args): """Generate documentation for an object.""" args = (object, name) + args # 'try' clause is to attempt to handle the possibility that inspect --- 291,302 ---- else: # Some other error occurred during the importing process. raise ErrorDuringImport(path, sys.exc_info()) return module # ---------------------------------------------------- formatter base class class Doc: ! def document(self, object, name=None, *args, **kwargs): """Generate documentation for an object.""" args = (object, name) + args # 'try' clause is to attempt to handle the possibility that inspect *************** *** 293,306 **** # think 'super' and how it is a descriptor (which raises the exception # by lacking a __name__ attribute) and an instance. try: ! if inspect.ismodule(object): return self.docmodule(*args) ! if inspect.isclass(object): return self.docclass(*args) ! if inspect.isroutine(object): return self.docroutine(*args) except AttributeError: pass ! return self.docother(*args) ! def fail(self, object, name=None, *args): """Raise an exception for unimplemented types.""" message = "don't know how to document object%s of type %s" % ( name and ' ' + repr(name), type(object).__name__) --- 304,317 ---- # think 'super' and how it is a descriptor (which raises the exception # by lacking a __name__ attribute) and an instance. try: ! if inspect.ismodule(object): return self.docmodule(*args, **kwargs) ! if inspect.isclass(object): return self.docclass(*args, **kwargs) ! if inspect.isroutine(object): return self.docroutine(*args,**kwargs) except AttributeError: pass ! return self.docother(*args, **kwargs) ! def fail(self, object, name=None, *args, **kwargs): """Raise an exception for unimplemented types.""" message = "don't know how to document object%s of type %s" % ( name and ' ' + repr(name), type(object).__name__) *************** *** 388,401 **** repr = _repr_instance.repr escape = _repr_instance.escape def page(self, title, contents): """Format an HTML page.""" return ''' ! Python: %s ! %s ! ''' % (title, contents) def heading(self, title, fgcol, bgcol, extras=''): """Format a page heading.""" --- 399,416 ---- repr = _repr_instance.repr escape = _repr_instance.escape + generatortag = '' + def page(self, title, contents): """Format an HTML page.""" return ''' ! %s ! Python: %s ! %s ! ! ''' % (self.generatortag, title, contents) def heading(self, title, fgcol, bgcol, extras=''): """Format a page heading.""" *************** *** 544,551 **** result = result + '
\n%s
\n' % self.formattree( entry, modname, c) return '
\n%s
\n' % result ! ! def docmodule(self, object, name=None, mod=None, *ignored): """Produce HTML documentation for a module object.""" name = object.__name__ # ignore the passed-in name try: --- 559,566 ---- result = result + '
\n%s
\n' % self.formattree( entry, modname, c) return '
\n%s
\n' % result ! ! def docmodule(self, object, name=None, mod=None, destdir=None, *ignored): """Produce HTML documentation for a module object.""" name = object.__name__ # ignore the passed-in name try: *************** *** 561,567 **** linkedname = join(links + parts[-1:], '.') head = '%s' % linkedname try: ! path = inspect.getabsfile(object) url = path if sys.platform == 'win32': import nturl2path --- 576,586 ---- linkedname = join(links + parts[-1:], '.') head = '%s' % linkedname try: ! path = os.path.abspath(inspect.getabsfile(object)) ! if destdir: ! curdir = os.path.abspath(os.getcwd()) ! if path.startswith(curdir): ! path = os.path.join(destdir, path[len(curdir)+1:]) url = path if sys.platform == 'win32': import nturl2path *************** *** 1389,1400 **** return 'instance of ' + thing.__class__.__name__ return type(thing).__name__ ! def locate(path, forceload=0): """Locate an object by name or dotted path, importing as necessary.""" parts = [part for part in split(path, '.') if part] module, n = None, 0 while n < len(parts): ! nextmodule = safeimport(join(parts[:n+1], '.'), forceload) if nextmodule: module, n = nextmodule, n + 1 else: break if module: --- 1408,1419 ---- return 'instance of ' + thing.__class__.__name__ return type(thing).__name__ ! def locate(path, forceload=False, finddirs=None): """Locate an object by name or dotted path, importing as necessary.""" parts = [part for part in split(path, '.') if part] module, n = None, 0 while n < len(parts): ! nextmodule = safeimport(join(parts[:n+1], '.'), forceload, finddirs) if nextmodule: module, n = nextmodule, n + 1 else: break if module: *************** *** 1412,1421 **** text = TextDoc() html = HTMLDoc() ! def resolve(thing, forceload=0): """Given an object or a path to an object, get the object and its name.""" if isinstance(thing, str): ! object = locate(thing, forceload) if not object: raise ImportError, 'no Python documentation found for %r' % thing return object, thing --- 1431,1440 ---- text = TextDoc() html = HTMLDoc() ! def resolve(thing, forceload=0, finddirs=None): """Given an object or a path to an object, get the object and its name.""" if isinstance(thing, str): ! object = locate(thing, forceload, finddirs) if not object: raise ImportError, 'no Python documentation found for %r' % thing return object, thing *************** *** 1436,1460 **** except (ImportError, ErrorDuringImport), value: print value ! def writedoc(thing, forceload=0): ! """Write HTML documentation to a file in the current directory.""" try: ! object, name = resolve(thing, forceload) ! page = html.page(describe(object), html.document(object, name)) ! file = open(name + '.html', 'w') ! file.write(page) ! file.close() ! print 'wrote', name + '.html' except (ImportError, ErrorDuringImport), value: print value ! def writedocs(dir, pkgpath='', done=None): """Write out HTML documentation for all modules in a directory tree.""" if done is None: done = {} for file in os.listdir(dir): path = os.path.join(dir, file) if ispackage(path): ! writedocs(path, pkgpath + file + '.', done) elif os.path.isfile(path): modname = inspect.getmodulename(path) if modname: --- 1455,1517 ---- except (ImportError, ErrorDuringImport), value: print value ! def shouldwritefile(sourcefn, destfn, updateonly): ! """ ! Get the module file name and the documentation file name, and return True ! if a documentation should be written. ! A documentation should be written if destfn doesn't exist, or it is older ! than sourcefn and was generated by pydoc. ! If sourcefn is None or updateonly is False, then the date of the existing ! file is ignored. ! """ ! if not os.path.exists(destfn): ! return True ! else: ! if sourcefn and updateonly and \ ! os.path.getmtime(destfn) > os.path.getmtime(sourcefn): ! return False ! else: ! if HTMLDoc.generatortag in file(destfn).read(1000): ! return True ! else: ! print >> sys.stderr, \ ! "Warning: file %s is older than %s, but wasn't updated "\ ! "because it hasn't been created by pydoc."\ ! % (destfn, sourcefn) ! return False ! ! def writedoc(thing, forceload=0, finddirs=None, outputdir="", destdir=None, ! updateonly=False): ! """Write HTML documentation to a file.""" try: ! object, name = resolve(thing, forceload, finddirs) ! try: ! sourcefn = inspect.getabsfile(object) ! except TypeError: ! sourcefn = None ! ! destfn = os.path.join(outputdir, name + '.html') ! if shouldwritefile(sourcefn, destfn, updateonly): ! page = html.page(describe(object), ! html.document(object, name, destdir=destdir)) ! file = open(destfn, 'w') ! file.write(page) ! file.close() ! print 'wrote', name + '.html' ! except (ImportError, ErrorDuringImport), value: print value ! def writedocs(dir, pkgpath='', done=None, outputdir="", destdir=None, ! origdir=None): """Write out HTML documentation for all modules in a directory tree.""" if done is None: done = {} + origdir = origdir or dir for file in os.listdir(dir): path = os.path.join(dir, file) if ispackage(path): ! writedocs(path, pkgpath + file + '.', done, outputdir, destdir, ! origdir) elif os.path.isfile(path): modname = inspect.getmodulename(path) if modname: *************** *** 1464,1470 **** modname = pkgpath + modname if modname not in done: done[modname] = 1 ! writedoc(modname) class Helper: keywords = { --- 1521,1528 ---- modname = pkgpath + modname if modname not in done: done[modname] = 1 ! writedoc(modname, finddirs=[origdir], outputdir=outputdir, ! destdir=destdir, updateonly=True) class Helper: keywords = { *************** *** 1881,1887 **** if path[:1] == '/': path = path[1:] if path and path != '.': try: ! obj = locate(path, forceload=1) except ErrorDuringImport, value: self.send_document(path, html.escape(str(value))) return --- 1939,1945 ---- if path[:1] == '/': path = path[1:] if path and path != '.': try: ! obj = locate(path, forceload=False) except ErrorDuringImport, value: self.send_document(path, html.escape(str(value))) return *************** *** 2138,2145 **** sys.path.insert(0, '.') try: ! opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w') writing = 0 for opt, val in opts: if opt == '-g': --- 2196,2205 ---- sys.path.insert(0, '.') try: ! opts, args = getopt.getopt(sys.argv[1:], 'gk:p:wo:d:') writing = 0 + outputdir = "" + destdir = "" for opt, val in opts: if opt == '-g': *************** *** 2161,2166 **** --- 2221,2230 ---- return if opt == '-w': writing = 1 + if opt == '-o': + outputdir = val + if opt == '-d': + destdir = val if not args: raise BadUsage for arg in args: *************** *** 2172,2180 **** arg = importfile(arg) if writing: if ispath(arg) and os.path.isdir(arg): ! writedocs(arg) else: ! writedoc(arg) else: help.help(arg) except ErrorDuringImport, value: --- 2236,2244 ---- arg = importfile(arg) if writing: if ispath(arg) and os.path.isdir(arg): ! writedocs(arg, outputdir=outputdir, destdir=destdir) else: ! writedoc(arg, outputdir=outputdir, destdir=destdir) else: help.help(arg) except ErrorDuringImport, value: *************** *** 2201,2210 **** %s -g Pop up a graphical interface for finding and serving documentation. ! %s -w ... Write out the HTML documentation for a module to a file in the current directory. If contains a '%s', it is treated as a filename; if it names a directory, documentation is written for all the contents. """ % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep) if __name__ == '__main__': cli() --- 2265,2279 ---- %s -g Pop up a graphical interface for finding and serving documentation. ! %s -w [-o outputdir] [-d destdir] ... Write out the HTML documentation for a module to a file in the current directory. If contains a '%s', it is treated as a filename; if it names a directory, documentation is written for all the contents. + If outputdir is given, files are written into that dir instead of into + current directory. + If destdir is given, the current working directory in module documentation + is replaced with destdir. This is useful if the files are to be transferred + to another location. """ % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep) if __name__ == '__main__': cli()