home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_680 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  78.8 KB  |  2,409 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __author__ = 'Ka-Ping Yee <ping@lfw.org>'
  5. __date__ = '26 February 2001'
  6. __version__ = '$Revision: 73530 $'
  7. __credits__ = 'Guido van Rossum, for an excellent programming language.\nTommy Burnette, the original creator of manpy.\nPaul Prescod, for all his work on onlinehelp.\nRichard Chamberlain, for the first implementation of textdoc.\n'
  8. import sys
  9. import imp
  10. import os
  11. import re
  12. import types
  13. import inspect
  14. import __builtin__
  15. import pkgutil
  16. from repr import Repr
  17. from string import expandtabs, find, join, lower, split, strip, rfind, rstrip
  18. from traceback import extract_tb
  19.  
  20. try:
  21.     from collections import deque
  22. except ImportError:
  23.     
  24.     class deque(list):
  25.         
  26.         def popleft(self):
  27.             return self.pop(0)
  28.  
  29.  
  30.  
  31.  
  32. def pathdirs():
  33.     dirs = []
  34.     normdirs = []
  35.     for dir in sys.path:
  36.         if not dir:
  37.             pass
  38.         dir = os.path.abspath('.')
  39.         normdir = os.path.normcase(dir)
  40.         if normdir not in normdirs and os.path.isdir(dir):
  41.             dirs.append(dir)
  42.             normdirs.append(normdir)
  43.             continue
  44.     
  45.     return dirs
  46.  
  47.  
  48. def getdoc(object):
  49.     if not inspect.getdoc(object):
  50.         pass
  51.     result = inspect.getcomments(object)
  52.     if not result or re.sub('^ *\n', '', rstrip(result)):
  53.         pass
  54.     return ''
  55.  
  56.  
  57. def splitdoc(doc):
  58.     lines = split(strip(doc), '\n')
  59.     if len(lines) == 1:
  60.         return (lines[0], '')
  61.     if len(lines) >= 2 and not rstrip(lines[1]):
  62.         return (lines[0], join(lines[2:], '\n'))
  63.     return ('', join(lines, '\n'))
  64.  
  65.  
  66. def classname(object, modname):
  67.     name = object.__name__
  68.     if object.__module__ != modname:
  69.         name = object.__module__ + '.' + name
  70.     
  71.     return name
  72.  
  73.  
  74. def isdata(object):
  75.     if not inspect.ismodule(object) and inspect.isclass(object) and inspect.isroutine(object) and inspect.isframe(object) and inspect.istraceback(object):
  76.         pass
  77.     return not inspect.iscode(object)
  78.  
  79.  
  80. def replace(text, *pairs):
  81.     while pairs:
  82.         text = join(split(text, pairs[0]), pairs[1])
  83.         pairs = pairs[2:]
  84.     return text
  85.  
  86.  
  87. def cram(text, maxlen):
  88.     if len(text) > maxlen:
  89.         pre = max(0, (maxlen - 3) // 2)
  90.         post = max(0, maxlen - 3 - pre)
  91.         return text[:pre] + '...' + text[len(text) - post:]
  92.     return text
  93.  
  94. _re_stripid = re.compile(' at 0x[0-9a-f]{6,16}(>+)$', re.IGNORECASE)
  95.  
  96. def stripid(text):
  97.     if _re_stripid.search(repr(Exception)):
  98.         return _re_stripid.sub('\\1', text)
  99.     return text
  100.  
  101.  
  102. def _is_some_method(obj):
  103.     if not inspect.ismethod(obj):
  104.         pass
  105.     return inspect.ismethoddescriptor(obj)
  106.  
  107.  
  108. def allmethods(cl):
  109.     methods = { }
  110.     for key, value in inspect.getmembers(cl, _is_some_method):
  111.         methods[key] = 1
  112.     
  113.     for base in cl.__bases__:
  114.         methods.update(allmethods(base))
  115.     
  116.     for key in methods.keys():
  117.         methods[key] = getattr(cl, key)
  118.     
  119.     return methods
  120.  
  121.  
  122. def _split_list(s, predicate):
  123.     yes = []
  124.     no = []
  125.     for x in s:
  126.         if predicate(x):
  127.             yes.append(x)
  128.             continue
  129.         no.append(x)
  130.     
  131.     return (yes, no)
  132.  
  133.  
  134. def visiblename(name, all = None):
  135.     _hidden_names = ('__builtins__', '__doc__', '__file__', '__path__', '__module__', '__name__', '__slots__', '__package__')
  136.     if name in _hidden_names:
  137.         return 0
  138.     if name.startswith('__') and name.endswith('__'):
  139.         return 1
  140.     if all is not None:
  141.         return name in all
  142.     return not name.startswith('_')
  143.  
  144.  
  145. def classify_class_attrs(object):
  146.     
  147.     def fixup(data):
  148.         (name, kind, cls, value) = data
  149.         if inspect.isdatadescriptor(value):
  150.             kind = 'data descriptor'
  151.         
  152.         return (name, kind, cls, value)
  153.  
  154.     return map(fixup, inspect.classify_class_attrs(object))
  155.  
  156.  
  157. def ispackage(path):
  158.     if os.path.isdir(path):
  159.         for ext in ('.py', '.pyc', '.pyo'):
  160.             if os.path.isfile(os.path.join(path, '__init__' + ext)):
  161.                 return True
  162.         
  163.     
  164.     return False
  165.  
  166.  
  167. def source_synopsis(file):
  168.     line = file.readline()
  169.     while line[:1] == '#' or not strip(line):
  170.         line = file.readline()
  171.         if not line:
  172.             break
  173.             continue
  174.     line = strip(line)
  175.     if line[:4] == 'r"""':
  176.         line = line[1:]
  177.     
  178.     if line[:3] == '"""':
  179.         line = line[3:]
  180.         if line[-1:] == '\\':
  181.             line = line[:-1]
  182.         
  183.         while not strip(line):
  184.             line = file.readline()
  185.             if not line:
  186.                 break
  187.                 continue
  188.         result = strip(split(line, '"""')[0])
  189.     else:
  190.         result = None
  191.     return result
  192.  
  193.  
  194. def synopsis(filename, cache = { }):
  195.     mtime = os.stat(filename).st_mtime
  196.     (lastupdate, result) = cache.get(filename, (0, None))
  197.     if lastupdate < mtime:
  198.         info = inspect.getmoduleinfo(filename)
  199.         
  200.         try:
  201.             file = open(filename)
  202.         except IOError:
  203.             return None
  204.  
  205.         if info and 'b' in info[2]:
  206.             
  207.             try:
  208.                 module = imp.load_module('__temp__', file, filename, info[1:])
  209.             except:
  210.                 return None
  211.  
  212.             if not module.__doc__:
  213.                 pass
  214.             result = ''.splitlines()[0]
  215.             del sys.modules['__temp__']
  216.         else:
  217.             result = source_synopsis(file)
  218.             file.close()
  219.         cache[filename] = (mtime, result)
  220.     
  221.     return result
  222.  
  223.  
  224. class ErrorDuringImport(Exception):
  225.     
  226.     def __init__(self, filename, exc_info):
  227.         (exc, value, tb) = exc_info
  228.         self.filename = filename
  229.         self.exc = exc
  230.         self.value = value
  231.         self.tb = tb
  232.  
  233.     
  234.     def __str__(self):
  235.         exc = self.exc
  236.         if type(exc) is types.ClassType:
  237.             exc = exc.__name__
  238.         
  239.         return 'problem in %s - %s: %s' % (self.filename, exc, self.value)
  240.  
  241.  
  242.  
  243. def importfile(path):
  244.     magic = imp.get_magic()
  245.     file = open(path, 'r')
  246.     if file.read(len(magic)) == magic:
  247.         kind = imp.PY_COMPILED
  248.     else:
  249.         kind = imp.PY_SOURCE
  250.     file.close()
  251.     filename = os.path.basename(path)
  252.     (name, ext) = os.path.splitext(filename)
  253.     file = open(path, 'r')
  254.     
  255.     try:
  256.         module = imp.load_module(name, file, path, (ext, 'r', kind))
  257.     except:
  258.         raise ErrorDuringImport(path, sys.exc_info())
  259.  
  260.     file.close()
  261.     return module
  262.  
  263.  
  264. def safeimport(path, forceload = 0, cache = { }):
  265.     
  266.     try:
  267.         if forceload and path in sys.modules:
  268.             if path not in sys.builtin_module_names:
  269.                 subs = _[1]
  270.                 for key in [
  271.                     path] + subs:
  272.                     cache[key] = sys.modules[key]
  273.                     del sys.modules[key]
  274.                 
  275.             
  276.         
  277.         module = __import__(path)
  278.     except:
  279.         (exc, value, tb) = info = sys.exc_info()
  280.         if path in sys.modules:
  281.             raise ErrorDuringImport(sys.modules[path].__file__, info)
  282.         path in sys.modules
  283.         if exc is SyntaxError:
  284.             raise ErrorDuringImport(value.filename, info)
  285.         exc is SyntaxError
  286.         if exc is ImportError and extract_tb(tb)[-1][2] == 'safeimport':
  287.             return None
  288.         raise ErrorDuringImport(path, sys.exc_info())
  289.  
  290.     for part in split(path, '.')[1:]:
  291.         
  292.         try:
  293.             module = getattr(module, part)
  294.         continue
  295.         except AttributeError:
  296.             extract_tb(tb)[-1][2] == 'safeimport'
  297.             extract_tb(tb)[-1][2] == 'safeimport'
  298.             return None
  299.         
  300.  
  301.     
  302.     return module
  303.  
  304.  
  305. class Doc:
  306.     
  307.     def document(self, object, name = None, *args):
  308.         args = (object, name) + args
  309.         if inspect.isgetsetdescriptor(object):
  310.             return self.docdata(*args)
  311.         if inspect.ismemberdescriptor(object):
  312.             return self.docdata(*args)
  313.         
  314.         try:
  315.             if inspect.ismodule(object):
  316.                 return self.docmodule(*args)
  317.             if inspect.isclass(object):
  318.                 return self.docclass(*args)
  319.             if inspect.isroutine(object):
  320.                 return self.docroutine(*args)
  321.         except AttributeError:
  322.             inspect.ismemberdescriptor(object)
  323.             inspect.ismemberdescriptor(object)
  324.             inspect.isgetsetdescriptor(object)
  325.         except:
  326.             inspect.ismemberdescriptor(object)
  327.  
  328.         if isinstance(object, property):
  329.             return self.docproperty(*args)
  330.         return self.docother(*args)
  331.  
  332.     
  333.     def fail(self, object, name = None, *args):
  334.         if name:
  335.             pass
  336.         message = "don't know how to document object%s of type %s" % (' ' + repr(name), type(object).__name__)
  337.         raise TypeError, message
  338.  
  339.     docmodule = docclass = docroutine = docother = docproperty = docdata = fail
  340.     
  341.     def getdocloc(self, object):
  342.         
  343.         try:
  344.             file = inspect.getabsfile(object)
  345.         except TypeError:
  346.             file = '(built-in)'
  347.  
  348.         docloc = os.environ.get('PYTHONDOCS', 'http://docs.python.org/library')
  349.         basedir = os.path.join(sys.exec_prefix, 'lib', 'python' + sys.version[0:3])
  350.         if isinstance(object, type(os)):
  351.             if (object.__name__ in ('errno', 'exceptions', 'gc', 'imp', 'marshal', 'posix', 'signal', 'sys', 'thread', 'zipimport') or file.startswith(basedir)) and not file.startswith(os.path.join(basedir, 'site-packages')):
  352.                 if docloc.startswith('http://'):
  353.                     docloc = '%s/%s' % (docloc.rstrip('/'), object.__name__)
  354.                 else:
  355.                     docloc = os.path.join(docloc, object.__name__ + '.html')
  356.             else:
  357.                 docloc = None
  358.         return docloc
  359.  
  360.  
  361.  
  362. class HTMLRepr(Repr):
  363.     
  364.     def __init__(self):
  365.         Repr.__init__(self)
  366.         self.maxlist = self.maxtuple = 20
  367.         self.maxdict = 10
  368.         self.maxstring = self.maxother = 100
  369.  
  370.     
  371.     def escape(self, text):
  372.         return replace(text, '&', '&', '<', '<', '>', '>')
  373.  
  374.     
  375.     def repr(self, object):
  376.         return Repr.repr(self, object)
  377.  
  378.     
  379.     def repr1(self, x, level):
  380.         if hasattr(type(x), '__name__'):
  381.             methodname = 'repr_' + join(split(type(x).__name__), '_')
  382.             if hasattr(self, methodname):
  383.                 return getattr(self, methodname)(x, level)
  384.         
  385.         return self.escape(cram(stripid(repr(x)), self.maxother))
  386.  
  387.     
  388.     def repr_string(self, x, level):
  389.         test = cram(x, self.maxstring)
  390.         testrepr = repr(test)
  391.         if '\\' in test and '\\' not in replace(testrepr, '\\\\', ''):
  392.             return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
  393.         return re.sub('((\\\\[\\\\abfnrtv\\\'"]|\\\\[0-9]..|\\\\x..|\\\\u....)+)', '<font color="#c040c0">\\1</font>', self.escape(testrepr))
  394.  
  395.     repr_str = repr_string
  396.     
  397.     def repr_instance(self, x, level):
  398.         
  399.         try:
  400.             return self.escape(cram(stripid(repr(x)), self.maxstring))
  401.         except:
  402.             return self.escape('<%s instance>' % x.__class__.__name__)
  403.  
  404.  
  405.     repr_unicode = repr_string
  406.  
  407.  
  408. class HTMLDoc(Doc):
  409.     _repr_instance = HTMLRepr()
  410.     repr = _repr_instance.repr
  411.     escape = _repr_instance.escape
  412.     
  413.     def page(self, title, contents):
  414.         return '\n<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\n<html><head><title>Python: %s</title>\n</head><body bgcolor="#f0f0f8">\n%s\n</body></html>' % (title, contents)
  415.  
  416.     
  417.     def heading(self, title, fgcol, bgcol, extras = ''):
  418.         if not extras:
  419.             pass
  420.         return '\n<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">\n<tr bgcolor="%s">\n<td valign=bottom> <br>\n<font color="%s" face="helvetica, arial"> <br>%s</font></td\n><td align=right valign=bottom\n><font color="%s" face="helvetica, arial">%s</font></td></tr></table>\n    ' % (bgcol, fgcol, title, fgcol, ' ')
  421.  
  422.     
  423.     def section(self, title, fgcol, bgcol, contents, width = 6, prelude = '', marginalia = None, gap = ' '):
  424.         if marginalia is None:
  425.             marginalia = '<tt>' + ' ' * width + '</tt>'
  426.         
  427.         result = '<p>\n<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">\n<tr bgcolor="%s">\n<td colspan=3 valign=bottom> <br>\n<font color="%s" face="helvetica, arial">%s</font></td></tr>\n    ' % (bgcol, fgcol, title)
  428.         if prelude:
  429.             result = result + '\n<tr bgcolor="%s"><td rowspan=2>%s</td>\n<td colspan=2>%s</td></tr>\n<tr><td>%s</td>' % (bgcol, marginalia, prelude, gap)
  430.         else:
  431.             result = result + '\n<tr><td bgcolor="%s">%s</td><td>%s</td>' % (bgcol, marginalia, gap)
  432.         return result + '\n<td width="100%%">%s</td></tr></table>' % contents
  433.  
  434.     
  435.     def bigsection(self, title, *args):
  436.         title = '<big><strong>%s</strong></big>' % title
  437.         return self.section(title, *args)
  438.  
  439.     
  440.     def preformat(self, text):
  441.         text = self.escape(expandtabs(text))
  442.         return replace(text, '\n\n', '\n \n', '\n\n', '\n \n', ' ', ' ', '\n', '<br>\n')
  443.  
  444.     
  445.     def multicolumn(self, list, format, cols = 4):
  446.         result = ''
  447.         rows = (len(list) + cols - 1) / cols
  448.         for col in range(cols):
  449.             result = result + '<td width="%d%%" valign=top>' % 100 / cols
  450.             for i in range(rows * col, rows * col + rows):
  451.                 if i < len(list):
  452.                     result = result + format(list[i]) + '<br>\n'
  453.                     continue
  454.             
  455.             result = result + '</td>'
  456.         
  457.         return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
  458.  
  459.     
  460.     def grey(self, text):
  461.         return '<font color="#909090">%s</font>' % text
  462.  
  463.     
  464.     def namelink(self, name, *dicts):
  465.         for dict in dicts:
  466.             if name in dict:
  467.                 return '<a href="%s">%s</a>' % (dict[name], name)
  468.         
  469.         return name
  470.  
  471.     
  472.     def classlink(self, object, modname):
  473.         name = object.__name__
  474.         module = sys.modules.get(object.__module__)
  475.         if hasattr(module, name) and getattr(module, name) is object:
  476.             return '<a href="%s.html#%s">%s</a>' % (module.__name__, name, classname(object, modname))
  477.         return classname(object, modname)
  478.  
  479.     
  480.     def modulelink(self, object):
  481.         return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__)
  482.  
  483.     
  484.     def modpkglink(self, data):
  485.         (name, path, ispackage, shadowed) = data
  486.         if shadowed:
  487.             return self.grey(name)
  488.         if path:
  489.             url = '%s.%s.html' % (path, name)
  490.         else:
  491.             url = '%s.html' % name
  492.         if ispackage:
  493.             text = '<strong>%s</strong> (package)' % name
  494.         else:
  495.             text = name
  496.         return '<a href="%s">%s</a>' % (url, text)
  497.  
  498.     
  499.     def markup(self, text, escape = None, funcs = { }, classes = { }, methods = { }):
  500.         if not escape:
  501.             pass
  502.         escape = self.escape
  503.         results = []
  504.         here = 0
  505.         pattern = re.compile('\\b((http|ftp)://\\S+[\\w/]|RFC[- ]?(\\d+)|PEP[- ]?(\\d+)|(self\\.)?(\\w+))')
  506.         while True:
  507.             match = pattern.search(text, here)
  508.             if not match:
  509.                 break
  510.             
  511.             (start, end) = match.span()
  512.             results.append(escape(text[here:start]))
  513.             (all, scheme, rfc, pep, selfdot, name) = match.groups()
  514.             if scheme:
  515.                 url = escape(all).replace('"', '"')
  516.                 results.append('<a href="%s">%s</a>' % (url, url))
  517.             elif rfc:
  518.                 url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
  519.                 results.append('<a href="%s">%s</a>' % (url, escape(all)))
  520.             elif pep:
  521.                 url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep)
  522.                 results.append('<a href="%s">%s</a>' % (url, escape(all)))
  523.             elif text[end:end + 1] == '(':
  524.                 results.append(self.namelink(name, methods, funcs, classes))
  525.             elif selfdot:
  526.                 results.append('self.<strong>%s</strong>' % name)
  527.             else:
  528.                 results.append(self.namelink(name, classes))
  529.             here = end
  530.         results.append(escape(text[here:]))
  531.         return join(results, '')
  532.  
  533.     
  534.     def formattree(self, tree, modname, parent = None):
  535.         result = ''
  536.         for entry in tree:
  537.             if type(entry) is type(()):
  538.                 (c, bases) = entry
  539.                 result = result + '<dt><font face="helvetica, arial">'
  540.                 result = result + self.classlink(c, modname)
  541.                 if bases and bases != (parent,):
  542.                     parents = []
  543.                     for base in bases:
  544.                         parents.append(self.classlink(base, modname))
  545.                     
  546.                     result = result + '(' + join(parents, ', ') + ')'
  547.                 
  548.                 result = result + '\n</font></dt>'
  549.                 continue
  550.             if type(entry) is type([]):
  551.                 result = result + '<dd>\n%s</dd>\n' % self.formattree(entry, modname, c)
  552.                 continue
  553.         
  554.         return '<dl>\n%s</dl>\n' % result
  555.  
  556.     
  557.     def docmodule(self, object, name = None, mod = None, *ignored):
  558.         name = object.__name__
  559.         
  560.         try:
  561.             all = object.__all__
  562.         except AttributeError:
  563.             all = None
  564.  
  565.         parts = split(name, '.')
  566.         links = []
  567.         for i in range(len(parts) - 1):
  568.             links.append('<a href="%s.html"><font color="#ffffff">%s</font></a>' % (join(parts[:i + 1], '.'), parts[i]))
  569.         
  570.         linkedname = join(links + parts[-1:], '.')
  571.         head = '<big><big><strong>%s</strong></big></big>' % linkedname
  572.         
  573.         try:
  574.             path = inspect.getabsfile(object)
  575.             url = path
  576.             if sys.platform == 'win32':
  577.                 import nturl2path
  578.                 url = nturl2path.pathname2url(path)
  579.             
  580.             filelink = '<a href="file:%s">%s</a>' % (url, path)
  581.         except TypeError:
  582.             filelink = '(built-in)'
  583.  
  584.         info = []
  585.         if hasattr(object, '__version__'):
  586.             version = str(object.__version__)
  587.             if version[:11] == '$Revision: ' and version[-1:] == '$':
  588.                 version = strip(version[11:-1])
  589.             
  590.             info.append('version %s' % self.escape(version))
  591.         
  592.         if hasattr(object, '__date__'):
  593.             info.append(self.escape(str(object.__date__)))
  594.         
  595.         if info:
  596.             head = head + ' (%s)' % join(info, ', ')
  597.         
  598.         docloc = self.getdocloc(object)
  599.         if docloc is not None:
  600.             docloc = '<br><a href="%(docloc)s">Module Docs</a>' % locals()
  601.         else:
  602.             docloc = ''
  603.         result = self.heading(head, '#ffffff', '#7799ee', '<a href=".">index</a><br>' + filelink + docloc)
  604.         modules = inspect.getmembers(object, inspect.ismodule)
  605.         classes = []
  606.         cdict = { }
  607.         for key, value in inspect.getmembers(object, inspect.isclass):
  608.             if not all is not None:
  609.                 if not inspect.getmodule(value):
  610.                     pass
  611.                 if object is object:
  612.                     if visiblename(key, all):
  613.                         classes.append((key, value))
  614.                         cdict[key] = cdict[value] = '#' + key
  615.                     
  616.             visiblename(key, all)
  617.         
  618.         for key, value in classes:
  619.             for base in value.__bases__:
  620.                 key = base.__name__
  621.                 modname = base.__module__
  622.                 module = sys.modules.get(modname)
  623.                 if modname != name and module and hasattr(module, key):
  624.                     if getattr(module, key) is base:
  625.                         if key not in cdict:
  626.                             cdict[key] = cdict[base] = modname + '.html#' + key
  627.                         
  628.                     
  629.                 getattr(module, key) is base
  630.             
  631.         
  632.         funcs = []
  633.         fdict = { }
  634.         for key, value in inspect.getmembers(object, inspect.isroutine):
  635.             if all is not None and inspect.isbuiltin(value) or inspect.getmodule(value) is object:
  636.                 if visiblename(key, all):
  637.                     funcs.append((key, value))
  638.                     fdict[key] = '#-' + key
  639.                     if inspect.isfunction(value):
  640.                         fdict[value] = fdict[key]
  641.                     
  642.                 
  643.             visiblename(key, all)
  644.         
  645.         data = []
  646.         for key, value in inspect.getmembers(object, isdata):
  647.             if visiblename(key, all):
  648.                 data.append((key, value))
  649.                 continue
  650.         
  651.         doc = self.markup(getdoc(object), self.preformat, fdict, cdict)
  652.         if doc:
  653.             pass
  654.         doc = '<tt>%s</tt>' % doc
  655.         result = result + '<p>%s</p>\n' % doc
  656.         if hasattr(object, '__path__'):
  657.             modpkgs = []
  658.             for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
  659.                 modpkgs.append((modname, name, ispkg, 0))
  660.             
  661.             modpkgs.sort()
  662.             contents = self.multicolumn(modpkgs, self.modpkglink)
  663.             result = result + self.bigsection('Package Contents', '#ffffff', '#aa55cc', contents)
  664.         elif modules:
  665.             contents = self.multicolumn(modules, (lambda key_value, s = self: s.modulelink(key_value[1])))
  666.             result = result + self.bigsection('Modules', '#ffffff', '#aa55cc', contents)
  667.         
  668.         if classes:
  669.             classlist = map((lambda key_value: key_value[1]), classes)
  670.             contents = [
  671.                 self.formattree(inspect.getclasstree(classlist, 1), name)]
  672.             for key, value in classes:
  673.                 contents.append(self.document(value, key, name, fdict, cdict))
  674.             
  675.             result = result + self.bigsection('Classes', '#ffffff', '#ee77aa', join(contents))
  676.         
  677.         if funcs:
  678.             contents = []
  679.             for key, value in funcs:
  680.                 contents.append(self.document(value, key, name, fdict, cdict))
  681.             
  682.             result = result + self.bigsection('Functions', '#ffffff', '#eeaa77', join(contents))
  683.         
  684.         if data:
  685.             contents = []
  686.             for key, value in data:
  687.                 contents.append(self.document(value, key))
  688.             
  689.             result = result + self.bigsection('Data', '#ffffff', '#55aa55', join(contents, '<br>\n'))
  690.         
  691.         if hasattr(object, '__author__'):
  692.             contents = self.markup(str(object.__author__), self.preformat)
  693.             result = result + self.bigsection('Author', '#ffffff', '#7799ee', contents)
  694.         
  695.         if hasattr(object, '__credits__'):
  696.             contents = self.markup(str(object.__credits__), self.preformat)
  697.             result = result + self.bigsection('Credits', '#ffffff', '#7799ee', contents)
  698.         
  699.         return result
  700.  
  701.     
  702.     def docclass(self, object, name = None, mod = None, funcs = { }, classes = { }, *ignored):
  703.         realname = object.__name__
  704.         if not name:
  705.             pass
  706.         name = realname
  707.         bases = object.__bases__
  708.         contents = []
  709.         push = contents.append
  710.         
  711.         class HorizontalRule(()):
  712.             
  713.             def __init__(self):
  714.                 self.needone = 0
  715.  
  716.             
  717.             def maybe(self):
  718.                 if self.needone:
  719.                     push('<hr>\n')
  720.                 
  721.                 self.needone = 1
  722.  
  723.  
  724.         hr = HorizontalRule()
  725.         mro = deque(inspect.getmro(object))
  726.         if len(mro) > 2:
  727.             hr.maybe()
  728.             push('<dl><dt>Method resolution order:</dt>\n')
  729.             for base in mro:
  730.                 push('<dd>%s</dd>\n' % self.classlink(base, object.__module__))
  731.             
  732.             push('</dl>\n')
  733.         
  734.         
  735.         def spill(msg, attrs, predicate):
  736.             (ok, attrs) = _split_list(attrs, predicate)
  737.             if ok:
  738.                 hr.maybe()
  739.                 push(msg)
  740.                 for name, kind, homecls, value in ok:
  741.                     push(self.document(getattr(object, name), name, mod, funcs, classes, mdict, object))
  742.                     push('\n')
  743.                 
  744.             
  745.             return attrs
  746.  
  747.         
  748.         def spilldescriptors(msg, attrs, predicate):
  749.             (ok, attrs) = _split_list(attrs, predicate)
  750.             if ok:
  751.                 hr.maybe()
  752.                 push(msg)
  753.                 for name, kind, homecls, value in ok:
  754.                     push(self._docdescriptor(name, value, mod))
  755.                 
  756.             
  757.             return attrs
  758.  
  759.         
  760.         def spilldata(msg, attrs, predicate):
  761.             (ok, attrs) = _split_list(attrs, predicate)
  762.             if ok:
  763.                 hr.maybe()
  764.                 push(msg)
  765.                 for name, kind, homecls, value in ok:
  766.                     base = self.docother(getattr(object, name), name, mod)
  767.                     if hasattr(value, '__call__') or inspect.isdatadescriptor(value):
  768.                         doc = getattr(value, '__doc__', None)
  769.                     else:
  770.                         doc = None
  771.                     if doc is None:
  772.                         push('<dl><dt>%s</dl>\n' % base)
  773.                     else:
  774.                         doc = self.markup(getdoc(value), self.preformat, funcs, classes, mdict)
  775.                         doc = '<dd><tt>%s</tt>' % doc
  776.                         push('<dl><dt>%s%s</dl>\n' % (base, doc))
  777.                     push('\n')
  778.                 
  779.             
  780.             return attrs
  781.  
  782.         attrs = filter((lambda data: visiblename(data[0])), classify_class_attrs(object))
  783.         mdict = { }
  784.         for key, kind, homecls, value in attrs:
  785.             value = getattr(object, key)
  786.             
  787.             try:
  788.                 mdict[value] = anchor
  789.             continue
  790.             except TypeError:
  791.                 (None, None, None, None, None, None, None, (None, None, None, (None, None, None, None, None, None, None, None)))
  792.                 (None, None, None, None, None, None, None, (None, None, None, (None, None, None, None, None, None, None, None)))
  793.                 continue
  794.             
  795.  
  796.         
  797.         while attrs:
  798.             (attrs, inherited) = _split_list((attrs,), (lambda t: t[2] is thisclass))
  799.             if thisclass is __builtin__.object:
  800.                 attrs = inherited
  801.                 continue
  802.             elif thisclass is object:
  803.                 tag = 'defined here'
  804.             else:
  805.                 tag = 'inherited from %s' % self.classlink(thisclass, object.__module__)
  806.             tag += ':<br>\n'
  807.             
  808.             try:
  809.                 attrs.sort(key = (lambda t: t[0]))
  810.             except TypeError:
  811.                 attrs.sort((lambda t1, t2: cmp(t1[0], t2[0])))
  812.  
  813.             attrs = spill('Methods %s' % tag, attrs, (lambda t: t[1] == 'method'))
  814.             attrs = spill('Class methods %s' % tag, attrs, (lambda t: t[1] == 'class method'))
  815.             attrs = spill('Static methods %s' % tag, attrs, (lambda t: t[1] == 'static method'))
  816.             attrs = spilldescriptors('Data descriptors %s' % tag, attrs, (lambda t: t[1] == 'data descriptor'))
  817.             attrs = spilldata('Data and other attributes %s' % tag, attrs, (lambda t: t[1] == 'data'))
  818.             attrs = inherited
  819.         contents = ''.join(contents)
  820.         if name == realname:
  821.             title = '<a name="%s">class <strong>%s</strong></a>' % (name, realname)
  822.         else:
  823.             title = '<strong>%s</strong> = <a name="%s">class %s</a>' % (name, name, realname)
  824.         if bases:
  825.             parents = []
  826.             for base in bases:
  827.                 parents.append(self.classlink(base, object.__module__))
  828.             
  829.             title = title + '(%s)' % join(parents, ', ')
  830.         
  831.         doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict)
  832.         if doc:
  833.             pass
  834.         doc = '<tt>%s<br> </tt>' % doc
  835.         return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)
  836.  
  837.     
  838.     def formatvalue(self, object):
  839.         return self.grey('=' + self.repr(object))
  840.  
  841.     
  842.     def docroutine(self, object, name = None, mod = None, funcs = { }, classes = { }, methods = { }, cl = None):
  843.         realname = object.__name__
  844.         if not name:
  845.             pass
  846.         name = realname
  847.         if not cl or cl.__name__:
  848.             pass
  849.         anchor = '' + '-' + name
  850.         note = ''
  851.         skipdocs = 0
  852.         if inspect.ismethod(object):
  853.             imclass = object.im_class
  854.             if cl:
  855.                 if imclass is not cl:
  856.                     note = ' from ' + self.classlink(imclass, mod)
  857.                 
  858.             elif object.im_self is not None:
  859.                 note = ' method of %s instance' % self.classlink(object.im_self.__class__, mod)
  860.             else:
  861.                 note = ' unbound %s method' % self.classlink(imclass, mod)
  862.             object = object.im_func
  863.         
  864.         if name == realname:
  865.             title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
  866.         elif cl and realname in cl.__dict__ and cl.__dict__[realname] is object:
  867.             reallink = '<a href="#%s">%s</a>' % (cl.__name__ + '-' + realname, realname)
  868.             skipdocs = 1
  869.         else:
  870.             reallink = realname
  871.         title = '<a name="%s"><strong>%s</strong></a> = %s' % (anchor, name, reallink)
  872.         if inspect.isfunction(object):
  873.             (args, varargs, varkw, defaults) = inspect.getargspec(object)
  874.             argspec = inspect.formatargspec(args, varargs, varkw, defaults, formatvalue = self.formatvalue)
  875.             if realname == '<lambda>':
  876.                 title = '<strong>%s</strong> <em>lambda</em> ' % name
  877.                 argspec = argspec[1:-1]
  878.             
  879.         else:
  880.             argspec = '(...)'
  881.         if note:
  882.             pass
  883.         decl = title + argspec + self.grey('<font face="helvetica, arial">%s</font>' % note)
  884.         if skipdocs:
  885.             return '<dl><dt>%s</dt></dl>\n' % decl
  886.         doc = self.markup(getdoc(object), self.preformat, funcs, classes, methods)
  887.         if doc:
  888.             pass
  889.         doc = '<dd><tt>%s</tt></dd>' % doc
  890.         return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
  891.  
  892.     
  893.     def _docdescriptor(self, name, value, mod):
  894.         results = []
  895.         push = results.append
  896.         if name:
  897.             push('<dl><dt><strong>%s</strong></dt>\n' % name)
  898.         
  899.         if value.__doc__ is not None:
  900.             doc = self.markup(getdoc(value), self.preformat)
  901.             push('<dd><tt>%s</tt></dd>\n' % doc)
  902.         
  903.         push('</dl>\n')
  904.         return ''.join(results)
  905.  
  906.     
  907.     def docproperty(self, object, name = None, mod = None, cl = None):
  908.         return self._docdescriptor(name, object, mod)
  909.  
  910.     
  911.     def docother(self, object, name = None, mod = None, *ignored):
  912.         if not name or '<strong>%s</strong> = ' % name:
  913.             pass
  914.         lhs = ''
  915.         return lhs + self.repr(object)
  916.  
  917.     
  918.     def docdata(self, object, name = None, mod = None, cl = None):
  919.         return self._docdescriptor(name, object, mod)
  920.  
  921.     
  922.     def index(self, dir, shadowed = None):
  923.         modpkgs = []
  924.         if shadowed is None:
  925.             shadowed = { }
  926.         
  927.         for importer, name, ispkg in pkgutil.iter_modules([
  928.             dir]):
  929.             modpkgs.append((name, '', ispkg, name in shadowed))
  930.             shadowed[name] = 1
  931.         
  932.         modpkgs.sort()
  933.         contents = self.multicolumn(modpkgs, self.modpkglink)
  934.         return self.bigsection(dir, '#ffffff', '#ee77aa', contents)
  935.  
  936.  
  937.  
  938. class TextRepr(Repr):
  939.     
  940.     def __init__(self):
  941.         Repr.__init__(self)
  942.         self.maxlist = self.maxtuple = 20
  943.         self.maxdict = 10
  944.         self.maxstring = self.maxother = 100
  945.  
  946.     
  947.     def repr1(self, x, level):
  948.         if hasattr(type(x), '__name__'):
  949.             methodname = 'repr_' + join(split(type(x).__name__), '_')
  950.             if hasattr(self, methodname):
  951.                 return getattr(self, methodname)(x, level)
  952.         
  953.         return cram(stripid(repr(x)), self.maxother)
  954.  
  955.     
  956.     def repr_string(self, x, level):
  957.         test = cram(x, self.maxstring)
  958.         testrepr = repr(test)
  959.         if '\\' in test and '\\' not in replace(testrepr, '\\\\', ''):
  960.             return 'r' + testrepr[0] + test + testrepr[0]
  961.         return testrepr
  962.  
  963.     repr_str = repr_string
  964.     
  965.     def repr_instance(self, x, level):
  966.         
  967.         try:
  968.             return cram(stripid(repr(x)), self.maxstring)
  969.         except:
  970.             return '<%s instance>' % x.__class__.__name__
  971.  
  972.  
  973.  
  974.  
  975. class TextDoc(Doc):
  976.     _repr_instance = TextRepr()
  977.     repr = _repr_instance.repr
  978.     
  979.     def bold(self, text):
  980.         return join(map((lambda ch: ch + '\x08' + ch), text), '')
  981.  
  982.     
  983.     def indent(self, text, prefix = '    '):
  984.         if not text:
  985.             return ''
  986.         lines = split(text, '\n')
  987.         lines = map((lambda line, prefix = prefix: prefix + line), lines)
  988.         if lines:
  989.             lines[-1] = rstrip(lines[-1])
  990.         
  991.         return join(lines, '\n')
  992.  
  993.     
  994.     def section(self, title, contents):
  995.         return self.bold(title) + '\n' + rstrip(self.indent(contents)) + '\n\n'
  996.  
  997.     
  998.     def formattree(self, tree, modname, parent = None, prefix = ''):
  999.         result = ''
  1000.         for entry in tree:
  1001.             if type(entry) is type(()):
  1002.                 (c, bases) = entry
  1003.                 result = result + prefix + classname(c, modname)
  1004.                 if bases and bases != (parent,):
  1005.                     parents = map((lambda c, m = modname: classname(c, m)), bases)
  1006.                     result = result + '(%s)' % join(parents, ', ')
  1007.                 
  1008.                 result = result + '\n'
  1009.                 continue
  1010.             if type(entry) is type([]):
  1011.                 result = result + self.formattree(entry, modname, c, prefix + '    ')
  1012.                 continue
  1013.         
  1014.         return result
  1015.  
  1016.     
  1017.     def docmodule(self, object, name = None, mod = None):
  1018.         name = object.__name__
  1019.         (synop, desc) = splitdoc(getdoc(object))
  1020.         if synop:
  1021.             pass
  1022.         result = self.section('NAME', name + ' - ' + synop)
  1023.         
  1024.         try:
  1025.             all = object.__all__
  1026.         except AttributeError:
  1027.             all = None
  1028.  
  1029.         
  1030.         try:
  1031.             file = inspect.getabsfile(object)
  1032.         except TypeError:
  1033.             file = '(built-in)'
  1034.  
  1035.         result = result + self.section('FILE', file)
  1036.         docloc = self.getdocloc(object)
  1037.         if docloc is not None:
  1038.             result = result + self.section('MODULE DOCS', docloc)
  1039.         
  1040.         if desc:
  1041.             result = result + self.section('DESCRIPTION', desc)
  1042.         
  1043.         classes = []
  1044.         for key, value in inspect.getmembers(object, inspect.isclass):
  1045.             if not all is not None:
  1046.                 if not inspect.getmodule(value):
  1047.                     pass
  1048.                 if object is object:
  1049.                     if visiblename(key, all):
  1050.                         classes.append((key, value))
  1051.                     
  1052.             visiblename(key, all)
  1053.         
  1054.         funcs = []
  1055.         for key, value in inspect.getmembers(object, inspect.isroutine):
  1056.             if all is not None and inspect.isbuiltin(value) or inspect.getmodule(value) is object:
  1057.                 if visiblename(key, all):
  1058.                     funcs.append((key, value))
  1059.                 
  1060.             visiblename(key, all)
  1061.         
  1062.         data = []
  1063.         for key, value in inspect.getmembers(object, isdata):
  1064.             if visiblename(key, all):
  1065.                 data.append((key, value))
  1066.                 continue
  1067.         
  1068.         modpkgs = []
  1069.         modpkgs_names = set()
  1070.         if hasattr(object, '__path__'):
  1071.             for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
  1072.                 modpkgs_names.add(modname)
  1073.                 if ispkg:
  1074.                     modpkgs.append(modname + ' (package)')
  1075.                     continue
  1076.                 modpkgs.append(modname)
  1077.             
  1078.             modpkgs.sort()
  1079.             result = result + self.section('PACKAGE CONTENTS', join(modpkgs, '\n'))
  1080.         
  1081.         submodules = []
  1082.         for key, value in inspect.getmembers(object, inspect.ismodule):
  1083.             if value.__name__.startswith(name + '.') and key not in modpkgs_names:
  1084.                 submodules.append(key)
  1085.                 continue
  1086.         
  1087.         if submodules:
  1088.             submodules.sort()
  1089.             result = result + self.section('SUBMODULES', join(submodules, '\n'))
  1090.         
  1091.         if classes:
  1092.             classlist = map((lambda key_value: key_value[1]), classes)
  1093.             contents = [
  1094.                 self.formattree(inspect.getclasstree(classlist, 1), name)]
  1095.             for key, value in classes:
  1096.                 contents.append(self.document(value, key, name))
  1097.             
  1098.             result = result + self.section('CLASSES', join(contents, '\n'))
  1099.         
  1100.         if funcs:
  1101.             contents = []
  1102.             for key, value in funcs:
  1103.                 contents.append(self.document(value, key, name))
  1104.             
  1105.             result = result + self.section('FUNCTIONS', join(contents, '\n'))
  1106.         
  1107.         if data:
  1108.             contents = []
  1109.             for key, value in data:
  1110.                 contents.append(self.docother(value, key, name, maxlen = 70))
  1111.             
  1112.             result = result + self.section('DATA', join(contents, '\n'))
  1113.         
  1114.         if hasattr(object, '__version__'):
  1115.             version = str(object.__version__)
  1116.             if version[:11] == '$Revision: ' and version[-1:] == '$':
  1117.                 version = strip(version[11:-1])
  1118.             
  1119.             result = result + self.section('VERSION', version)
  1120.         
  1121.         if hasattr(object, '__date__'):
  1122.             result = result + self.section('DATE', str(object.__date__))
  1123.         
  1124.         if hasattr(object, '__author__'):
  1125.             result = result + self.section('AUTHOR', str(object.__author__))
  1126.         
  1127.         if hasattr(object, '__credits__'):
  1128.             result = result + self.section('CREDITS', str(object.__credits__))
  1129.         
  1130.         return result
  1131.  
  1132.     
  1133.     def docclass(self, object, name = None, mod = None):
  1134.         realname = object.__name__
  1135.         if not name:
  1136.             pass
  1137.         name = realname
  1138.         bases = object.__bases__
  1139.         
  1140.         def makename(c, m = object.__module__):
  1141.             return classname(c, m)
  1142.  
  1143.         if name == realname:
  1144.             title = 'class ' + self.bold(realname)
  1145.         else:
  1146.             title = self.bold(name) + ' = class ' + realname
  1147.         if bases:
  1148.             parents = map(makename, bases)
  1149.             title = title + '(%s)' % join(parents, ', ')
  1150.         
  1151.         doc = getdoc(object)
  1152.         if not doc or [
  1153.             doc + '\n']:
  1154.             pass
  1155.         contents = []
  1156.         push = contents.append
  1157.         mro = deque(inspect.getmro(object))
  1158.         if len(mro) > 2:
  1159.             push('Method resolution order:')
  1160.             for base in mro:
  1161.                 push('    ' + makename(base))
  1162.             
  1163.             push('')
  1164.         
  1165.         
  1166.         class HorizontalRule(()):
  1167.             
  1168.             def __init__(self):
  1169.                 self.needone = 0
  1170.  
  1171.             
  1172.             def maybe(self):
  1173.                 if self.needone:
  1174.                     push('-' * 70)
  1175.                 
  1176.                 self.needone = 1
  1177.  
  1178.  
  1179.         hr = HorizontalRule()
  1180.         
  1181.         def spill(msg, attrs, predicate):
  1182.             (ok, attrs) = _split_list(attrs, predicate)
  1183.             if ok:
  1184.                 hr.maybe()
  1185.                 push(msg)
  1186.                 for name, kind, homecls, value in ok:
  1187.                     push(self.document(getattr(object, name), name, mod, object))
  1188.                 
  1189.             
  1190.             return attrs
  1191.  
  1192.         
  1193.         def spilldescriptors(msg, attrs, predicate):
  1194.             (ok, attrs) = _split_list(attrs, predicate)
  1195.             if ok:
  1196.                 hr.maybe()
  1197.                 push(msg)
  1198.                 for name, kind, homecls, value in ok:
  1199.                     push(self._docdescriptor(name, value, mod))
  1200.                 
  1201.             
  1202.             return attrs
  1203.  
  1204.         
  1205.         def spilldata(msg, attrs, predicate):
  1206.             (ok, attrs) = _split_list(attrs, predicate)
  1207.             if ok:
  1208.                 hr.maybe()
  1209.                 push(msg)
  1210.                 for name, kind, homecls, value in ok:
  1211.                     if hasattr(value, '__call__') or inspect.isdatadescriptor(value):
  1212.                         doc = getdoc(value)
  1213.                     else:
  1214.                         doc = None
  1215.                     push(self.docother(getattr(object, name), name, mod, maxlen = 70, doc = doc) + '\n')
  1216.                 
  1217.             
  1218.             return attrs
  1219.  
  1220.         attrs = filter((lambda data: visiblename(data[0])), classify_class_attrs(object))
  1221.         while attrs:
  1222.             if mro:
  1223.                 thisclass = mro.popleft()
  1224.             else:
  1225.                 thisclass = attrs[0][2]
  1226.             (attrs, inherited) = _split_list((attrs,), (lambda t: t[2] is thisclass))
  1227.             if thisclass is __builtin__.object:
  1228.                 attrs = inherited
  1229.                 continue
  1230.             elif thisclass is object:
  1231.                 tag = 'defined here'
  1232.             else:
  1233.                 tag = 'inherited from %s' % classname(thisclass, object.__module__)
  1234.             attrs.sort()
  1235.             attrs = spill('Methods %s:\n' % tag, attrs, (lambda t: t[1] == 'method'))
  1236.             attrs = spill('Class methods %s:\n' % tag, attrs, (lambda t: t[1] == 'class method'))
  1237.             attrs = spill('Static methods %s:\n' % tag, attrs, (lambda t: t[1] == 'static method'))
  1238.             attrs = spilldescriptors('Data descriptors %s:\n' % tag, attrs, (lambda t: t[1] == 'data descriptor'))
  1239.             attrs = spilldata('Data and other attributes %s:\n' % tag, attrs, (lambda t: t[1] == 'data'))
  1240.             attrs = inherited
  1241.         contents = '\n'.join(contents)
  1242.         if not contents:
  1243.             return title + '\n'
  1244.         return title + '\n' + self.indent(rstrip(contents), ' |  ') + '\n'
  1245.  
  1246.     
  1247.     def formatvalue(self, object):
  1248.         return '=' + self.repr(object)
  1249.  
  1250.     
  1251.     def docroutine(self, object, name = None, mod = None, cl = None):
  1252.         realname = object.__name__
  1253.         if not name:
  1254.             pass
  1255.         name = realname
  1256.         note = ''
  1257.         skipdocs = 0
  1258.         if inspect.ismethod(object):
  1259.             imclass = object.im_class
  1260.             if cl:
  1261.                 if imclass is not cl:
  1262.                     note = ' from ' + classname(imclass, mod)
  1263.                 
  1264.             elif object.im_self is not None:
  1265.                 note = ' method of %s instance' % classname(object.im_self.__class__, mod)
  1266.             else:
  1267.                 note = ' unbound %s method' % classname(imclass, mod)
  1268.             object = object.im_func
  1269.         
  1270.         if name == realname:
  1271.             title = self.bold(realname)
  1272.         elif cl and realname in cl.__dict__ and cl.__dict__[realname] is object:
  1273.             skipdocs = 1
  1274.         
  1275.         title = self.bold(name) + ' = ' + realname
  1276.         if inspect.isfunction(object):
  1277.             (args, varargs, varkw, defaults) = inspect.getargspec(object)
  1278.             argspec = inspect.formatargspec(args, varargs, varkw, defaults, formatvalue = self.formatvalue)
  1279.             if realname == '<lambda>':
  1280.                 title = self.bold(name) + ' lambda '
  1281.                 argspec = argspec[1:-1]
  1282.             
  1283.         else:
  1284.             argspec = '(...)'
  1285.         decl = title + argspec + note
  1286.         if skipdocs:
  1287.             return decl + '\n'
  1288.         if not getdoc(object):
  1289.             pass
  1290.         doc = ''
  1291.         if doc:
  1292.             pass
  1293.         return decl + '\n' + rstrip(self.indent(doc)) + '\n'
  1294.  
  1295.     
  1296.     def _docdescriptor(self, name, value, mod):
  1297.         results = []
  1298.         push = results.append
  1299.         if name:
  1300.             push(self.bold(name))
  1301.             push('\n')
  1302.         
  1303.         if not getdoc(value):
  1304.             pass
  1305.         doc = ''
  1306.         if doc:
  1307.             push(self.indent(doc))
  1308.             push('\n')
  1309.         
  1310.         return ''.join(results)
  1311.  
  1312.     
  1313.     def docproperty(self, object, name = None, mod = None, cl = None):
  1314.         return self._docdescriptor(name, object, mod)
  1315.  
  1316.     
  1317.     def docdata(self, object, name = None, mod = None, cl = None):
  1318.         return self._docdescriptor(name, object, mod)
  1319.  
  1320.     
  1321.     def docother(self, object, name = None, mod = None, parent = None, maxlen = None, doc = None):
  1322.         repr = self.repr(object)
  1323.         if maxlen:
  1324.             if not name or name + ' = ':
  1325.                 pass
  1326.             line = '' + repr
  1327.             chop = maxlen - len(line)
  1328.             if chop < 0:
  1329.                 repr = repr[:chop] + '...'
  1330.             
  1331.         
  1332.         if not name or self.bold(name) + ' = ':
  1333.             pass
  1334.         line = '' + repr
  1335.         if doc is not None:
  1336.             line += '\n' + self.indent(str(doc))
  1337.         
  1338.         return line
  1339.  
  1340.  
  1341.  
  1342. def pager(text):
  1343.     global pager
  1344.     pager = getpager()
  1345.     pager(text)
  1346.  
  1347.  
  1348. def getpager():
  1349.     if type(sys.stdout) is not types.FileType:
  1350.         return plainpager
  1351.     if not sys.stdin.isatty() or not sys.stdout.isatty():
  1352.         return plainpager
  1353.     if 'PAGER' in os.environ:
  1354.         if sys.platform == 'win32':
  1355.             return (lambda text: tempfilepager(plain(text), os.environ['PAGER']))
  1356.         if os.environ.get('TERM') in ('dumb', 'emacs'):
  1357.             return (lambda text: pipepager(plain(text), os.environ['PAGER']))
  1358.         return (lambda text: pipepager(text, os.environ['PAGER']))
  1359.     'PAGER' in os.environ
  1360.     if os.environ.get('TERM') in ('dumb', 'emacs'):
  1361.         return plainpager
  1362.     if sys.platform == 'win32' or sys.platform.startswith('os2'):
  1363.         return (lambda text: tempfilepager(plain(text), 'more <'))
  1364.     if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:
  1365.         return (lambda text: pipepager(text, 'less'))
  1366.     import tempfile
  1367.     (fd, filename) = tempfile.mkstemp()
  1368.     os.close(fd)
  1369.     
  1370.     try:
  1371.         if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0:
  1372.             return (lambda text: pipepager(text, 'more'))
  1373.         return ttypager
  1374.     finally:
  1375.         os.unlink(filename)
  1376.  
  1377.  
  1378.  
  1379. def plain(text):
  1380.     return re.sub('.\x08', '', text)
  1381.  
  1382.  
  1383. def pipepager(text, cmd):
  1384.     pipe = os.popen(cmd, 'w')
  1385.     
  1386.     try:
  1387.         pipe.write(text)
  1388.         pipe.close()
  1389.     except IOError:
  1390.         pass
  1391.  
  1392.  
  1393.  
  1394. def tempfilepager(text, cmd):
  1395.     import tempfile
  1396.     filename = tempfile.mktemp()
  1397.     file = open(filename, 'w')
  1398.     file.write(text)
  1399.     file.close()
  1400.     
  1401.     try:
  1402.         os.system(cmd + ' "' + filename + '"')
  1403.     finally:
  1404.         os.unlink(filename)
  1405.  
  1406.  
  1407.  
  1408. def ttypager(text):
  1409.     lines = split(plain(text), '\n')
  1410.     
  1411.     try:
  1412.         import tty
  1413.         fd = sys.stdin.fileno()
  1414.         old = tty.tcgetattr(fd)
  1415.         tty.setcbreak(fd)
  1416.         
  1417.         getchar = lambda : sys.stdin.read(1)
  1418.     except (ImportError, AttributeError):
  1419.         tty = None
  1420.         
  1421.         getchar = lambda : sys.stdin.readline()[:-1][:1]
  1422.  
  1423.     
  1424.     try:
  1425.         r = inc = os.environ.get('LINES', 25) - 1
  1426.         sys.stdout.write(join(lines[:inc], '\n') + '\n')
  1427.         while lines[r:]:
  1428.             sys.stdout.write('-- more --')
  1429.             sys.stdout.flush()
  1430.             c = getchar()
  1431.             if c in ('q', 'Q'):
  1432.                 sys.stdout.write('\r          \r')
  1433.                 break
  1434.             elif c in ('\r', '\n'):
  1435.                 sys.stdout.write('\r          \r' + lines[r] + '\n')
  1436.                 r = r + 1
  1437.                 continue
  1438.             
  1439.             if c in ('b', 'B', '\x1b'):
  1440.                 r = r - inc - inc
  1441.                 if r < 0:
  1442.                     r = 0
  1443.                 
  1444.             
  1445.             sys.stdout.write('\n' + join(lines[r:r + inc], '\n') + '\n')
  1446.             r = r + inc
  1447.     finally:
  1448.         if tty:
  1449.             tty.tcsetattr(fd, tty.TCSAFLUSH, old)
  1450.         
  1451.  
  1452.  
  1453.  
  1454. def plainpager(text):
  1455.     sys.stdout.write(plain(text))
  1456.  
  1457.  
  1458. def describe(thing):
  1459.     if inspect.ismodule(thing):
  1460.         if thing.__name__ in sys.builtin_module_names:
  1461.             return 'built-in module ' + thing.__name__
  1462.         if hasattr(thing, '__path__'):
  1463.             return 'package ' + thing.__name__
  1464.         return 'module ' + thing.__name__
  1465.     inspect.ismodule(thing)
  1466.     if inspect.isbuiltin(thing):
  1467.         return 'built-in function ' + thing.__name__
  1468.     if inspect.isgetsetdescriptor(thing):
  1469.         return 'getset descriptor %s.%s.%s' % (thing.__objclass__.__module__, thing.__objclass__.__name__, thing.__name__)
  1470.     if inspect.ismemberdescriptor(thing):
  1471.         return 'member descriptor %s.%s.%s' % (thing.__objclass__.__module__, thing.__objclass__.__name__, thing.__name__)
  1472.     if inspect.isclass(thing):
  1473.         return 'class ' + thing.__name__
  1474.     if inspect.isfunction(thing):
  1475.         return 'function ' + thing.__name__
  1476.     if inspect.ismethod(thing):
  1477.         return 'method ' + thing.__name__
  1478.     if type(thing) is types.InstanceType:
  1479.         return 'instance of ' + thing.__class__.__name__
  1480.     return type(thing).__name__
  1481.  
  1482.  
  1483. def locate(path, forceload = 0):
  1484.     parts = _[1]
  1485.     (module, n) = (None, 0)
  1486.     while n < len(parts):
  1487.         nextmodule = safeimport(join(parts[:n + 1], '.'), forceload)
  1488.         if nextmodule:
  1489.             module = nextmodule
  1490.             n = n + 1
  1491.             continue
  1492.         []
  1493.         break
  1494.         continue
  1495.         []
  1496.     if module:
  1497.         object = module
  1498.         for part in parts[n:]:
  1499.             
  1500.             try:
  1501.                 object = getattr(object, part)
  1502.             continue
  1503.             except AttributeError:
  1504.                 return None
  1505.             
  1506.  
  1507.         
  1508.         return object
  1509.     if hasattr(__builtin__, path):
  1510.         return getattr(__builtin__, path)
  1511.  
  1512. text = TextDoc()
  1513. html = HTMLDoc()
  1514.  
  1515. class _OldStyleClass:
  1516.     pass
  1517.  
  1518. _OLD_INSTANCE_TYPE = type(_OldStyleClass())
  1519.  
  1520. def resolve(thing, forceload = 0):
  1521.     if isinstance(thing, str):
  1522.         object = locate(thing, forceload)
  1523.         if not object:
  1524.             raise ImportError, 'no Python documentation found for %r' % thing
  1525.         object
  1526.         return (object, thing)
  1527.     return (thing, getattr(thing, '__name__', None))
  1528.  
  1529.  
  1530. def render_doc(thing, title = 'Python Library Documentation: %s', forceload = 0):
  1531.     (object, name) = resolve(thing, forceload)
  1532.     desc = describe(object)
  1533.     module = inspect.getmodule(object)
  1534.     if name and '.' in name:
  1535.         desc += ' in ' + name[:name.rfind('.')]
  1536.     elif module and module is not object:
  1537.         desc += ' in module ' + module.__name__
  1538.     
  1539.     if type(object) is _OLD_INSTANCE_TYPE:
  1540.         object = object.__class__
  1541.     elif not inspect.ismodule(object) and inspect.isclass(object) and inspect.isroutine(object) and inspect.isgetsetdescriptor(object) and inspect.ismemberdescriptor(object) or isinstance(object, property):
  1542.         object = type(object)
  1543.         desc += ' object'
  1544.     
  1545.     return title % desc + '\n\n' + text.document(object, name)
  1546.  
  1547.  
  1548. def doc(thing, title = 'Python Library Documentation: %s', forceload = 0):
  1549.     
  1550.     try:
  1551.         pager(render_doc(thing, title, forceload))
  1552.     except (ImportError, ErrorDuringImport):
  1553.         value = None
  1554.         print value
  1555.  
  1556.  
  1557.  
  1558. def writedoc(thing, forceload = 0):
  1559.     
  1560.     try:
  1561.         (object, name) = resolve(thing, forceload)
  1562.         page = html.page(describe(object), html.document(object, name))
  1563.         file = open(name + '.html', 'w')
  1564.         file.write(page)
  1565.         file.close()
  1566.         print 'wrote', name + '.html'
  1567.     except (ImportError, ErrorDuringImport):
  1568.         value = None
  1569.         print value
  1570.  
  1571.  
  1572.  
  1573. def writedocs(dir, pkgpath = '', done = None):
  1574.     if done is None:
  1575.         done = { }
  1576.     
  1577.     for importer, modname, ispkg in pkgutil.walk_packages([
  1578.         dir], pkgpath):
  1579.         writedoc(modname)
  1580.     
  1581.  
  1582.  
  1583. class Helper:
  1584.     keywords = {
  1585.         'and': 'BOOLEAN',
  1586.         'as': 'with',
  1587.         'assert': ('assert', ''),
  1588.         'break': ('break', 'while for'),
  1589.         'class': ('class', 'CLASSES SPECIALMETHODS'),
  1590.         'continue': ('continue', 'while for'),
  1591.         'def': ('function', ''),
  1592.         'del': ('del', 'BASICMETHODS'),
  1593.         'elif': 'if',
  1594.         'else': ('else', 'while for'),
  1595.         'except': 'try',
  1596.         'exec': ('exec', ''),
  1597.         'finally': 'try',
  1598.         'for': ('for', 'break continue while'),
  1599.         'from': 'import',
  1600.         'global': ('global', 'NAMESPACES'),
  1601.         'if': ('if', 'TRUTHVALUE'),
  1602.         'import': ('import', 'MODULES'),
  1603.         'in': ('in', 'SEQUENCEMETHODS2'),
  1604.         'is': 'COMPARISON',
  1605.         'lambda': ('lambda', 'FUNCTIONS'),
  1606.         'not': 'BOOLEAN',
  1607.         'or': 'BOOLEAN',
  1608.         'pass': ('pass', ''),
  1609.         'print': ('print', ''),
  1610.         'raise': ('raise', 'EXCEPTIONS'),
  1611.         'return': ('return', 'FUNCTIONS'),
  1612.         'try': ('try', 'EXCEPTIONS'),
  1613.         'while': ('while', 'break continue if TRUTHVALUE'),
  1614.         'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
  1615.         'yield': ('yield', '') }
  1616.     _symbols_inverse = {
  1617.         'STRINGS': ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'),
  1618.         'OPERATORS': ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),
  1619.         'COMPARISON': ('<', '>', '<=', '>=', '==', '!=', '<>'),
  1620.         'UNARY': ('-', '~'),
  1621.         'AUGMENTEDASSIGNMENT': ('+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=', '<<=', '>>=', '**=', '//='),
  1622.         'BITWISE': ('<<', '>>', '&', '|', '^', '~'),
  1623.         'COMPLEX': ('j', 'J') }
  1624.     symbols = {
  1625.         '%': 'OPERATORS FORMATTING',
  1626.         '**': 'POWER',
  1627.         ',': 'TUPLES LISTS FUNCTIONS',
  1628.         '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',
  1629.         '...': 'ELLIPSIS',
  1630.         ':': 'SLICINGS DICTIONARYLITERALS',
  1631.         '@': 'def class',
  1632.         '\\': 'STRINGS',
  1633.         '_': 'PRIVATENAMES',
  1634.         '__': 'PRIVATENAMES SPECIALMETHODS',
  1635.         '`': 'BACKQUOTES',
  1636.         '(': 'TUPLES FUNCTIONS CALLS',
  1637.         ')': 'TUPLES FUNCTIONS CALLS',
  1638.         '[': 'LISTS SUBSCRIPTS SLICINGS',
  1639.         ']': 'LISTS SUBSCRIPTS SLICINGS' }
  1640.     for topic, symbols_ in _symbols_inverse.iteritems():
  1641.         for symbol in symbols_:
  1642.             topics = symbols.get(symbol, topic)
  1643.             if topic not in topics:
  1644.                 topics = topics + ' ' + topic
  1645.             
  1646.             symbols[symbol] = topics
  1647.         
  1648.     
  1649.     topics = {
  1650.         'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS FUNCTIONS CLASSES MODULES FILES inspect'),
  1651.         'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING TYPES'),
  1652.         'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'),
  1653.         'FORMATTING': ('formatstrings', 'OPERATORS'),
  1654.         'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS FORMATTING TYPES'),
  1655.         'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'),
  1656.         'INTEGER': ('integers', 'int range'),
  1657.         'FLOAT': ('floating', 'float math'),
  1658.         'COMPLEX': ('imaginary', 'complex cmath'),
  1659.         'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING xrange LISTS'),
  1660.         'MAPPINGS': 'DICTIONARIES',
  1661.         'FUNCTIONS': ('typesfunctions', 'def TYPES'),
  1662.         'METHODS': ('typesmethods', 'class def CLASSES TYPES'),
  1663.         'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'),
  1664.         'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'),
  1665.         'FRAMEOBJECTS': 'TYPES',
  1666.         'TRACEBACKS': 'TYPES',
  1667.         'NONE': ('bltin-null-object', ''),
  1668.         'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'),
  1669.         'FILES': ('bltin-file-objects', ''),
  1670.         'SPECIALATTRIBUTES': ('specialattrs', ''),
  1671.         'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'),
  1672.         'MODULES': ('typesmodules', 'import'),
  1673.         'PACKAGES': 'import',
  1674.         'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES LISTS DICTIONARIES BACKQUOTES'),
  1675.         'OPERATORS': 'EXPRESSIONS',
  1676.         'PRECEDENCE': 'EXPRESSIONS',
  1677.         'OBJECTS': ('objects', 'TYPES'),
  1678.         'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
  1679.         'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'),
  1680.         'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
  1681.         'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
  1682.         'SEQUENCEMETHODS1': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 SPECIALMETHODS'),
  1683.         'SEQUENCEMETHODS2': ('sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 SPECIALMETHODS'),
  1684.         'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),
  1685.         'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT SPECIALMETHODS'),
  1686.         'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),
  1687.         'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'),
  1688.         'DYNAMICFEATURES': ('dynamic-features', ''),
  1689.         'SCOPING': 'NAMESPACES',
  1690.         'FRAMES': 'NAMESPACES',
  1691.         'EXCEPTIONS': ('exceptions', 'try except finally raise'),
  1692.         'COERCIONS': ('coercion-rules', 'CONVERSIONS'),
  1693.         'CONVERSIONS': ('conversions', 'COERCIONS'),
  1694.         'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'),
  1695.         'SPECIALIDENTIFIERS': ('id-classes', ''),
  1696.         'PRIVATENAMES': ('atom-identifiers', ''),
  1697.         'LITERALS': ('atom-literals', 'STRINGS BACKQUOTES NUMBERS TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'),
  1698.         'TUPLES': 'SEQUENCES',
  1699.         'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'),
  1700.         'LISTS': ('typesseq-mutable', 'LISTLITERALS'),
  1701.         'LISTLITERALS': ('lists', 'LISTS LITERALS'),
  1702.         'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),
  1703.         'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),
  1704.         'BACKQUOTES': ('string-conversions', 'repr str STRINGS LITERALS'),
  1705.         'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'),
  1706.         'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'),
  1707.         'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'),
  1708.         'CALLS': ('calls', 'EXPRESSIONS'),
  1709.         'POWER': ('power', 'EXPRESSIONS'),
  1710.         'UNARY': ('unary', 'EXPRESSIONS'),
  1711.         'BINARY': ('binary', 'EXPRESSIONS'),
  1712.         'SHIFTING': ('shifting', 'EXPRESSIONS'),
  1713.         'BITWISE': ('bitwise', 'EXPRESSIONS'),
  1714.         'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'),
  1715.         'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'),
  1716.         'ASSERTION': 'assert',
  1717.         'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'),
  1718.         'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'),
  1719.         'DELETION': 'del',
  1720.         'PRINTING': 'print',
  1721.         'RETURNING': 'return',
  1722.         'IMPORTING': 'import',
  1723.         'CONDITIONAL': 'if',
  1724.         'LOOPING': ('compound', 'for while break continue'),
  1725.         'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'),
  1726.         'DEBUGGING': ('debugger', 'pdb'),
  1727.         'CONTEXTMANAGERS': ('context-managers', 'with') }
  1728.     
  1729.     def __init__(self, input, output):
  1730.         self.input = input
  1731.         self.output = output
  1732.  
  1733.     
  1734.     def __repr__(self):
  1735.         if inspect.stack()[1][3] == '?':
  1736.             self()
  1737.             return ''
  1738.         return '<pydoc.Helper instance>'
  1739.  
  1740.     
  1741.     def __call__(self, request = None):
  1742.         if request is not None:
  1743.             self.help(request)
  1744.         else:
  1745.             self.intro()
  1746.             self.interact()
  1747.             self.output.write('\nYou are now leaving help and returning to the Python interpreter.\nIf you want to ask for help on a particular object directly from the\ninterpreter, you can type "help(object)".  Executing "help(\'string\')"\nhas the same effect as typing a particular string at the help> prompt.\n')
  1748.  
  1749.     
  1750.     def interact(self):
  1751.         self.output.write('\n')
  1752.         while True:
  1753.             
  1754.             try:
  1755.                 request = self.getline('help> ')
  1756.                 if not request:
  1757.                     break
  1758.             except (KeyboardInterrupt, EOFError):
  1759.                 break
  1760.  
  1761.             request = strip(replace(request, '"', '', "'", ''))
  1762.             if lower(request) in ('q', 'quit'):
  1763.                 break
  1764.             
  1765.             self.help(request)
  1766.  
  1767.     
  1768.     def getline(self, prompt):
  1769.         if self.input is sys.stdin:
  1770.             return raw_input(prompt)
  1771.         self.output.write(prompt)
  1772.         self.output.flush()
  1773.         return self.input.readline()
  1774.  
  1775.     
  1776.     def help(self, request):
  1777.         if type(request) is type(''):
  1778.             request = request.strip()
  1779.             if request == 'help':
  1780.                 self.intro()
  1781.             elif request == 'keywords':
  1782.                 self.listkeywords()
  1783.             elif request == 'symbols':
  1784.                 self.listsymbols()
  1785.             elif request == 'topics':
  1786.                 self.listtopics()
  1787.             elif request == 'modules':
  1788.                 self.listmodules()
  1789.             elif request[:8] == 'modules ':
  1790.                 self.listmodules(split(request)[1])
  1791.             elif request in self.symbols:
  1792.                 self.showsymbol(request)
  1793.             elif request in self.keywords:
  1794.                 self.showtopic(request)
  1795.             elif request in self.topics:
  1796.                 self.showtopic(request)
  1797.             elif request:
  1798.                 doc(request, 'Help on %s:')
  1799.             
  1800.         elif isinstance(request, Helper):
  1801.             self()
  1802.         else:
  1803.             doc(request, 'Help on %s:')
  1804.         self.output.write('\n')
  1805.  
  1806.     
  1807.     def intro(self):
  1808.         self.output.write('\nWelcome to Python %s!  This is the online help utility.\n\nIf this is your first time using Python, you should definitely check out\nthe tutorial on the Internet at http://docs.python.org/tutorial/.\n\nEnter the name of any module, keyword, or topic to get help on writing\nPython programs and using Python modules.  To quit this help utility and\nreturn to the interpreter, just type "quit".\n\nTo get a list of available modules, keywords, or topics, type "modules",\n"keywords", or "topics".  Each module also comes with a one-line summary\nof what it does; to list the modules whose summaries contain a given word\nsuch as "spam", type "modules spam".\n' % sys.version[:3])
  1809.  
  1810.     
  1811.     def list(self, items, columns = 4, width = 80):
  1812.         items = items[:]
  1813.         items.sort()
  1814.         colw = width / columns
  1815.         rows = (len(items) + columns - 1) / columns
  1816.         for row in range(rows):
  1817.             for col in range(columns):
  1818.                 i = col * rows + row
  1819.                 if i < len(items):
  1820.                     self.output.write(items[i])
  1821.                     if col < columns - 1:
  1822.                         self.output.write(' ' + ' ' * (colw - 1 - len(items[i])))
  1823.                     
  1824.                 col < columns - 1
  1825.             
  1826.             self.output.write('\n')
  1827.         
  1828.  
  1829.     
  1830.     def listkeywords(self):
  1831.         self.output.write('\nHere is a list of the Python keywords.  Enter any keyword to get more help.\n\n')
  1832.         self.list(self.keywords.keys())
  1833.  
  1834.     
  1835.     def listsymbols(self):
  1836.         self.output.write('\nHere is a list of the punctuation symbols which Python assigns special meaning\nto. Enter any symbol to get more help.\n\n')
  1837.         self.list(self.symbols.keys())
  1838.  
  1839.     
  1840.     def listtopics(self):
  1841.         self.output.write('\nHere is a list of available topics.  Enter any topic name to get more help.\n\n')
  1842.         self.list(self.topics.keys())
  1843.  
  1844.     
  1845.     def showtopic(self, topic, more_xrefs = ''):
  1846.         
  1847.         try:
  1848.             import pydoc_topics
  1849.         except ImportError:
  1850.             self.output.write('\nSorry, topic and keyword documentation is not available because the\nmodule "pydoc_topics" could not be found.\n')
  1851.             return None
  1852.  
  1853.         target = self.topics.get(topic, self.keywords.get(topic))
  1854.         if not target:
  1855.             self.output.write('no documentation found for %s\n' % repr(topic))
  1856.             return None
  1857.         if type(target) is type(''):
  1858.             return self.showtopic(target, more_xrefs)
  1859.         (label, xrefs) = target
  1860.         
  1861.         try:
  1862.             doc = pydoc_topics.topics[label]
  1863.         except KeyError:
  1864.             type(target) is type('')
  1865.             type(target) is type('')
  1866.             target
  1867.             self.output.write('no documentation found for %s\n' % repr(topic))
  1868.             return None
  1869.  
  1870.         pager(strip(doc) + '\n')
  1871.         if xrefs:
  1872.             import StringIO
  1873.             import formatter
  1874.             buffer = StringIO.StringIO()
  1875.             formatter.DumbWriter(buffer).send_flowing_data('Related help topics: ' + join(split(xrefs), ', ') + '\n')
  1876.             self.output.write('\n%s\n' % buffer.getvalue())
  1877.         
  1878.  
  1879.     
  1880.     def showsymbol(self, symbol):
  1881.         target = self.symbols[symbol]
  1882.         (topic, _, xrefs) = target.partition(' ')
  1883.         self.showtopic(topic, xrefs)
  1884.  
  1885.     
  1886.     def listmodules(self, key = ''):
  1887.         pass
  1888.  
  1889.  
  1890. help = Helper(sys.stdin, sys.stdout)
  1891.  
  1892. class Scanner:
  1893.     
  1894.     def __init__(self, roots, children, descendp):
  1895.         self.roots = roots[:]
  1896.         self.state = []
  1897.         self.children = children
  1898.         self.descendp = descendp
  1899.  
  1900.     
  1901.     def next(self):
  1902.         if not self.state:
  1903.             if not self.roots:
  1904.                 return None
  1905.             root = self.roots.pop(0)
  1906.             self.state = [
  1907.                 (root, self.children(root))]
  1908.         
  1909.         (node, children) = self.state[-1]
  1910.         if not children:
  1911.             self.state.pop()
  1912.             return self.next()
  1913.         child = children.pop(0)
  1914.         if self.descendp(child):
  1915.             self.state.append((child, self.children(child)))
  1916.         
  1917.         return child
  1918.  
  1919.  
  1920.  
  1921. class ModuleScanner:
  1922.     
  1923.     def run(self, callback, key = None, completer = None, onerror = None):
  1924.         if key:
  1925.             key = lower(key)
  1926.         
  1927.         self.quit = False
  1928.         seen = { }
  1929.         for modname in sys.builtin_module_names:
  1930.             if modname != '__main__':
  1931.                 seen[modname] = 1
  1932.                 if key is None:
  1933.                     callback(None, modname, '')
  1934.                 elif not __import__(modname).__doc__:
  1935.                     pass
  1936.                 desc = split('', '\n')[0]
  1937.                 if find(lower(modname + ' - ' + desc), key) >= 0:
  1938.                     callback(None, modname, desc)
  1939.                 
  1940.             find(lower(modname + ' - ' + desc), key) >= 0
  1941.         
  1942.         for importer, modname, ispkg in pkgutil.walk_packages(onerror = onerror):
  1943.             if self.quit:
  1944.                 break
  1945.             
  1946.             if key is None:
  1947.                 callback(None, modname, '')
  1948.                 continue
  1949.             loader = importer.find_module(modname)
  1950.             if hasattr(loader, 'get_source'):
  1951.                 import StringIO
  1952.                 if not source_synopsis(StringIO.StringIO(loader.get_source(modname))):
  1953.                     pass
  1954.                 desc = ''
  1955.                 if hasattr(loader, 'get_filename'):
  1956.                     path = loader.get_filename(modname)
  1957.                 else:
  1958.                     path = None
  1959.             else:
  1960.                 module = loader.load_module(modname)
  1961.                 if not module.__doc__:
  1962.                     pass
  1963.                 desc = ''.splitlines()[0]
  1964.                 path = getattr(module, '__file__', None)
  1965.             if find(lower(modname + ' - ' + desc), key) >= 0:
  1966.                 callback(path, modname, desc)
  1967.                 continue
  1968.         
  1969.         if completer:
  1970.             completer()
  1971.         
  1972.  
  1973.  
  1974.  
  1975. def apropos(key):
  1976.     
  1977.     def callback(path, modname, desc):
  1978.         if modname[-9:] == '.__init__':
  1979.             modname = modname[:-9] + ' (package)'
  1980.         
  1981.         print modname,
  1982.         if desc:
  1983.             pass
  1984.         print '- ' + desc
  1985.  
  1986.     
  1987.     try:
  1988.         import warnings
  1989.     except ImportError:
  1990.         pass
  1991.  
  1992.     warnings.filterwarnings('ignore')
  1993.     ModuleScanner().run(callback, key)
  1994.  
  1995.  
  1996. def serve(port, callback = None, completer = None):
  1997.     import BaseHTTPServer
  1998.     import mimetools
  1999.     import select
  2000.     
  2001.     class Message(mimetools.Message):
  2002.         
  2003.         def __init__(self, fp, seekable = 1):
  2004.             Message = self.__class__
  2005.             Message.__bases__[0].__bases__[0].__init__(self, fp, seekable)
  2006.             self.encodingheader = self.getheader('content-transfer-encoding')
  2007.             self.typeheader = self.getheader('content-type')
  2008.             self.parsetype()
  2009.             self.parseplist()
  2010.  
  2011.  
  2012.     
  2013.     class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  2014.         
  2015.         def send_document(self, title, contents):
  2016.             
  2017.             try:
  2018.                 self.send_response(200)
  2019.                 self.send_header('Content-Type', 'text/html')
  2020.                 self.end_headers()
  2021.                 self.wfile.write(html.page(title, contents))
  2022.             except IOError:
  2023.                 pass
  2024.  
  2025.  
  2026.         
  2027.         def do_GET(self):
  2028.             path = self.path
  2029.             if path[-5:] == '.html':
  2030.                 path = path[:-5]
  2031.             
  2032.             if path[:1] == '/':
  2033.                 path = path[1:]
  2034.             
  2035.             if path and path != '.':
  2036.                 
  2037.                 try:
  2038.                     obj = locate(path, forceload = 1)
  2039.                 except ErrorDuringImport:
  2040.                     value = None
  2041.                     self.send_document(path, html.escape(str(value)))
  2042.                     return None
  2043.  
  2044.                 if obj:
  2045.                     self.send_document(describe(obj), html.document(obj, path))
  2046.                 else:
  2047.                     self.send_document(path, 'no Python documentation found for %s' % repr(path))
  2048.             else:
  2049.                 heading = html.heading('<big><big><strong>Python: Index of Modules</strong></big></big>', '#ffffff', '#7799ee')
  2050.                 
  2051.                 def bltinlink(name):
  2052.                     return '<a href="%s.html">%s</a>' % (name, name)
  2053.  
  2054.                 names = filter((lambda x: x != '__main__'), sys.builtin_module_names)
  2055.                 contents = html.multicolumn(names, bltinlink)
  2056.                 indices = [
  2057.                     '<p>' + html.bigsection('Built-in Modules', '#ffffff', '#ee77aa', contents)]
  2058.                 seen = { }
  2059.                 for dir in sys.path:
  2060.                     indices.append(html.index(dir, seen))
  2061.                 
  2062.                 contents = heading + join(indices) + '<p align=right>\n<font color="#909090" face="helvetica, arial"><strong>\npydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'
  2063.                 self.send_document('Index of Modules', contents)
  2064.  
  2065.         
  2066.         def log_message(self, *args):
  2067.             pass
  2068.  
  2069.  
  2070.     
  2071.     class DocServer(BaseHTTPServer.HTTPServer):
  2072.         
  2073.         def __init__(self, port, callback):
  2074.             if not sys.platform == 'mac' or '127.0.0.1':
  2075.                 pass
  2076.             host = 'localhost'
  2077.             self.address = ('', port)
  2078.             self.url = 'http://%s:%d/' % (host, port)
  2079.             self.callback = callback
  2080.             self.base.__init__(self, self.address, self.handler)
  2081.  
  2082.         
  2083.         def serve_until_quit(self):
  2084.             import select
  2085.             self.quit = False
  2086.             while not self.quit:
  2087.                 (rd, wr, ex) = select.select([
  2088.                     self.socket.fileno()], [], [], 1)
  2089.                 if rd:
  2090.                     self.handle_request()
  2091.                     continue
  2092.  
  2093.         
  2094.         def server_activate(self):
  2095.             self.base.server_activate(self)
  2096.             if self.callback:
  2097.                 self.callback(self)
  2098.             
  2099.  
  2100.  
  2101.     DocServer.base = BaseHTTPServer.HTTPServer
  2102.     DocServer.handler = DocHandler
  2103.     DocHandler.MessageClass = Message
  2104.     
  2105.     try:
  2106.         DocServer(port, callback).serve_until_quit()
  2107.     except (KeyboardInterrupt, select.error):
  2108.         pass
  2109.     finally:
  2110.         if completer:
  2111.             completer()
  2112.         
  2113.  
  2114.  
  2115.  
  2116. def gui():
  2117.     
  2118.     class GUI:
  2119.         
  2120.         def __init__(self, window, port = 7464):
  2121.             self.window = window
  2122.             self.server = None
  2123.             self.scanner = None
  2124.             import Tkinter
  2125.             self.server_frm = Tkinter.Frame(window)
  2126.             self.title_lbl = Tkinter.Label(self.server_frm, text = 'Starting server...\n ')
  2127.             self.open_btn = Tkinter.Button(self.server_frm, text = 'open browser', command = self.open, state = 'disabled')
  2128.             self.quit_btn = Tkinter.Button(self.server_frm, text = 'quit serving', command = self.quit, state = 'disabled')
  2129.             self.search_frm = Tkinter.Frame(window)
  2130.             self.search_lbl = Tkinter.Label(self.search_frm, text = 'Search for')
  2131.             self.search_ent = Tkinter.Entry(self.search_frm)
  2132.             self.search_ent.bind('<Return>', self.search)
  2133.             self.stop_btn = Tkinter.Button(self.search_frm, text = 'stop', pady = 0, command = self.stop, state = 'disabled')
  2134.             if sys.platform == 'win32':
  2135.                 self.stop_btn.pack(side = 'right')
  2136.             
  2137.             self.window.title('pydoc')
  2138.             self.window.protocol('WM_DELETE_WINDOW', self.quit)
  2139.             self.title_lbl.pack(side = 'top', fill = 'x')
  2140.             self.open_btn.pack(side = 'left', fill = 'x', expand = 1)
  2141.             self.quit_btn.pack(side = 'right', fill = 'x', expand = 1)
  2142.             self.server_frm.pack(side = 'top', fill = 'x')
  2143.             self.search_lbl.pack(side = 'left')
  2144.             self.search_ent.pack(side = 'right', fill = 'x', expand = 1)
  2145.             self.search_frm.pack(side = 'top', fill = 'x')
  2146.             self.search_ent.focus_set()
  2147.             if not sys.platform == 'win32' or 8:
  2148.                 pass
  2149.             font = ('helvetica', 10)
  2150.             self.result_lst = Tkinter.Listbox(window, font = font, height = 6)
  2151.             self.result_lst.bind('<Button-1>', self.select)
  2152.             self.result_lst.bind('<Double-Button-1>', self.goto)
  2153.             self.result_scr = Tkinter.Scrollbar(window, orient = 'vertical', command = self.result_lst.yview)
  2154.             self.result_lst.config(yscrollcommand = self.result_scr.set)
  2155.             self.result_frm = Tkinter.Frame(window)
  2156.             self.goto_btn = Tkinter.Button(self.result_frm, text = 'go to selected', command = self.goto)
  2157.             self.hide_btn = Tkinter.Button(self.result_frm, text = 'hide results', command = self.hide)
  2158.             self.goto_btn.pack(side = 'left', fill = 'x', expand = 1)
  2159.             self.hide_btn.pack(side = 'right', fill = 'x', expand = 1)
  2160.             self.window.update()
  2161.             self.minwidth = self.window.winfo_width()
  2162.             self.minheight = self.window.winfo_height()
  2163.             self.bigminheight = self.server_frm.winfo_reqheight() + self.search_frm.winfo_reqheight() + self.result_lst.winfo_reqheight() + self.result_frm.winfo_reqheight()
  2164.             self.bigwidth = self.minwidth
  2165.             self.bigheight = self.bigminheight
  2166.             self.expanded = 0
  2167.             self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
  2168.             self.window.wm_minsize(self.minwidth, self.minheight)
  2169.             self.window.tk.willdispatch()
  2170.             import threading
  2171.             threading.Thread(target = serve, args = (port, self.ready, self.quit)).start()
  2172.  
  2173.         
  2174.         def ready(self, server):
  2175.             self.server = server
  2176.             self.title_lbl.config(text = 'Python documentation server at\n' + server.url)
  2177.             self.open_btn.config(state = 'normal')
  2178.             self.quit_btn.config(state = 'normal')
  2179.  
  2180.         
  2181.         def open(self, event = None, url = None):
  2182.             if not url:
  2183.                 pass
  2184.             url = self.server.url
  2185.             
  2186.             try:
  2187.                 import webbrowser
  2188.                 webbrowser.open(url)
  2189.             except ImportError:
  2190.                 if sys.platform == 'win32':
  2191.                     os.system('start "%s"' % url)
  2192.                 elif sys.platform == 'mac':
  2193.                     
  2194.                     try:
  2195.                         import ic
  2196.                     except ImportError:
  2197.                         pass
  2198.  
  2199.                     ic.launchurl(url)
  2200.                 else:
  2201.                     rc = os.system('netscape -remote "openURL(%s)" &' % url)
  2202.                     if rc:
  2203.                         os.system('netscape "%s" &' % url)
  2204.                     
  2205.             except:
  2206.                 sys.platform == 'win32'
  2207.  
  2208.  
  2209.         
  2210.         def quit(self, event = None):
  2211.             if self.server:
  2212.                 self.server.quit = 1
  2213.             
  2214.             self.window.quit()
  2215.  
  2216.         
  2217.         def search(self, event = None):
  2218.             key = self.search_ent.get()
  2219.             self.stop_btn.pack(side = 'right')
  2220.             self.stop_btn.config(state = 'normal')
  2221.             self.search_lbl.config(text = 'Searching for "%s"...' % key)
  2222.             self.search_ent.forget()
  2223.             self.search_lbl.pack(side = 'left')
  2224.             self.result_lst.delete(0, 'end')
  2225.             self.goto_btn.config(state = 'disabled')
  2226.             self.expand()
  2227.             import threading
  2228.             if self.scanner:
  2229.                 self.scanner.quit = 1
  2230.             
  2231.             self.scanner = ModuleScanner()
  2232.             threading.Thread(target = self.scanner.run, args = (self.update, key, self.done)).start()
  2233.  
  2234.         
  2235.         def update(self, path, modname, desc):
  2236.             if modname[-9:] == '.__init__':
  2237.                 modname = modname[:-9] + ' (package)'
  2238.             
  2239.             if not desc:
  2240.                 pass
  2241.             self.result_lst.insert('end', modname + ' - ' + '(no description)')
  2242.  
  2243.         
  2244.         def stop(self, event = None):
  2245.             if self.scanner:
  2246.                 self.scanner.quit = 1
  2247.                 self.scanner = None
  2248.             
  2249.  
  2250.         
  2251.         def done(self):
  2252.             self.scanner = None
  2253.             self.search_lbl.config(text = 'Search for')
  2254.             self.search_lbl.pack(side = 'left')
  2255.             self.search_ent.pack(side = 'right', fill = 'x', expand = 1)
  2256.             if sys.platform != 'win32':
  2257.                 self.stop_btn.forget()
  2258.             
  2259.             self.stop_btn.config(state = 'disabled')
  2260.  
  2261.         
  2262.         def select(self, event = None):
  2263.             self.goto_btn.config(state = 'normal')
  2264.  
  2265.         
  2266.         def goto(self, event = None):
  2267.             selection = self.result_lst.curselection()
  2268.             if selection:
  2269.                 modname = split(self.result_lst.get(selection[0]))[0]
  2270.                 self.open(url = self.server.url + modname + '.html')
  2271.             
  2272.  
  2273.         
  2274.         def collapse(self):
  2275.             if not self.expanded:
  2276.                 return None
  2277.             self.result_frm.forget()
  2278.             self.result_scr.forget()
  2279.             self.result_lst.forget()
  2280.             self.bigwidth = self.window.winfo_width()
  2281.             self.bigheight = self.window.winfo_height()
  2282.             self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
  2283.             self.window.wm_minsize(self.minwidth, self.minheight)
  2284.             self.expanded = 0
  2285.  
  2286.         
  2287.         def expand(self):
  2288.             if self.expanded:
  2289.                 return None
  2290.             self.result_frm.pack(side = 'bottom', fill = 'x')
  2291.             self.result_scr.pack(side = 'right', fill = 'y')
  2292.             self.result_lst.pack(side = 'top', fill = 'both', expand = 1)
  2293.             self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight))
  2294.             self.window.wm_minsize(self.minwidth, self.bigminheight)
  2295.             self.expanded = 1
  2296.  
  2297.         
  2298.         def hide(self, event = None):
  2299.             self.stop()
  2300.             self.collapse()
  2301.  
  2302.  
  2303.     import Tkinter
  2304.     
  2305.     try:
  2306.         root = Tkinter.Tk()
  2307.         
  2308.         try:
  2309.             gui = GUI(root)
  2310.             root.mainloop()
  2311.         finally:
  2312.             root.destroy()
  2313.  
  2314.     except KeyboardInterrupt:
  2315.         pass
  2316.  
  2317.  
  2318.  
  2319. def ispath(x):
  2320.     if isinstance(x, str):
  2321.         pass
  2322.     return find(x, os.sep) >= 0
  2323.  
  2324.  
  2325. def cli():
  2326.     import getopt
  2327.     
  2328.     class BadUsage:
  2329.         pass
  2330.  
  2331.     scriptdir = os.path.dirname(sys.argv[0])
  2332.     if scriptdir in sys.path:
  2333.         sys.path.remove(scriptdir)
  2334.     
  2335.     sys.path.insert(0, '.')
  2336.     
  2337.     try:
  2338.         (opts, args) = getopt.getopt(sys.argv[1:], 'gk:p:w')
  2339.         writing = 0
  2340.         for opt, val in opts:
  2341.             if opt == '-g':
  2342.                 gui()
  2343.                 return None
  2344.             if opt == '-k':
  2345.                 apropos(val)
  2346.                 return None
  2347.             if opt == '-p':
  2348.                 
  2349.                 try:
  2350.                     port = int(val)
  2351.                 except ValueError:
  2352.                     opt == '-k'
  2353.                     opt == '-k'
  2354.                     opt == '-g'
  2355.                     raise BadUsage
  2356.                 except:
  2357.                     opt == '-k'
  2358.  
  2359.                 
  2360.                 def ready(server):
  2361.                     print 'pydoc server ready at %s' % server.url
  2362.  
  2363.                 
  2364.                 def stopped():
  2365.                     print 'pydoc server stopped'
  2366.  
  2367.                 serve(port, ready, stopped)
  2368.                 return None
  2369.             if opt == '-w':
  2370.                 writing = 1
  2371.                 continue
  2372.             opt == '-p'
  2373.         
  2374.         if not args:
  2375.             raise BadUsage
  2376.         args
  2377.         for arg in args:
  2378.             if ispath(arg) and not os.path.exists(arg):
  2379.                 print 'file %r does not exist' % arg
  2380.                 break
  2381.             
  2382.             
  2383.             try:
  2384.                 if ispath(arg) and os.path.isfile(arg):
  2385.                     arg = importfile(arg)
  2386.                 
  2387.                 if writing:
  2388.                     if ispath(arg) and os.path.isdir(arg):
  2389.                         writedocs(arg)
  2390.                     else:
  2391.                         writedoc(arg)
  2392.                 else:
  2393.                     help.help(arg)
  2394.             continue
  2395.             except ErrorDuringImport:
  2396.                 value = None
  2397.                 print value
  2398.                 continue
  2399.             
  2400.  
  2401.     except (getopt.error, BadUsage):
  2402.         cmd = os.path.basename(sys.argv[0])
  2403.         print "pydoc - the Python documentation tool\n\n%s <name> ...\n    Show text documentation on something.  <name> may be the name of a\n    Python keyword, topic, function, module, or package, or a dotted\n    reference to a class or function within a module or module in a\n    package.  If <name> contains a '%s', it is used as the path to a\n    Python source file to document. If name is 'keywords', 'topics',\n    or 'modules', a listing of these things is displayed.\n\n%s -k <keyword>\n    Search for a keyword in the synopsis lines of all available modules.\n\n%s -p <port>\n    Start an HTTP server on the given port on the local machine.\n\n%s -g\n    Pop up a graphical interface for finding and serving documentation.\n\n%s -w <name> ...\n    Write out the HTML documentation for a module to a file in the current\n    directory.  If <name> contains a '%s', it is treated as a filename; if\n    it names a directory, documentation is written for all the contents.\n" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep)
  2404.  
  2405.  
  2406. if __name__ == '__main__':
  2407.     cli()
  2408.  
  2409.