*** /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()