13b553e0ab2146ef2055c969a1893b453b2023cf4darylm#!/usr/bin/env python 23b553e0ab2146ef2055c969a1893b453b2023cf4darylm# -*- coding: latin-1 -*- 33b553e0ab2146ef2055c969a1893b453b2023cf4darylm"""Generate Python documentation in HTML or text for interactive use. 43b553e0ab2146ef2055c969a1893b453b2023cf4darylm 53b553e0ab2146ef2055c969a1893b453b2023cf4darylmIn the Python interpreter, do "from pydoc import help" to provide online 63b553e0ab2146ef2055c969a1893b453b2023cf4darylmhelp. Calling help(thing) on a Python object documents the object. 73b553e0ab2146ef2055c969a1893b453b2023cf4darylm 83b553e0ab2146ef2055c969a1893b453b2023cf4darylmOr, at the shell command line outside of Python: 93b553e0ab2146ef2055c969a1893b453b2023cf4darylm 103b553e0ab2146ef2055c969a1893b453b2023cf4darylmRun "pydoc <name>" to show documentation on something. <name> may be 113b553e0ab2146ef2055c969a1893b453b2023cf4darylmthe name of a function, module, package, or a dotted reference to a 123b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass or function within a module or module in a package. If the 133b553e0ab2146ef2055c969a1893b453b2023cf4darylmargument contains a path segment delimiter (e.g. slash on Unix, 143b553e0ab2146ef2055c969a1893b453b2023cf4darylmbackslash on Windows) it is treated as the path to a Python source file. 153b553e0ab2146ef2055c969a1893b453b2023cf4darylm 163b553e0ab2146ef2055c969a1893b453b2023cf4darylmRun "pydoc -k <keyword>" to search for a keyword in the synopsis lines 173b553e0ab2146ef2055c969a1893b453b2023cf4darylmof all available modules. 183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 193b553e0ab2146ef2055c969a1893b453b2023cf4darylmRun "pydoc -p <port>" to start an HTTP server on a given port on the 203b553e0ab2146ef2055c969a1893b453b2023cf4darylmlocal machine to generate documentation web pages. 213b553e0ab2146ef2055c969a1893b453b2023cf4darylm 223b553e0ab2146ef2055c969a1893b453b2023cf4darylmFor platforms without a command line, "pydoc -g" starts the HTTP server 233b553e0ab2146ef2055c969a1893b453b2023cf4darylmand also pops up a little window for controlling it. 243b553e0ab2146ef2055c969a1893b453b2023cf4darylm 253b553e0ab2146ef2055c969a1893b453b2023cf4darylmRun "pydoc -w <name>" to write out the HTML documentation for a module 263b553e0ab2146ef2055c969a1893b453b2023cf4darylmto a file named "<name>.html". 273b553e0ab2146ef2055c969a1893b453b2023cf4darylm 283b553e0ab2146ef2055c969a1893b453b2023cf4darylmModule docs for core modules are assumed to be in 293b553e0ab2146ef2055c969a1893b453b2023cf4darylm 303b553e0ab2146ef2055c969a1893b453b2023cf4darylm http://docs.python.org/library/ 313b553e0ab2146ef2055c969a1893b453b2023cf4darylm 323b553e0ab2146ef2055c969a1893b453b2023cf4darylmThis can be overridden by setting the PYTHONDOCS environment variable 333b553e0ab2146ef2055c969a1893b453b2023cf4darylmto a different URL or to a local directory containing the Library 343b553e0ab2146ef2055c969a1893b453b2023cf4darylmReference Manual pages. 353b553e0ab2146ef2055c969a1893b453b2023cf4darylm""" 363b553e0ab2146ef2055c969a1893b453b2023cf4darylm 373b553e0ab2146ef2055c969a1893b453b2023cf4darylm__author__ = "Ka-Ping Yee <ping@lfw.org>" 383b553e0ab2146ef2055c969a1893b453b2023cf4darylm__date__ = "26 February 2001" 393b553e0ab2146ef2055c969a1893b453b2023cf4darylm 403b553e0ab2146ef2055c969a1893b453b2023cf4darylm__version__ = "$Revision$" 413b553e0ab2146ef2055c969a1893b453b2023cf4darylm__credits__ = """Guido van Rossum, for an excellent programming language. 423b553e0ab2146ef2055c969a1893b453b2023cf4darylmTommy Burnette, the original creator of manpy. 433b553e0ab2146ef2055c969a1893b453b2023cf4darylmPaul Prescod, for all his work on onlinehelp. 443b553e0ab2146ef2055c969a1893b453b2023cf4darylmRichard Chamberlain, for the first implementation of textdoc. 453b553e0ab2146ef2055c969a1893b453b2023cf4darylm""" 463b553e0ab2146ef2055c969a1893b453b2023cf4darylm 473b553e0ab2146ef2055c969a1893b453b2023cf4darylm# Known bugs that can't be fixed here: 483b553e0ab2146ef2055c969a1893b453b2023cf4darylm# - imp.load_module() cannot be prevented from clobbering existing 493b553e0ab2146ef2055c969a1893b453b2023cf4darylm# loaded modules, so calling synopsis() on a binary module file 503b553e0ab2146ef2055c969a1893b453b2023cf4darylm# changes the contents of any existing module with the same name. 513b553e0ab2146ef2055c969a1893b453b2023cf4darylm# - If the __file__ attribute on a module is a relative path and 523b553e0ab2146ef2055c969a1893b453b2023cf4darylm# the current directory is changed with os.chdir(), an incorrect 533b553e0ab2146ef2055c969a1893b453b2023cf4darylm# path will be displayed. 543b553e0ab2146ef2055c969a1893b453b2023cf4darylm 553b553e0ab2146ef2055c969a1893b453b2023cf4darylmimport sys, imp, os, re, types, inspect, __builtin__, pkgutil 563b553e0ab2146ef2055c969a1893b453b2023cf4darylmfrom repr import Repr 573b553e0ab2146ef2055c969a1893b453b2023cf4darylmfrom string import expandtabs, find, join, lower, split, strip, rfind, rstrip 583b553e0ab2146ef2055c969a1893b453b2023cf4darylmfrom traceback import extract_tb 593b553e0ab2146ef2055c969a1893b453b2023cf4darylmtry: 603b553e0ab2146ef2055c969a1893b453b2023cf4darylm from collections import deque 613b553e0ab2146ef2055c969a1893b453b2023cf4darylmexcept ImportError: 623b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Python 2.3 compatibility 633b553e0ab2146ef2055c969a1893b453b2023cf4darylm class deque(list): 643b553e0ab2146ef2055c969a1893b453b2023cf4darylm def popleft(self): 653b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.pop(0) 663b553e0ab2146ef2055c969a1893b453b2023cf4darylm 673b553e0ab2146ef2055c969a1893b453b2023cf4darylm# --------------------------------------------------------- common routines 683b553e0ab2146ef2055c969a1893b453b2023cf4darylm 693b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef pathdirs(): 703b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Convert sys.path into a list of absolute, existing, unique paths.""" 713b553e0ab2146ef2055c969a1893b453b2023cf4darylm dirs = [] 723b553e0ab2146ef2055c969a1893b453b2023cf4darylm normdirs = [] 733b553e0ab2146ef2055c969a1893b453b2023cf4darylm for dir in sys.path: 743b553e0ab2146ef2055c969a1893b453b2023cf4darylm dir = os.path.abspath(dir or '.') 753b553e0ab2146ef2055c969a1893b453b2023cf4darylm normdir = os.path.normcase(dir) 763b553e0ab2146ef2055c969a1893b453b2023cf4darylm if normdir not in normdirs and os.path.isdir(dir): 773b553e0ab2146ef2055c969a1893b453b2023cf4darylm dirs.append(dir) 783b553e0ab2146ef2055c969a1893b453b2023cf4darylm normdirs.append(normdir) 793b553e0ab2146ef2055c969a1893b453b2023cf4darylm return dirs 803b553e0ab2146ef2055c969a1893b453b2023cf4darylm 813b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef getdoc(object): 823b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Get the doc string or comments for an object.""" 833b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = inspect.getdoc(object) or inspect.getcomments(object) 843b553e0ab2146ef2055c969a1893b453b2023cf4darylm return result and re.sub('^ *\n', '', rstrip(result)) or '' 853b553e0ab2146ef2055c969a1893b453b2023cf4darylm 863b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef splitdoc(doc): 873b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Split a doc string into a synopsis line (if any) and the rest.""" 883b553e0ab2146ef2055c969a1893b453b2023cf4darylm lines = split(strip(doc), '\n') 893b553e0ab2146ef2055c969a1893b453b2023cf4darylm if len(lines) == 1: 903b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lines[0], '' 913b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif len(lines) >= 2 and not rstrip(lines[1]): 923b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lines[0], join(lines[2:], '\n') 933b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '', join(lines, '\n') 943b553e0ab2146ef2055c969a1893b453b2023cf4darylm 953b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef classname(object, modname): 963b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Get a class name and qualify it with a module name if necessary.""" 973b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = object.__name__ 983b553e0ab2146ef2055c969a1893b453b2023cf4darylm if object.__module__ != modname: 993b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = object.__module__ + '.' + name 1003b553e0ab2146ef2055c969a1893b453b2023cf4darylm return name 1013b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1023b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef isdata(object): 1033b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Check if an object is of a type that probably means it's data.""" 1043b553e0ab2146ef2055c969a1893b453b2023cf4darylm return not (inspect.ismodule(object) or inspect.isclass(object) or 1053b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isroutine(object) or inspect.isframe(object) or 1063b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.istraceback(object) or inspect.iscode(object)) 1073b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1083b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef replace(text, *pairs): 1093b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Do a series of global replacements on a string.""" 1103b553e0ab2146ef2055c969a1893b453b2023cf4darylm while pairs: 1113b553e0ab2146ef2055c969a1893b453b2023cf4darylm text = join(split(text, pairs[0]), pairs[1]) 1123b553e0ab2146ef2055c969a1893b453b2023cf4darylm pairs = pairs[2:] 1133b553e0ab2146ef2055c969a1893b453b2023cf4darylm return text 1143b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1153b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef cram(text, maxlen): 1163b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Omit part of a string if needed to make it fit in a maximum length.""" 1173b553e0ab2146ef2055c969a1893b453b2023cf4darylm if len(text) > maxlen: 1183b553e0ab2146ef2055c969a1893b453b2023cf4darylm pre = max(0, (maxlen-3)//2) 1193b553e0ab2146ef2055c969a1893b453b2023cf4darylm post = max(0, maxlen-3-pre) 1203b553e0ab2146ef2055c969a1893b453b2023cf4darylm return text[:pre] + '...' + text[len(text)-post:] 1213b553e0ab2146ef2055c969a1893b453b2023cf4darylm return text 1223b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1233b553e0ab2146ef2055c969a1893b453b2023cf4darylm_re_stripid = re.compile(r' at 0x[0-9a-f]{6,16}(>+)$', re.IGNORECASE) 1243b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef stripid(text): 1253b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Remove the hexadecimal id from a Python object representation.""" 1263b553e0ab2146ef2055c969a1893b453b2023cf4darylm # The behaviour of %p is implementation-dependent in terms of case. 1273b553e0ab2146ef2055c969a1893b453b2023cf4darylm return _re_stripid.sub(r'\1', text) 1283b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1293b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef _is_some_method(obj): 1303b553e0ab2146ef2055c969a1893b453b2023cf4darylm return inspect.ismethod(obj) or inspect.ismethoddescriptor(obj) 1313b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1323b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef allmethods(cl): 1333b553e0ab2146ef2055c969a1893b453b2023cf4darylm methods = {} 1343b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(cl, _is_some_method): 1353b553e0ab2146ef2055c969a1893b453b2023cf4darylm methods[key] = 1 1363b553e0ab2146ef2055c969a1893b453b2023cf4darylm for base in cl.__bases__: 1373b553e0ab2146ef2055c969a1893b453b2023cf4darylm methods.update(allmethods(base)) # all your base are belong to us 1383b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key in methods.keys(): 1393b553e0ab2146ef2055c969a1893b453b2023cf4darylm methods[key] = getattr(cl, key) 1403b553e0ab2146ef2055c969a1893b453b2023cf4darylm return methods 1413b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1423b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef _split_list(s, predicate): 1433b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Split sequence s via predicate, and return pair ([true], [false]). 1443b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1453b553e0ab2146ef2055c969a1893b453b2023cf4darylm The return value is a 2-tuple of lists, 1463b553e0ab2146ef2055c969a1893b453b2023cf4darylm ([x for x in s if predicate(x)], 1473b553e0ab2146ef2055c969a1893b453b2023cf4darylm [x for x in s if not predicate(x)]) 1483b553e0ab2146ef2055c969a1893b453b2023cf4darylm """ 1493b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1503b553e0ab2146ef2055c969a1893b453b2023cf4darylm yes = [] 1513b553e0ab2146ef2055c969a1893b453b2023cf4darylm no = [] 1523b553e0ab2146ef2055c969a1893b453b2023cf4darylm for x in s: 1533b553e0ab2146ef2055c969a1893b453b2023cf4darylm if predicate(x): 1543b553e0ab2146ef2055c969a1893b453b2023cf4darylm yes.append(x) 1553b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 1563b553e0ab2146ef2055c969a1893b453b2023cf4darylm no.append(x) 1573b553e0ab2146ef2055c969a1893b453b2023cf4darylm return yes, no 1583b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1593b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef visiblename(name, all=None, obj=None): 1603b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Decide whether to show documentation on a variable.""" 1613b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Certain special names are redundant. 1623b553e0ab2146ef2055c969a1893b453b2023cf4darylm _hidden_names = ('__builtins__', '__doc__', '__file__', '__path__', 1633b553e0ab2146ef2055c969a1893b453b2023cf4darylm '__module__', '__name__', '__slots__', '__package__') 1643b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name in _hidden_names: return 0 1653b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Private names are hidden, but special names are displayed. 1663b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name.startswith('__') and name.endswith('__'): return 1 1673b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Namedtuples have public fields and methods with a single leading underscore 1683b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name.startswith('_') and hasattr(obj, '_fields'): 1693b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 1 1703b553e0ab2146ef2055c969a1893b453b2023cf4darylm if all is not None: 1713b553e0ab2146ef2055c969a1893b453b2023cf4darylm # only document that which the programmer exported in __all__ 1723b553e0ab2146ef2055c969a1893b453b2023cf4darylm return name in all 1733b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 1743b553e0ab2146ef2055c969a1893b453b2023cf4darylm return not name.startswith('_') 1753b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1763b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef classify_class_attrs(object): 1773b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Wrap inspect.classify_class_attrs, with fixup for data descriptors.""" 1783b553e0ab2146ef2055c969a1893b453b2023cf4darylm def fixup(data): 1793b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, kind, cls, value = data 1803b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isdatadescriptor(value): 1813b553e0ab2146ef2055c969a1893b453b2023cf4darylm kind = 'data descriptor' 1823b553e0ab2146ef2055c969a1893b453b2023cf4darylm return name, kind, cls, value 1833b553e0ab2146ef2055c969a1893b453b2023cf4darylm return map(fixup, inspect.classify_class_attrs(object)) 1843b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1853b553e0ab2146ef2055c969a1893b453b2023cf4darylm# ----------------------------------------------------- module manipulation 1863b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1873b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef ispackage(path): 1883b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Guess whether a path refers to a package directory.""" 1893b553e0ab2146ef2055c969a1893b453b2023cf4darylm if os.path.isdir(path): 1903b553e0ab2146ef2055c969a1893b453b2023cf4darylm for ext in ('.py', '.pyc', '.pyo'): 1913b553e0ab2146ef2055c969a1893b453b2023cf4darylm if os.path.isfile(os.path.join(path, '__init__' + ext)): 1923b553e0ab2146ef2055c969a1893b453b2023cf4darylm return True 1933b553e0ab2146ef2055c969a1893b453b2023cf4darylm return False 1943b553e0ab2146ef2055c969a1893b453b2023cf4darylm 1953b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef source_synopsis(file): 1963b553e0ab2146ef2055c969a1893b453b2023cf4darylm line = file.readline() 1973b553e0ab2146ef2055c969a1893b453b2023cf4darylm while line[:1] == '#' or not strip(line): 1983b553e0ab2146ef2055c969a1893b453b2023cf4darylm line = file.readline() 1993b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not line: break 2003b553e0ab2146ef2055c969a1893b453b2023cf4darylm line = strip(line) 2013b553e0ab2146ef2055c969a1893b453b2023cf4darylm if line[:4] == 'r"""': line = line[1:] 2023b553e0ab2146ef2055c969a1893b453b2023cf4darylm if line[:3] == '"""': 2033b553e0ab2146ef2055c969a1893b453b2023cf4darylm line = line[3:] 2043b553e0ab2146ef2055c969a1893b453b2023cf4darylm if line[-1:] == '\\': line = line[:-1] 2053b553e0ab2146ef2055c969a1893b453b2023cf4darylm while not strip(line): 2063b553e0ab2146ef2055c969a1893b453b2023cf4darylm line = file.readline() 2073b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not line: break 2083b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = strip(split(line, '"""')[0]) 2093b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: result = None 2103b553e0ab2146ef2055c969a1893b453b2023cf4darylm return result 2113b553e0ab2146ef2055c969a1893b453b2023cf4darylm 2123b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef synopsis(filename, cache={}): 2133b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Get the one-line summary out of a module file.""" 2143b553e0ab2146ef2055c969a1893b453b2023cf4darylm mtime = os.stat(filename).st_mtime 2153b553e0ab2146ef2055c969a1893b453b2023cf4darylm lastupdate, result = cache.get(filename, (0, None)) 2163b553e0ab2146ef2055c969a1893b453b2023cf4darylm if lastupdate < mtime: 2173b553e0ab2146ef2055c969a1893b453b2023cf4darylm info = inspect.getmoduleinfo(filename) 2183b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 2193b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = open(filename) 2203b553e0ab2146ef2055c969a1893b453b2023cf4darylm except IOError: 2213b553e0ab2146ef2055c969a1893b453b2023cf4darylm # module can't be opened, so skip it 2223b553e0ab2146ef2055c969a1893b453b2023cf4darylm return None 2233b553e0ab2146ef2055c969a1893b453b2023cf4darylm if info and 'b' in info[2]: # binary modules have to be imported 2243b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: module = imp.load_module('__temp__', file, filename, info[1:]) 2253b553e0ab2146ef2055c969a1893b453b2023cf4darylm except: return None 2263b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = (module.__doc__ or '').splitlines()[0] 2273b553e0ab2146ef2055c969a1893b453b2023cf4darylm del sys.modules['__temp__'] 2283b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: # text modules can be directly examined 2293b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = source_synopsis(file) 2303b553e0ab2146ef2055c969a1893b453b2023cf4darylm file.close() 2313b553e0ab2146ef2055c969a1893b453b2023cf4darylm cache[filename] = (mtime, result) 2323b553e0ab2146ef2055c969a1893b453b2023cf4darylm return result 2333b553e0ab2146ef2055c969a1893b453b2023cf4darylm 2343b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass ErrorDuringImport(Exception): 2353b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Errors that occurred while trying to import something to document it.""" 2363b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self, filename, exc_info): 2373b553e0ab2146ef2055c969a1893b453b2023cf4darylm exc, value, tb = exc_info 2383b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.filename = filename 2393b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.exc = exc 2403b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.value = value 2413b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.tb = tb 2423b553e0ab2146ef2055c969a1893b453b2023cf4darylm 2433b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __str__(self): 2443b553e0ab2146ef2055c969a1893b453b2023cf4darylm exc = self.exc 2453b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(exc) is types.ClassType: 2463b553e0ab2146ef2055c969a1893b453b2023cf4darylm exc = exc.__name__ 2473b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'problem in %s - %s: %s' % (self.filename, exc, self.value) 2483b553e0ab2146ef2055c969a1893b453b2023cf4darylm 2493b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef importfile(path): 2503b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Import a Python source file or compiled file given its path.""" 2513b553e0ab2146ef2055c969a1893b453b2023cf4darylm magic = imp.get_magic() 2523b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = open(path, 'r') 2533b553e0ab2146ef2055c969a1893b453b2023cf4darylm if file.read(len(magic)) == magic: 2543b553e0ab2146ef2055c969a1893b453b2023cf4darylm kind = imp.PY_COMPILED 2553b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 2563b553e0ab2146ef2055c969a1893b453b2023cf4darylm kind = imp.PY_SOURCE 2573b553e0ab2146ef2055c969a1893b453b2023cf4darylm file.close() 2583b553e0ab2146ef2055c969a1893b453b2023cf4darylm filename = os.path.basename(path) 2593b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, ext = os.path.splitext(filename) 2603b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = open(path, 'r') 2613b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 2623b553e0ab2146ef2055c969a1893b453b2023cf4darylm module = imp.load_module(name, file, path, (ext, 'r', kind)) 2633b553e0ab2146ef2055c969a1893b453b2023cf4darylm except: 2643b553e0ab2146ef2055c969a1893b453b2023cf4darylm raise ErrorDuringImport(path, sys.exc_info()) 2653b553e0ab2146ef2055c969a1893b453b2023cf4darylm file.close() 2663b553e0ab2146ef2055c969a1893b453b2023cf4darylm return module 2673b553e0ab2146ef2055c969a1893b453b2023cf4darylm 2683b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef safeimport(path, forceload=0, cache={}): 2693b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Import a module; handle errors; return None if the module isn't found. 2703b553e0ab2146ef2055c969a1893b453b2023cf4darylm 2713b553e0ab2146ef2055c969a1893b453b2023cf4darylm If the module *is* found but an exception occurs, it's wrapped in an 2723b553e0ab2146ef2055c969a1893b453b2023cf4darylm ErrorDuringImport exception and reraised. Unlike __import__, if a 2733b553e0ab2146ef2055c969a1893b453b2023cf4darylm package path is specified, the module at the end of the path is returned, 2743b553e0ab2146ef2055c969a1893b453b2023cf4darylm not the package at the beginning. If the optional 'forceload' argument 2753b553e0ab2146ef2055c969a1893b453b2023cf4darylm is 1, we reload the module from disk (unless it's a dynamic extension).""" 2763b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 2773b553e0ab2146ef2055c969a1893b453b2023cf4darylm # If forceload is 1 and the module has been previously loaded from 2783b553e0ab2146ef2055c969a1893b453b2023cf4darylm # disk, we always have to reload the module. Checking the file's 2793b553e0ab2146ef2055c969a1893b453b2023cf4darylm # mtime isn't good enough (e.g. the module could contain a class 2803b553e0ab2146ef2055c969a1893b453b2023cf4darylm # that inherits from another module that has changed). 2813b553e0ab2146ef2055c969a1893b453b2023cf4darylm if forceload and path in sys.modules: 2823b553e0ab2146ef2055c969a1893b453b2023cf4darylm if path not in sys.builtin_module_names: 2833b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Avoid simply calling reload() because it leaves names in 2843b553e0ab2146ef2055c969a1893b453b2023cf4darylm # the currently loaded module lying around if they're not 2853b553e0ab2146ef2055c969a1893b453b2023cf4darylm # defined in the new source file. Instead, remove the 2863b553e0ab2146ef2055c969a1893b453b2023cf4darylm # module from sys.modules and re-import. Also remove any 2873b553e0ab2146ef2055c969a1893b453b2023cf4darylm # submodules because they won't appear in the newly loaded 2883b553e0ab2146ef2055c969a1893b453b2023cf4darylm # module's namespace if they're already in sys.modules. 2893b553e0ab2146ef2055c969a1893b453b2023cf4darylm subs = [m for m in sys.modules if m.startswith(path + '.')] 2903b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key in [path] + subs: 2913b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Prevent garbage collection. 2923b553e0ab2146ef2055c969a1893b453b2023cf4darylm cache[key] = sys.modules[key] 2933b553e0ab2146ef2055c969a1893b453b2023cf4darylm del sys.modules[key] 2943b553e0ab2146ef2055c969a1893b453b2023cf4darylm module = __import__(path) 2953b553e0ab2146ef2055c969a1893b453b2023cf4darylm except: 2963b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Did the error occur before or after the module was found? 2973b553e0ab2146ef2055c969a1893b453b2023cf4darylm (exc, value, tb) = info = sys.exc_info() 2983b553e0ab2146ef2055c969a1893b453b2023cf4darylm if path in sys.modules: 2993b553e0ab2146ef2055c969a1893b453b2023cf4darylm # An error occurred while executing the imported module. 3003b553e0ab2146ef2055c969a1893b453b2023cf4darylm raise ErrorDuringImport(sys.modules[path].__file__, info) 3013b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif exc is SyntaxError: 3023b553e0ab2146ef2055c969a1893b453b2023cf4darylm # A SyntaxError occurred before we could execute the module. 3033b553e0ab2146ef2055c969a1893b453b2023cf4darylm raise ErrorDuringImport(value.filename, info) 3043b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif exc is ImportError and extract_tb(tb)[-1][2]=='safeimport': 3053b553e0ab2146ef2055c969a1893b453b2023cf4darylm # The import error occurred directly in this function, 3063b553e0ab2146ef2055c969a1893b453b2023cf4darylm # which means there is no such module in the path. 3073b553e0ab2146ef2055c969a1893b453b2023cf4darylm return None 3083b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 3093b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Some other error occurred during the importing process. 3103b553e0ab2146ef2055c969a1893b453b2023cf4darylm raise ErrorDuringImport(path, sys.exc_info()) 3113b553e0ab2146ef2055c969a1893b453b2023cf4darylm for part in split(path, '.')[1:]: 3123b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: module = getattr(module, part) 3133b553e0ab2146ef2055c969a1893b453b2023cf4darylm except AttributeError: return None 3143b553e0ab2146ef2055c969a1893b453b2023cf4darylm return module 3153b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3163b553e0ab2146ef2055c969a1893b453b2023cf4darylm# ---------------------------------------------------- formatter base class 3173b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3183b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass Doc: 3193b553e0ab2146ef2055c969a1893b453b2023cf4darylm def document(self, object, name=None, *args): 3203b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Generate documentation for an object.""" 3213b553e0ab2146ef2055c969a1893b453b2023cf4darylm args = (object, name) + args 3223b553e0ab2146ef2055c969a1893b453b2023cf4darylm # 'try' clause is to attempt to handle the possibility that inspect 3233b553e0ab2146ef2055c969a1893b453b2023cf4darylm # identifies something in a way that pydoc itself has issues handling; 3243b553e0ab2146ef2055c969a1893b453b2023cf4darylm # think 'super' and how it is a descriptor (which raises the exception 3253b553e0ab2146ef2055c969a1893b453b2023cf4darylm # by lacking a __name__ attribute) and an instance. 3263b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isgetsetdescriptor(object): return self.docdata(*args) 3273b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.ismemberdescriptor(object): return self.docdata(*args) 3283b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 3293b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.ismodule(object): return self.docmodule(*args) 3303b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isclass(object): return self.docclass(*args) 3313b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isroutine(object): return self.docroutine(*args) 3323b553e0ab2146ef2055c969a1893b453b2023cf4darylm except AttributeError: 3333b553e0ab2146ef2055c969a1893b453b2023cf4darylm pass 3343b553e0ab2146ef2055c969a1893b453b2023cf4darylm if isinstance(object, property): return self.docproperty(*args) 3353b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.docother(*args) 3363b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3373b553e0ab2146ef2055c969a1893b453b2023cf4darylm def fail(self, object, name=None, *args): 3383b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Raise an exception for unimplemented types.""" 3393b553e0ab2146ef2055c969a1893b453b2023cf4darylm message = "don't know how to document object%s of type %s" % ( 3403b553e0ab2146ef2055c969a1893b453b2023cf4darylm name and ' ' + repr(name), type(object).__name__) 3413b553e0ab2146ef2055c969a1893b453b2023cf4darylm raise TypeError, message 3423b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3433b553e0ab2146ef2055c969a1893b453b2023cf4darylm docmodule = docclass = docroutine = docother = docproperty = docdata = fail 3443b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3453b553e0ab2146ef2055c969a1893b453b2023cf4darylm def getdocloc(self, object): 3463b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Return the location of module docs or None""" 3473b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3483b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 3493b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = inspect.getabsfile(object) 3503b553e0ab2146ef2055c969a1893b453b2023cf4darylm except TypeError: 3513b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = '(built-in)' 3523b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3533b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = os.environ.get("PYTHONDOCS", 3543b553e0ab2146ef2055c969a1893b453b2023cf4darylm "http://docs.python.org/library") 3553b553e0ab2146ef2055c969a1893b453b2023cf4darylm basedir = os.path.join(sys.exec_prefix, "lib", 3563b553e0ab2146ef2055c969a1893b453b2023cf4darylm "python"+sys.version[0:3]) 3573b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (isinstance(object, type(os)) and 3583b553e0ab2146ef2055c969a1893b453b2023cf4darylm (object.__name__ in ('errno', 'exceptions', 'gc', 'imp', 3593b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'marshal', 'posix', 'signal', 'sys', 3603b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'thread', 'zipimport') or 3613b553e0ab2146ef2055c969a1893b453b2023cf4darylm (file.startswith(basedir) and 3623b553e0ab2146ef2055c969a1893b453b2023cf4darylm not file.startswith(os.path.join(basedir, 'site-packages')))) and 3633b553e0ab2146ef2055c969a1893b453b2023cf4darylm object.__name__ not in ('xml.etree', 'test.pydoc_mod')): 3643b553e0ab2146ef2055c969a1893b453b2023cf4darylm if docloc.startswith("http://"): 3653b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__) 3663b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 3673b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = os.path.join(docloc, object.__name__ + ".html") 3683b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 3693b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = None 3703b553e0ab2146ef2055c969a1893b453b2023cf4darylm return docloc 3713b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3723b553e0ab2146ef2055c969a1893b453b2023cf4darylm# -------------------------------------------- HTML documentation generator 3733b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3743b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass HTMLRepr(Repr): 3753b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Class for safely making an HTML representation of a Python object.""" 3763b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self): 3773b553e0ab2146ef2055c969a1893b453b2023cf4darylm Repr.__init__(self) 3783b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.maxlist = self.maxtuple = 20 3793b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.maxdict = 10 3803b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.maxstring = self.maxother = 100 3813b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3823b553e0ab2146ef2055c969a1893b453b2023cf4darylm def escape(self, text): 3833b553e0ab2146ef2055c969a1893b453b2023cf4darylm return replace(text, '&', '&', '<', '<', '>', '>') 3843b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3853b553e0ab2146ef2055c969a1893b453b2023cf4darylm def repr(self, object): 3863b553e0ab2146ef2055c969a1893b453b2023cf4darylm return Repr.repr(self, object) 3873b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3883b553e0ab2146ef2055c969a1893b453b2023cf4darylm def repr1(self, x, level): 3893b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(type(x), '__name__'): 3903b553e0ab2146ef2055c969a1893b453b2023cf4darylm methodname = 'repr_' + join(split(type(x).__name__), '_') 3913b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(self, methodname): 3923b553e0ab2146ef2055c969a1893b453b2023cf4darylm return getattr(self, methodname)(x, level) 3933b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.escape(cram(stripid(repr(x)), self.maxother)) 3943b553e0ab2146ef2055c969a1893b453b2023cf4darylm 3953b553e0ab2146ef2055c969a1893b453b2023cf4darylm def repr_string(self, x, level): 3963b553e0ab2146ef2055c969a1893b453b2023cf4darylm test = cram(x, self.maxstring) 3973b553e0ab2146ef2055c969a1893b453b2023cf4darylm testrepr = repr(test) 3983b553e0ab2146ef2055c969a1893b453b2023cf4darylm if '\\' in test and '\\' not in replace(testrepr, r'\\', ''): 3993b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Backslashes are only literal in the string and are never 4003b553e0ab2146ef2055c969a1893b453b2023cf4darylm # needed to make any special characters, so show a raw string. 4013b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'r' + testrepr[0] + self.escape(test) + testrepr[0] 4023b553e0ab2146ef2055c969a1893b453b2023cf4darylm return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)', 4033b553e0ab2146ef2055c969a1893b453b2023cf4darylm r'<font color="#c040c0">\1</font>', 4043b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.escape(testrepr)) 4053b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4063b553e0ab2146ef2055c969a1893b453b2023cf4darylm repr_str = repr_string 4073b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4083b553e0ab2146ef2055c969a1893b453b2023cf4darylm def repr_instance(self, x, level): 4093b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 4103b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.escape(cram(stripid(repr(x)), self.maxstring)) 4113b553e0ab2146ef2055c969a1893b453b2023cf4darylm except: 4123b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.escape('<%s instance>' % x.__class__.__name__) 4133b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4143b553e0ab2146ef2055c969a1893b453b2023cf4darylm repr_unicode = repr_string 4153b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4163b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass HTMLDoc(Doc): 4173b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Formatter class for HTML documentation.""" 4183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4193b553e0ab2146ef2055c969a1893b453b2023cf4darylm # ------------------------------------------- HTML formatting utilities 4203b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4213b553e0ab2146ef2055c969a1893b453b2023cf4darylm _repr_instance = HTMLRepr() 4223b553e0ab2146ef2055c969a1893b453b2023cf4darylm repr = _repr_instance.repr 4233b553e0ab2146ef2055c969a1893b453b2023cf4darylm escape = _repr_instance.escape 4243b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4253b553e0ab2146ef2055c969a1893b453b2023cf4darylm def page(self, title, contents): 4263b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format an HTML page.""" 4273b553e0ab2146ef2055c969a1893b453b2023cf4darylm return ''' 4283b553e0ab2146ef2055c969a1893b453b2023cf4darylm<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 4293b553e0ab2146ef2055c969a1893b453b2023cf4darylm<html><head><title>Python: %s</title> 4303b553e0ab2146ef2055c969a1893b453b2023cf4darylm</head><body bgcolor="#f0f0f8"> 4313b553e0ab2146ef2055c969a1893b453b2023cf4darylm%s 4323b553e0ab2146ef2055c969a1893b453b2023cf4darylm</body></html>''' % (title, contents) 4333b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4343b553e0ab2146ef2055c969a1893b453b2023cf4darylm def heading(self, title, fgcol, bgcol, extras=''): 4353b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format a page heading.""" 4363b553e0ab2146ef2055c969a1893b453b2023cf4darylm return ''' 4373b553e0ab2146ef2055c969a1893b453b2023cf4darylm<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading"> 4383b553e0ab2146ef2055c969a1893b453b2023cf4darylm<tr bgcolor="%s"> 4393b553e0ab2146ef2055c969a1893b453b2023cf4darylm<td valign=bottom> <br> 4403b553e0ab2146ef2055c969a1893b453b2023cf4darylm<font color="%s" face="helvetica, arial"> <br>%s</font></td 4413b553e0ab2146ef2055c969a1893b453b2023cf4darylm><td align=right valign=bottom 4423b553e0ab2146ef2055c969a1893b453b2023cf4darylm><font color="%s" face="helvetica, arial">%s</font></td></tr></table> 4433b553e0ab2146ef2055c969a1893b453b2023cf4darylm ''' % (bgcol, fgcol, title, fgcol, extras or ' ') 4443b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4453b553e0ab2146ef2055c969a1893b453b2023cf4darylm def section(self, title, fgcol, bgcol, contents, width=6, 4463b553e0ab2146ef2055c969a1893b453b2023cf4darylm prelude='', marginalia=None, gap=' '): 4473b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format a section with a heading.""" 4483b553e0ab2146ef2055c969a1893b453b2023cf4darylm if marginalia is None: 4493b553e0ab2146ef2055c969a1893b453b2023cf4darylm marginalia = '<tt>' + ' ' * width + '</tt>' 4503b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = '''<p> 4513b553e0ab2146ef2055c969a1893b453b2023cf4darylm<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section"> 4523b553e0ab2146ef2055c969a1893b453b2023cf4darylm<tr bgcolor="%s"> 4533b553e0ab2146ef2055c969a1893b453b2023cf4darylm<td colspan=3 valign=bottom> <br> 4543b553e0ab2146ef2055c969a1893b453b2023cf4darylm<font color="%s" face="helvetica, arial">%s</font></td></tr> 4553b553e0ab2146ef2055c969a1893b453b2023cf4darylm ''' % (bgcol, fgcol, title) 4563b553e0ab2146ef2055c969a1893b453b2023cf4darylm if prelude: 4573b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + ''' 4583b553e0ab2146ef2055c969a1893b453b2023cf4darylm<tr bgcolor="%s"><td rowspan=2>%s</td> 4593b553e0ab2146ef2055c969a1893b453b2023cf4darylm<td colspan=2>%s</td></tr> 4603b553e0ab2146ef2055c969a1893b453b2023cf4darylm<tr><td>%s</td>''' % (bgcol, marginalia, prelude, gap) 4613b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 4623b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + ''' 4633b553e0ab2146ef2055c969a1893b453b2023cf4darylm<tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol, marginalia, gap) 4643b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4653b553e0ab2146ef2055c969a1893b453b2023cf4darylm return result + '\n<td width="100%%">%s</td></tr></table>' % contents 4663b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4673b553e0ab2146ef2055c969a1893b453b2023cf4darylm def bigsection(self, title, *args): 4683b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format a section with a big heading.""" 4693b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = '<big><strong>%s</strong></big>' % title 4703b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.section(title, *args) 4713b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4723b553e0ab2146ef2055c969a1893b453b2023cf4darylm def preformat(self, text): 4733b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format literal preformatted text.""" 4743b553e0ab2146ef2055c969a1893b453b2023cf4darylm text = self.escape(expandtabs(text)) 4753b553e0ab2146ef2055c969a1893b453b2023cf4darylm return replace(text, '\n\n', '\n \n', '\n\n', '\n \n', 4763b553e0ab2146ef2055c969a1893b453b2023cf4darylm ' ', ' ', '\n', '<br>\n') 4773b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4783b553e0ab2146ef2055c969a1893b453b2023cf4darylm def multicolumn(self, list, format, cols=4): 4793b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format a list of items into a multi-column list.""" 4803b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = '' 4813b553e0ab2146ef2055c969a1893b453b2023cf4darylm rows = (len(list)+cols-1)//cols 4823b553e0ab2146ef2055c969a1893b453b2023cf4darylm for col in range(cols): 4833b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '<td width="%d%%" valign=top>' % (100//cols) 4843b553e0ab2146ef2055c969a1893b453b2023cf4darylm for i in range(rows*col, rows*col+rows): 4853b553e0ab2146ef2055c969a1893b453b2023cf4darylm if i < len(list): 4863b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + format(list[i]) + '<br>\n' 4873b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '</td>' 4883b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result 4893b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4903b553e0ab2146ef2055c969a1893b453b2023cf4darylm def grey(self, text): return '<font color="#909090">%s</font>' % text 4913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4923b553e0ab2146ef2055c969a1893b453b2023cf4darylm def namelink(self, name, *dicts): 4933b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Make a link for an identifier, given name-to-URL mappings.""" 4943b553e0ab2146ef2055c969a1893b453b2023cf4darylm for dict in dicts: 4953b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name in dict: 4963b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<a href="%s">%s</a>' % (dict[name], name) 4973b553e0ab2146ef2055c969a1893b453b2023cf4darylm return name 4983b553e0ab2146ef2055c969a1893b453b2023cf4darylm 4993b553e0ab2146ef2055c969a1893b453b2023cf4darylm def classlink(self, object, modname): 5003b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Make a link for a class.""" 5013b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, module = object.__name__, sys.modules.get(object.__module__) 5023b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(module, name) and getattr(module, name) is object: 5033b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<a href="%s.html#%s">%s</a>' % ( 5043b553e0ab2146ef2055c969a1893b453b2023cf4darylm module.__name__, name, classname(object, modname)) 5053b553e0ab2146ef2055c969a1893b453b2023cf4darylm return classname(object, modname) 5063b553e0ab2146ef2055c969a1893b453b2023cf4darylm 5073b553e0ab2146ef2055c969a1893b453b2023cf4darylm def modulelink(self, object): 5083b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Make a link for a module.""" 5093b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__) 5103b553e0ab2146ef2055c969a1893b453b2023cf4darylm 5113b553e0ab2146ef2055c969a1893b453b2023cf4darylm def modpkglink(self, data): 5123b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Make a link for a module or package to display in an index.""" 5133b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, path, ispackage, shadowed = data 5143b553e0ab2146ef2055c969a1893b453b2023cf4darylm if shadowed: 5153b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.grey(name) 5163b553e0ab2146ef2055c969a1893b453b2023cf4darylm if path: 5173b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = '%s.%s.html' % (path, name) 5183b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 5193b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = '%s.html' % name 5203b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ispackage: 5213b553e0ab2146ef2055c969a1893b453b2023cf4darylm text = '<strong>%s</strong> (package)' % name 5223b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 5233b553e0ab2146ef2055c969a1893b453b2023cf4darylm text = name 5243b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<a href="%s">%s</a>' % (url, text) 5253b553e0ab2146ef2055c969a1893b453b2023cf4darylm 5263b553e0ab2146ef2055c969a1893b453b2023cf4darylm def markup(self, text, escape=None, funcs={}, classes={}, methods={}): 5273b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Mark up some plain text, given a context of symbols to look for. 5283b553e0ab2146ef2055c969a1893b453b2023cf4darylm Each context dictionary maps object names to anchor names.""" 5293b553e0ab2146ef2055c969a1893b453b2023cf4darylm escape = escape or self.escape 5303b553e0ab2146ef2055c969a1893b453b2023cf4darylm results = [] 5313b553e0ab2146ef2055c969a1893b453b2023cf4darylm here = 0 5323b553e0ab2146ef2055c969a1893b453b2023cf4darylm pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|' 5333b553e0ab2146ef2055c969a1893b453b2023cf4darylm r'RFC[- ]?(\d+)|' 5343b553e0ab2146ef2055c969a1893b453b2023cf4darylm r'PEP[- ]?(\d+)|' 5353b553e0ab2146ef2055c969a1893b453b2023cf4darylm r'(self\.)?(\w+))') 5363b553e0ab2146ef2055c969a1893b453b2023cf4darylm while True: 5373b553e0ab2146ef2055c969a1893b453b2023cf4darylm match = pattern.search(text, here) 5383b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not match: break 5393b553e0ab2146ef2055c969a1893b453b2023cf4darylm start, end = match.span() 5403b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append(escape(text[here:start])) 5413b553e0ab2146ef2055c969a1893b453b2023cf4darylm 5423b553e0ab2146ef2055c969a1893b453b2023cf4darylm all, scheme, rfc, pep, selfdot, name = match.groups() 5433b553e0ab2146ef2055c969a1893b453b2023cf4darylm if scheme: 5443b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = escape(all).replace('"', '"') 5453b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append('<a href="%s">%s</a>' % (url, url)) 5463b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif rfc: 5473b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) 5483b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append('<a href="%s">%s</a>' % (url, escape(all))) 5493b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif pep: 5503b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep) 5513b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append('<a href="%s">%s</a>' % (url, escape(all))) 5523b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif text[end:end+1] == '(': 5533b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append(self.namelink(name, methods, funcs, classes)) 5543b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif selfdot: 5553b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append('self.<strong>%s</strong>' % name) 5563b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 5573b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append(self.namelink(name, classes)) 5583b553e0ab2146ef2055c969a1893b453b2023cf4darylm here = end 5593b553e0ab2146ef2055c969a1893b453b2023cf4darylm results.append(escape(text[here:])) 5603b553e0ab2146ef2055c969a1893b453b2023cf4darylm return join(results, '') 5613b553e0ab2146ef2055c969a1893b453b2023cf4darylm 5623b553e0ab2146ef2055c969a1893b453b2023cf4darylm # ---------------------------------------------- type-specific routines 5633b553e0ab2146ef2055c969a1893b453b2023cf4darylm 5643b553e0ab2146ef2055c969a1893b453b2023cf4darylm def formattree(self, tree, modname, parent=None): 5653b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce HTML for a class tree as given by inspect.getclasstree().""" 5663b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = '' 5673b553e0ab2146ef2055c969a1893b453b2023cf4darylm for entry in tree: 5683b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(entry) is type(()): 5693b553e0ab2146ef2055c969a1893b453b2023cf4darylm c, bases = entry 5703b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '<dt><font face="helvetica, arial">' 5713b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.classlink(c, modname) 5723b553e0ab2146ef2055c969a1893b453b2023cf4darylm if bases and bases != (parent,): 5733b553e0ab2146ef2055c969a1893b453b2023cf4darylm parents = [] 5743b553e0ab2146ef2055c969a1893b453b2023cf4darylm for base in bases: 5753b553e0ab2146ef2055c969a1893b453b2023cf4darylm parents.append(self.classlink(base, modname)) 5763b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '(' + join(parents, ', ') + ')' 5773b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '\n</font></dt>' 5783b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif type(entry) is type([]): 5793b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '<dd>\n%s</dd>\n' % self.formattree( 5803b553e0ab2146ef2055c969a1893b453b2023cf4darylm entry, modname, c) 5813b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<dl>\n%s</dl>\n' % result 5823b553e0ab2146ef2055c969a1893b453b2023cf4darylm 5833b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docmodule(self, object, name=None, mod=None, *ignored): 5843b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce HTML documentation for a module object.""" 5853b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = object.__name__ # ignore the passed-in name 5863b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 5873b553e0ab2146ef2055c969a1893b453b2023cf4darylm all = object.__all__ 5883b553e0ab2146ef2055c969a1893b453b2023cf4darylm except AttributeError: 5893b553e0ab2146ef2055c969a1893b453b2023cf4darylm all = None 5903b553e0ab2146ef2055c969a1893b453b2023cf4darylm parts = split(name, '.') 5913b553e0ab2146ef2055c969a1893b453b2023cf4darylm links = [] 5923b553e0ab2146ef2055c969a1893b453b2023cf4darylm for i in range(len(parts)-1): 5933b553e0ab2146ef2055c969a1893b453b2023cf4darylm links.append( 5943b553e0ab2146ef2055c969a1893b453b2023cf4darylm '<a href="%s.html"><font color="#ffffff">%s</font></a>' % 5953b553e0ab2146ef2055c969a1893b453b2023cf4darylm (join(parts[:i+1], '.'), parts[i])) 5963b553e0ab2146ef2055c969a1893b453b2023cf4darylm linkedname = join(links + parts[-1:], '.') 5973b553e0ab2146ef2055c969a1893b453b2023cf4darylm head = '<big><big><strong>%s</strong></big></big>' % linkedname 5983b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 5993b553e0ab2146ef2055c969a1893b453b2023cf4darylm path = inspect.getabsfile(object) 6003b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = path 6013b553e0ab2146ef2055c969a1893b453b2023cf4darylm if sys.platform == 'win32': 6023b553e0ab2146ef2055c969a1893b453b2023cf4darylm import nturl2path 6033b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = nturl2path.pathname2url(path) 6043b553e0ab2146ef2055c969a1893b453b2023cf4darylm filelink = '<a href="file:%s">%s</a>' % (url, path) 6053b553e0ab2146ef2055c969a1893b453b2023cf4darylm except TypeError: 6063b553e0ab2146ef2055c969a1893b453b2023cf4darylm filelink = '(built-in)' 6073b553e0ab2146ef2055c969a1893b453b2023cf4darylm info = [] 6083b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__version__'): 6093b553e0ab2146ef2055c969a1893b453b2023cf4darylm version = str(object.__version__) 6103b553e0ab2146ef2055c969a1893b453b2023cf4darylm if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': 6113b553e0ab2146ef2055c969a1893b453b2023cf4darylm version = strip(version[11:-1]) 6123b553e0ab2146ef2055c969a1893b453b2023cf4darylm info.append('version %s' % self.escape(version)) 6133b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__date__'): 6143b553e0ab2146ef2055c969a1893b453b2023cf4darylm info.append(self.escape(str(object.__date__))) 6153b553e0ab2146ef2055c969a1893b453b2023cf4darylm if info: 6163b553e0ab2146ef2055c969a1893b453b2023cf4darylm head = head + ' (%s)' % join(info, ', ') 6173b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = self.getdocloc(object) 6183b553e0ab2146ef2055c969a1893b453b2023cf4darylm if docloc is not None: 6193b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = '<br><a href="%(docloc)s">Module Docs</a>' % locals() 6203b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 6213b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = '' 6223b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = self.heading( 6233b553e0ab2146ef2055c969a1893b453b2023cf4darylm head, '#ffffff', '#7799ee', 6243b553e0ab2146ef2055c969a1893b453b2023cf4darylm '<a href=".">index</a><br>' + filelink + docloc) 6253b553e0ab2146ef2055c969a1893b453b2023cf4darylm 6263b553e0ab2146ef2055c969a1893b453b2023cf4darylm modules = inspect.getmembers(object, inspect.ismodule) 6273b553e0ab2146ef2055c969a1893b453b2023cf4darylm 6283b553e0ab2146ef2055c969a1893b453b2023cf4darylm classes, cdict = [], {} 6293b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(object, inspect.isclass): 6303b553e0ab2146ef2055c969a1893b453b2023cf4darylm # if __all__ exists, believe it. Otherwise use old heuristic. 6313b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (all is not None or 6323b553e0ab2146ef2055c969a1893b453b2023cf4darylm (inspect.getmodule(value) or object) is object): 6333b553e0ab2146ef2055c969a1893b453b2023cf4darylm if visiblename(key, all, object): 6343b553e0ab2146ef2055c969a1893b453b2023cf4darylm classes.append((key, value)) 6353b553e0ab2146ef2055c969a1893b453b2023cf4darylm cdict[key] = cdict[value] = '#' + key 6363b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in classes: 6373b553e0ab2146ef2055c969a1893b453b2023cf4darylm for base in value.__bases__: 6383b553e0ab2146ef2055c969a1893b453b2023cf4darylm key, modname = base.__name__, base.__module__ 6393b553e0ab2146ef2055c969a1893b453b2023cf4darylm module = sys.modules.get(modname) 6403b553e0ab2146ef2055c969a1893b453b2023cf4darylm if modname != name and module and hasattr(module, key): 6413b553e0ab2146ef2055c969a1893b453b2023cf4darylm if getattr(module, key) is base: 6423b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not key in cdict: 6433b553e0ab2146ef2055c969a1893b453b2023cf4darylm cdict[key] = cdict[base] = modname + '.html#' + key 6443b553e0ab2146ef2055c969a1893b453b2023cf4darylm funcs, fdict = [], {} 6453b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(object, inspect.isroutine): 6463b553e0ab2146ef2055c969a1893b453b2023cf4darylm # if __all__ exists, believe it. Otherwise use old heuristic. 6473b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (all is not None or 6483b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isbuiltin(value) or inspect.getmodule(value) is object): 6493b553e0ab2146ef2055c969a1893b453b2023cf4darylm if visiblename(key, all, object): 6503b553e0ab2146ef2055c969a1893b453b2023cf4darylm funcs.append((key, value)) 6513b553e0ab2146ef2055c969a1893b453b2023cf4darylm fdict[key] = '#-' + key 6523b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isfunction(value): fdict[value] = fdict[key] 6533b553e0ab2146ef2055c969a1893b453b2023cf4darylm data = [] 6543b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(object, isdata): 6553b553e0ab2146ef2055c969a1893b453b2023cf4darylm if visiblename(key, all, object): 6563b553e0ab2146ef2055c969a1893b453b2023cf4darylm data.append((key, value)) 6573b553e0ab2146ef2055c969a1893b453b2023cf4darylm 6583b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = self.markup(getdoc(object), self.preformat, fdict, cdict) 6593b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = doc and '<tt>%s</tt>' % doc 6603b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '<p>%s</p>\n' % doc 6613b553e0ab2146ef2055c969a1893b453b2023cf4darylm 6623b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__path__'): 6633b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs = [] 6643b553e0ab2146ef2055c969a1893b453b2023cf4darylm for importer, modname, ispkg in pkgutil.iter_modules(object.__path__): 6653b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs.append((modname, name, ispkg, 0)) 6663b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs.sort() 6673b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = self.multicolumn(modpkgs, self.modpkglink) 6683b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.bigsection( 6693b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Package Contents', '#ffffff', '#aa55cc', contents) 6703b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif modules: 6713b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = self.multicolumn( 6723b553e0ab2146ef2055c969a1893b453b2023cf4darylm modules, lambda key_value, s=self: s.modulelink(key_value[1])) 6733b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.bigsection( 6743b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Modules', '#ffffff', '#aa55cc', contents) 6753b553e0ab2146ef2055c969a1893b453b2023cf4darylm 6763b553e0ab2146ef2055c969a1893b453b2023cf4darylm if classes: 6773b553e0ab2146ef2055c969a1893b453b2023cf4darylm classlist = map(lambda key_value: key_value[1], classes) 6783b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = [ 6793b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.formattree(inspect.getclasstree(classlist, 1), name)] 6803b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in classes: 6813b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents.append(self.document(value, key, name, fdict, cdict)) 6823b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.bigsection( 6833b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Classes', '#ffffff', '#ee77aa', join(contents)) 6843b553e0ab2146ef2055c969a1893b453b2023cf4darylm if funcs: 6853b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = [] 6863b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in funcs: 6873b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents.append(self.document(value, key, name, fdict, cdict)) 6883b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.bigsection( 6893b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Functions', '#ffffff', '#eeaa77', join(contents)) 6903b553e0ab2146ef2055c969a1893b453b2023cf4darylm if data: 6913b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = [] 6923b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in data: 6933b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents.append(self.document(value, key)) 6943b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.bigsection( 6953b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Data', '#ffffff', '#55aa55', join(contents, '<br>\n')) 6963b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__author__'): 6973b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = self.markup(str(object.__author__), self.preformat) 6983b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.bigsection( 6993b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Author', '#ffffff', '#7799ee', contents) 7003b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__credits__'): 7013b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = self.markup(str(object.__credits__), self.preformat) 7023b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.bigsection( 7033b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Credits', '#ffffff', '#7799ee', contents) 7043b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7053b553e0ab2146ef2055c969a1893b453b2023cf4darylm return result 7063b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7073b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docclass(self, object, name=None, mod=None, funcs={}, classes={}, 7083b553e0ab2146ef2055c969a1893b453b2023cf4darylm *ignored): 7093b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce HTML documentation for a class object.""" 7103b553e0ab2146ef2055c969a1893b453b2023cf4darylm realname = object.__name__ 7113b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = name or realname 7123b553e0ab2146ef2055c969a1893b453b2023cf4darylm bases = object.__bases__ 7133b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7143b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = [] 7153b553e0ab2146ef2055c969a1893b453b2023cf4darylm push = contents.append 7163b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7173b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Cute little class to pump out a horizontal rule between sections. 7183b553e0ab2146ef2055c969a1893b453b2023cf4darylm class HorizontalRule: 7193b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self): 7203b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.needone = 0 7213b553e0ab2146ef2055c969a1893b453b2023cf4darylm def maybe(self): 7223b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.needone: 7233b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('<hr>\n') 7243b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.needone = 1 7253b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr = HorizontalRule() 7263b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7273b553e0ab2146ef2055c969a1893b453b2023cf4darylm # List the mro, if non-trivial. 7283b553e0ab2146ef2055c969a1893b453b2023cf4darylm mro = deque(inspect.getmro(object)) 7293b553e0ab2146ef2055c969a1893b453b2023cf4darylm if len(mro) > 2: 7303b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr.maybe() 7313b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('<dl><dt>Method resolution order:</dt>\n') 7323b553e0ab2146ef2055c969a1893b453b2023cf4darylm for base in mro: 7333b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('<dd>%s</dd>\n' % self.classlink(base, 7343b553e0ab2146ef2055c969a1893b453b2023cf4darylm object.__module__)) 7353b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('</dl>\n') 7363b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7373b553e0ab2146ef2055c969a1893b453b2023cf4darylm def spill(msg, attrs, predicate): 7383b553e0ab2146ef2055c969a1893b453b2023cf4darylm ok, attrs = _split_list(attrs, predicate) 7393b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ok: 7403b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr.maybe() 7413b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(msg) 7423b553e0ab2146ef2055c969a1893b453b2023cf4darylm for name, kind, homecls, value in ok: 7433b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(self.document(getattr(object, name), name, mod, 7443b553e0ab2146ef2055c969a1893b453b2023cf4darylm funcs, classes, mdict, object)) 7453b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('\n') 7463b553e0ab2146ef2055c969a1893b453b2023cf4darylm return attrs 7473b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7483b553e0ab2146ef2055c969a1893b453b2023cf4darylm def spilldescriptors(msg, attrs, predicate): 7493b553e0ab2146ef2055c969a1893b453b2023cf4darylm ok, attrs = _split_list(attrs, predicate) 7503b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ok: 7513b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr.maybe() 7523b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(msg) 7533b553e0ab2146ef2055c969a1893b453b2023cf4darylm for name, kind, homecls, value in ok: 7543b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(self._docdescriptor(name, value, mod)) 7553b553e0ab2146ef2055c969a1893b453b2023cf4darylm return attrs 7563b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7573b553e0ab2146ef2055c969a1893b453b2023cf4darylm def spilldata(msg, attrs, predicate): 7583b553e0ab2146ef2055c969a1893b453b2023cf4darylm ok, attrs = _split_list(attrs, predicate) 7593b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ok: 7603b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr.maybe() 7613b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(msg) 7623b553e0ab2146ef2055c969a1893b453b2023cf4darylm for name, kind, homecls, value in ok: 7633b553e0ab2146ef2055c969a1893b453b2023cf4darylm base = self.docother(getattr(object, name), name, mod) 7643b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (hasattr(value, '__call__') or 7653b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isdatadescriptor(value)): 7663b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = getattr(value, "__doc__", None) 7673b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 7683b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = None 7693b553e0ab2146ef2055c969a1893b453b2023cf4darylm if doc is None: 7703b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('<dl><dt>%s</dl>\n' % base) 7713b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 7723b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = self.markup(getdoc(value), self.preformat, 7733b553e0ab2146ef2055c969a1893b453b2023cf4darylm funcs, classes, mdict) 7743b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = '<dd><tt>%s</tt>' % doc 7753b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('<dl><dt>%s%s</dl>\n' % (base, doc)) 7763b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('\n') 7773b553e0ab2146ef2055c969a1893b453b2023cf4darylm return attrs 7783b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7793b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = filter(lambda data: visiblename(data[0], obj=object), 7803b553e0ab2146ef2055c969a1893b453b2023cf4darylm classify_class_attrs(object)) 7813b553e0ab2146ef2055c969a1893b453b2023cf4darylm mdict = {} 7823b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, kind, homecls, value in attrs: 7833b553e0ab2146ef2055c969a1893b453b2023cf4darylm mdict[key] = anchor = '#' + name + '-' + key 7843b553e0ab2146ef2055c969a1893b453b2023cf4darylm value = getattr(object, key) 7853b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 7863b553e0ab2146ef2055c969a1893b453b2023cf4darylm # The value may not be hashable (e.g., a data attr with 7873b553e0ab2146ef2055c969a1893b453b2023cf4darylm # a dict or list value). 7883b553e0ab2146ef2055c969a1893b453b2023cf4darylm mdict[value] = anchor 7893b553e0ab2146ef2055c969a1893b453b2023cf4darylm except TypeError: 7903b553e0ab2146ef2055c969a1893b453b2023cf4darylm pass 7913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7923b553e0ab2146ef2055c969a1893b453b2023cf4darylm while attrs: 7933b553e0ab2146ef2055c969a1893b453b2023cf4darylm if mro: 7943b553e0ab2146ef2055c969a1893b453b2023cf4darylm thisclass = mro.popleft() 7953b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 7963b553e0ab2146ef2055c969a1893b453b2023cf4darylm thisclass = attrs[0][2] 7973b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) 7983b553e0ab2146ef2055c969a1893b453b2023cf4darylm 7993b553e0ab2146ef2055c969a1893b453b2023cf4darylm if thisclass is __builtin__.object: 8003b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = inherited 8013b553e0ab2146ef2055c969a1893b453b2023cf4darylm continue 8023b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif thisclass is object: 8033b553e0ab2146ef2055c969a1893b453b2023cf4darylm tag = 'defined here' 8043b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 8053b553e0ab2146ef2055c969a1893b453b2023cf4darylm tag = 'inherited from %s' % self.classlink(thisclass, 8063b553e0ab2146ef2055c969a1893b453b2023cf4darylm object.__module__) 8073b553e0ab2146ef2055c969a1893b453b2023cf4darylm tag += ':<br>\n' 8083b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8093b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Sort attrs by name. 8103b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 8113b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs.sort(key=lambda t: t[0]) 8123b553e0ab2146ef2055c969a1893b453b2023cf4darylm except TypeError: 8133b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) # 2.3 compat 8143b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8153b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Pump out the attrs, segregated by kind. 8163b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spill('Methods %s' % tag, attrs, 8173b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'method') 8183b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spill('Class methods %s' % tag, attrs, 8193b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'class method') 8203b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spill('Static methods %s' % tag, attrs, 8213b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'static method') 8223b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spilldescriptors('Data descriptors %s' % tag, attrs, 8233b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'data descriptor') 8243b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spilldata('Data and other attributes %s' % tag, attrs, 8253b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'data') 8263b553e0ab2146ef2055c969a1893b453b2023cf4darylm assert attrs == [] 8273b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = inherited 8283b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8293b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = ''.join(contents) 8303b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8313b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name == realname: 8323b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = '<a name="%s">class <strong>%s</strong></a>' % ( 8333b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, realname) 8343b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 8353b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = '<strong>%s</strong> = <a name="%s">class %s</a>' % ( 8363b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, name, realname) 8373b553e0ab2146ef2055c969a1893b453b2023cf4darylm if bases: 8383b553e0ab2146ef2055c969a1893b453b2023cf4darylm parents = [] 8393b553e0ab2146ef2055c969a1893b453b2023cf4darylm for base in bases: 8403b553e0ab2146ef2055c969a1893b453b2023cf4darylm parents.append(self.classlink(base, object.__module__)) 8413b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = title + '(%s)' % join(parents, ', ') 8423b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict) 8433b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = doc and '<tt>%s<br> </tt>' % doc 8443b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8453b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.section(title, '#000000', '#ffc8d8', contents, 3, doc) 8463b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8473b553e0ab2146ef2055c969a1893b453b2023cf4darylm def formatvalue(self, object): 8483b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format an argument default value as text.""" 8493b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.grey('=' + self.repr(object)) 8503b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8513b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docroutine(self, object, name=None, mod=None, 8523b553e0ab2146ef2055c969a1893b453b2023cf4darylm funcs={}, classes={}, methods={}, cl=None): 8533b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce HTML documentation for a function or method object.""" 8543b553e0ab2146ef2055c969a1893b453b2023cf4darylm realname = object.__name__ 8553b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = name or realname 8563b553e0ab2146ef2055c969a1893b453b2023cf4darylm anchor = (cl and cl.__name__ or '') + '-' + name 8573b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = '' 8583b553e0ab2146ef2055c969a1893b453b2023cf4darylm skipdocs = 0 8593b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.ismethod(object): 8603b553e0ab2146ef2055c969a1893b453b2023cf4darylm imclass = object.im_class 8613b553e0ab2146ef2055c969a1893b453b2023cf4darylm if cl: 8623b553e0ab2146ef2055c969a1893b453b2023cf4darylm if imclass is not cl: 8633b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = ' from ' + self.classlink(imclass, mod) 8643b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 8653b553e0ab2146ef2055c969a1893b453b2023cf4darylm if object.im_self is not None: 8663b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = ' method of %s instance' % self.classlink( 8673b553e0ab2146ef2055c969a1893b453b2023cf4darylm object.im_self.__class__, mod) 8683b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 8693b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = ' unbound %s method' % self.classlink(imclass,mod) 8703b553e0ab2146ef2055c969a1893b453b2023cf4darylm object = object.im_func 8713b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8723b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name == realname: 8733b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname) 8743b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 8753b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (cl and realname in cl.__dict__ and 8763b553e0ab2146ef2055c969a1893b453b2023cf4darylm cl.__dict__[realname] is object): 8773b553e0ab2146ef2055c969a1893b453b2023cf4darylm reallink = '<a href="#%s">%s</a>' % ( 8783b553e0ab2146ef2055c969a1893b453b2023cf4darylm cl.__name__ + '-' + realname, realname) 8793b553e0ab2146ef2055c969a1893b453b2023cf4darylm skipdocs = 1 8803b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 8813b553e0ab2146ef2055c969a1893b453b2023cf4darylm reallink = realname 8823b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = '<a name="%s"><strong>%s</strong></a> = %s' % ( 8833b553e0ab2146ef2055c969a1893b453b2023cf4darylm anchor, name, reallink) 8843b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isfunction(object): 8853b553e0ab2146ef2055c969a1893b453b2023cf4darylm args, varargs, varkw, defaults = inspect.getargspec(object) 8863b553e0ab2146ef2055c969a1893b453b2023cf4darylm argspec = inspect.formatargspec( 8873b553e0ab2146ef2055c969a1893b453b2023cf4darylm args, varargs, varkw, defaults, formatvalue=self.formatvalue) 8883b553e0ab2146ef2055c969a1893b453b2023cf4darylm if realname == '<lambda>': 8893b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = '<strong>%s</strong> <em>lambda</em> ' % name 8903b553e0ab2146ef2055c969a1893b453b2023cf4darylm argspec = argspec[1:-1] # remove parentheses 8913b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 8923b553e0ab2146ef2055c969a1893b453b2023cf4darylm argspec = '(...)' 8933b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8943b553e0ab2146ef2055c969a1893b453b2023cf4darylm decl = title + argspec + (note and self.grey( 8953b553e0ab2146ef2055c969a1893b453b2023cf4darylm '<font face="helvetica, arial">%s</font>' % note)) 8963b553e0ab2146ef2055c969a1893b453b2023cf4darylm 8973b553e0ab2146ef2055c969a1893b453b2023cf4darylm if skipdocs: 8983b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<dl><dt>%s</dt></dl>\n' % decl 8993b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 9003b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = self.markup( 9013b553e0ab2146ef2055c969a1893b453b2023cf4darylm getdoc(object), self.preformat, funcs, classes, methods) 9023b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = doc and '<dd><tt>%s</tt></dd>' % doc 9033b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc) 9043b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9053b553e0ab2146ef2055c969a1893b453b2023cf4darylm def _docdescriptor(self, name, value, mod): 9063b553e0ab2146ef2055c969a1893b453b2023cf4darylm results = [] 9073b553e0ab2146ef2055c969a1893b453b2023cf4darylm push = results.append 9083b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9093b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name: 9103b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('<dl><dt><strong>%s</strong></dt>\n' % name) 9113b553e0ab2146ef2055c969a1893b453b2023cf4darylm if value.__doc__ is not None: 9123b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = self.markup(getdoc(value), self.preformat) 9133b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('<dd><tt>%s</tt></dd>\n' % doc) 9143b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('</dl>\n') 9153b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9163b553e0ab2146ef2055c969a1893b453b2023cf4darylm return ''.join(results) 9173b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9183b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docproperty(self, object, name=None, mod=None, cl=None): 9193b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce html documentation for a property.""" 9203b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self._docdescriptor(name, object, mod) 9213b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9223b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docother(self, object, name=None, mod=None, *ignored): 9233b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce HTML documentation for a data object.""" 9243b553e0ab2146ef2055c969a1893b453b2023cf4darylm lhs = name and '<strong>%s</strong> = ' % name or '' 9253b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lhs + self.repr(object) 9263b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9273b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docdata(self, object, name=None, mod=None, cl=None): 9283b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce html documentation for a data descriptor.""" 9293b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self._docdescriptor(name, object, mod) 9303b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9313b553e0ab2146ef2055c969a1893b453b2023cf4darylm def index(self, dir, shadowed=None): 9323b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Generate an HTML index for a directory of modules.""" 9333b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs = [] 9343b553e0ab2146ef2055c969a1893b453b2023cf4darylm if shadowed is None: shadowed = {} 9353b553e0ab2146ef2055c969a1893b453b2023cf4darylm for importer, name, ispkg in pkgutil.iter_modules([dir]): 9363b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs.append((name, '', ispkg, name in shadowed)) 9373b553e0ab2146ef2055c969a1893b453b2023cf4darylm shadowed[name] = 1 9383b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9393b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs.sort() 9403b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = self.multicolumn(modpkgs, self.modpkglink) 9413b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.bigsection(dir, '#ffffff', '#ee77aa', contents) 9423b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9433b553e0ab2146ef2055c969a1893b453b2023cf4darylm# -------------------------------------------- text documentation generator 9443b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9453b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass TextRepr(Repr): 9463b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Class for safely making a text representation of a Python object.""" 9473b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self): 9483b553e0ab2146ef2055c969a1893b453b2023cf4darylm Repr.__init__(self) 9493b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.maxlist = self.maxtuple = 20 9503b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.maxdict = 10 9513b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.maxstring = self.maxother = 100 9523b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9533b553e0ab2146ef2055c969a1893b453b2023cf4darylm def repr1(self, x, level): 9543b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(type(x), '__name__'): 9553b553e0ab2146ef2055c969a1893b453b2023cf4darylm methodname = 'repr_' + join(split(type(x).__name__), '_') 9563b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(self, methodname): 9573b553e0ab2146ef2055c969a1893b453b2023cf4darylm return getattr(self, methodname)(x, level) 9583b553e0ab2146ef2055c969a1893b453b2023cf4darylm return cram(stripid(repr(x)), self.maxother) 9593b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9603b553e0ab2146ef2055c969a1893b453b2023cf4darylm def repr_string(self, x, level): 9613b553e0ab2146ef2055c969a1893b453b2023cf4darylm test = cram(x, self.maxstring) 9623b553e0ab2146ef2055c969a1893b453b2023cf4darylm testrepr = repr(test) 9633b553e0ab2146ef2055c969a1893b453b2023cf4darylm if '\\' in test and '\\' not in replace(testrepr, r'\\', ''): 9643b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Backslashes are only literal in the string and are never 9653b553e0ab2146ef2055c969a1893b453b2023cf4darylm # needed to make any special characters, so show a raw string. 9663b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'r' + testrepr[0] + test + testrepr[0] 9673b553e0ab2146ef2055c969a1893b453b2023cf4darylm return testrepr 9683b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9693b553e0ab2146ef2055c969a1893b453b2023cf4darylm repr_str = repr_string 9703b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9713b553e0ab2146ef2055c969a1893b453b2023cf4darylm def repr_instance(self, x, level): 9723b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 9733b553e0ab2146ef2055c969a1893b453b2023cf4darylm return cram(stripid(repr(x)), self.maxstring) 9743b553e0ab2146ef2055c969a1893b453b2023cf4darylm except: 9753b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<%s instance>' % x.__class__.__name__ 9763b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9773b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass TextDoc(Doc): 9783b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Formatter class for text documentation.""" 9793b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9803b553e0ab2146ef2055c969a1893b453b2023cf4darylm # ------------------------------------------- text formatting utilities 9813b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9823b553e0ab2146ef2055c969a1893b453b2023cf4darylm _repr_instance = TextRepr() 9833b553e0ab2146ef2055c969a1893b453b2023cf4darylm repr = _repr_instance.repr 9843b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9853b553e0ab2146ef2055c969a1893b453b2023cf4darylm def bold(self, text): 9863b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format a string in bold by overstriking.""" 9873b553e0ab2146ef2055c969a1893b453b2023cf4darylm return join(map(lambda ch: ch + '\b' + ch, text), '') 9883b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9893b553e0ab2146ef2055c969a1893b453b2023cf4darylm def indent(self, text, prefix=' '): 9903b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Indent text by prepending a given prefix to each line.""" 9913b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not text: return '' 9923b553e0ab2146ef2055c969a1893b453b2023cf4darylm lines = split(text, '\n') 9933b553e0ab2146ef2055c969a1893b453b2023cf4darylm lines = map(lambda line, prefix=prefix: prefix + line, lines) 9943b553e0ab2146ef2055c969a1893b453b2023cf4darylm if lines: lines[-1] = rstrip(lines[-1]) 9953b553e0ab2146ef2055c969a1893b453b2023cf4darylm return join(lines, '\n') 9963b553e0ab2146ef2055c969a1893b453b2023cf4darylm 9973b553e0ab2146ef2055c969a1893b453b2023cf4darylm def section(self, title, contents): 9983b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format a section with a given heading.""" 9993b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.bold(title) + '\n' + rstrip(self.indent(contents)) + '\n\n' 10003b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10013b553e0ab2146ef2055c969a1893b453b2023cf4darylm # ---------------------------------------------- type-specific routines 10023b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10033b553e0ab2146ef2055c969a1893b453b2023cf4darylm def formattree(self, tree, modname, parent=None, prefix=''): 10043b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Render in text a class tree as returned by inspect.getclasstree().""" 10053b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = '' 10063b553e0ab2146ef2055c969a1893b453b2023cf4darylm for entry in tree: 10073b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(entry) is type(()): 10083b553e0ab2146ef2055c969a1893b453b2023cf4darylm c, bases = entry 10093b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + prefix + classname(c, modname) 10103b553e0ab2146ef2055c969a1893b453b2023cf4darylm if bases and bases != (parent,): 10113b553e0ab2146ef2055c969a1893b453b2023cf4darylm parents = map(lambda c, m=modname: classname(c, m), bases) 10123b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '(%s)' % join(parents, ', ') 10133b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + '\n' 10143b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif type(entry) is type([]): 10153b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.formattree( 10163b553e0ab2146ef2055c969a1893b453b2023cf4darylm entry, modname, c, prefix + ' ') 10173b553e0ab2146ef2055c969a1893b453b2023cf4darylm return result 10183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10193b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docmodule(self, object, name=None, mod=None): 10203b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce text documentation for a given module object.""" 10213b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = object.__name__ # ignore the passed-in name 10223b553e0ab2146ef2055c969a1893b453b2023cf4darylm synop, desc = splitdoc(getdoc(object)) 10233b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = self.section('NAME', name + (synop and ' - ' + synop)) 10243b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10253b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 10263b553e0ab2146ef2055c969a1893b453b2023cf4darylm all = object.__all__ 10273b553e0ab2146ef2055c969a1893b453b2023cf4darylm except AttributeError: 10283b553e0ab2146ef2055c969a1893b453b2023cf4darylm all = None 10293b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10303b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 10313b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = inspect.getabsfile(object) 10323b553e0ab2146ef2055c969a1893b453b2023cf4darylm except TypeError: 10333b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = '(built-in)' 10343b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('FILE', file) 10353b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10363b553e0ab2146ef2055c969a1893b453b2023cf4darylm docloc = self.getdocloc(object) 10373b553e0ab2146ef2055c969a1893b453b2023cf4darylm if docloc is not None: 10383b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('MODULE DOCS', docloc) 10393b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10403b553e0ab2146ef2055c969a1893b453b2023cf4darylm if desc: 10413b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('DESCRIPTION', desc) 10423b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10433b553e0ab2146ef2055c969a1893b453b2023cf4darylm classes = [] 10443b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(object, inspect.isclass): 10453b553e0ab2146ef2055c969a1893b453b2023cf4darylm # if __all__ exists, believe it. Otherwise use old heuristic. 10463b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (all is not None 10473b553e0ab2146ef2055c969a1893b453b2023cf4darylm or (inspect.getmodule(value) or object) is object): 10483b553e0ab2146ef2055c969a1893b453b2023cf4darylm if visiblename(key, all, object): 10493b553e0ab2146ef2055c969a1893b453b2023cf4darylm classes.append((key, value)) 10503b553e0ab2146ef2055c969a1893b453b2023cf4darylm funcs = [] 10513b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(object, inspect.isroutine): 10523b553e0ab2146ef2055c969a1893b453b2023cf4darylm # if __all__ exists, believe it. Otherwise use old heuristic. 10533b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (all is not None or 10543b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isbuiltin(value) or inspect.getmodule(value) is object): 10553b553e0ab2146ef2055c969a1893b453b2023cf4darylm if visiblename(key, all, object): 10563b553e0ab2146ef2055c969a1893b453b2023cf4darylm funcs.append((key, value)) 10573b553e0ab2146ef2055c969a1893b453b2023cf4darylm data = [] 10583b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(object, isdata): 10593b553e0ab2146ef2055c969a1893b453b2023cf4darylm if visiblename(key, all, object): 10603b553e0ab2146ef2055c969a1893b453b2023cf4darylm data.append((key, value)) 10613b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10623b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs = [] 10633b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs_names = set() 10643b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__path__'): 10653b553e0ab2146ef2055c969a1893b453b2023cf4darylm for importer, modname, ispkg in pkgutil.iter_modules(object.__path__): 10663b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs_names.add(modname) 10673b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ispkg: 10683b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs.append(modname + ' (package)') 10693b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 10703b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs.append(modname) 10713b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10723b553e0ab2146ef2055c969a1893b453b2023cf4darylm modpkgs.sort() 10733b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section( 10743b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'PACKAGE CONTENTS', join(modpkgs, '\n')) 10753b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10763b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Detect submodules as sometimes created by C extensions 10773b553e0ab2146ef2055c969a1893b453b2023cf4darylm submodules = [] 10783b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in inspect.getmembers(object, inspect.ismodule): 10793b553e0ab2146ef2055c969a1893b453b2023cf4darylm if value.__name__.startswith(name + '.') and key not in modpkgs_names: 10803b553e0ab2146ef2055c969a1893b453b2023cf4darylm submodules.append(key) 10813b553e0ab2146ef2055c969a1893b453b2023cf4darylm if submodules: 10823b553e0ab2146ef2055c969a1893b453b2023cf4darylm submodules.sort() 10833b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section( 10843b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SUBMODULES', join(submodules, '\n')) 10853b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10863b553e0ab2146ef2055c969a1893b453b2023cf4darylm if classes: 10873b553e0ab2146ef2055c969a1893b453b2023cf4darylm classlist = map(lambda key_value: key_value[1], classes) 10883b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = [self.formattree( 10893b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.getclasstree(classlist, 1), name)] 10903b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in classes: 10913b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents.append(self.document(value, key, name)) 10923b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('CLASSES', join(contents, '\n')) 10933b553e0ab2146ef2055c969a1893b453b2023cf4darylm 10943b553e0ab2146ef2055c969a1893b453b2023cf4darylm if funcs: 10953b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = [] 10963b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in funcs: 10973b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents.append(self.document(value, key, name)) 10983b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('FUNCTIONS', join(contents, '\n')) 10993b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11003b553e0ab2146ef2055c969a1893b453b2023cf4darylm if data: 11013b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = [] 11023b553e0ab2146ef2055c969a1893b453b2023cf4darylm for key, value in data: 11033b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents.append(self.docother(value, key, name, maxlen=70)) 11043b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('DATA', join(contents, '\n')) 11053b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11063b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__version__'): 11073b553e0ab2146ef2055c969a1893b453b2023cf4darylm version = str(object.__version__) 11083b553e0ab2146ef2055c969a1893b453b2023cf4darylm if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': 11093b553e0ab2146ef2055c969a1893b453b2023cf4darylm version = strip(version[11:-1]) 11103b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('VERSION', version) 11113b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__date__'): 11123b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('DATE', str(object.__date__)) 11133b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__author__'): 11143b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('AUTHOR', str(object.__author__)) 11153b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(object, '__credits__'): 11163b553e0ab2146ef2055c969a1893b453b2023cf4darylm result = result + self.section('CREDITS', str(object.__credits__)) 11173b553e0ab2146ef2055c969a1893b453b2023cf4darylm return result 11183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11193b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docclass(self, object, name=None, mod=None, *ignored): 11203b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce text documentation for a given class object.""" 11213b553e0ab2146ef2055c969a1893b453b2023cf4darylm realname = object.__name__ 11223b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = name or realname 11233b553e0ab2146ef2055c969a1893b453b2023cf4darylm bases = object.__bases__ 11243b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11253b553e0ab2146ef2055c969a1893b453b2023cf4darylm def makename(c, m=object.__module__): 11263b553e0ab2146ef2055c969a1893b453b2023cf4darylm return classname(c, m) 11273b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11283b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name == realname: 11293b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = 'class ' + self.bold(realname) 11303b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 11313b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = self.bold(name) + ' = class ' + realname 11323b553e0ab2146ef2055c969a1893b453b2023cf4darylm if bases: 11333b553e0ab2146ef2055c969a1893b453b2023cf4darylm parents = map(makename, bases) 11343b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = title + '(%s)' % join(parents, ', ') 11353b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11363b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = getdoc(object) 11373b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = doc and [doc + '\n'] or [] 11383b553e0ab2146ef2055c969a1893b453b2023cf4darylm push = contents.append 11393b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11403b553e0ab2146ef2055c969a1893b453b2023cf4darylm # List the mro, if non-trivial. 11413b553e0ab2146ef2055c969a1893b453b2023cf4darylm mro = deque(inspect.getmro(object)) 11423b553e0ab2146ef2055c969a1893b453b2023cf4darylm if len(mro) > 2: 11433b553e0ab2146ef2055c969a1893b453b2023cf4darylm push("Method resolution order:") 11443b553e0ab2146ef2055c969a1893b453b2023cf4darylm for base in mro: 11453b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(' ' + makename(base)) 11463b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('') 11473b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11483b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Cute little class to pump out a horizontal rule between sections. 11493b553e0ab2146ef2055c969a1893b453b2023cf4darylm class HorizontalRule: 11503b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self): 11513b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.needone = 0 11523b553e0ab2146ef2055c969a1893b453b2023cf4darylm def maybe(self): 11533b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.needone: 11543b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('-' * 70) 11553b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.needone = 1 11563b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr = HorizontalRule() 11573b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11583b553e0ab2146ef2055c969a1893b453b2023cf4darylm def spill(msg, attrs, predicate): 11593b553e0ab2146ef2055c969a1893b453b2023cf4darylm ok, attrs = _split_list(attrs, predicate) 11603b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ok: 11613b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr.maybe() 11623b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(msg) 11633b553e0ab2146ef2055c969a1893b453b2023cf4darylm for name, kind, homecls, value in ok: 11643b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(self.document(getattr(object, name), 11653b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, mod, object)) 11663b553e0ab2146ef2055c969a1893b453b2023cf4darylm return attrs 11673b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11683b553e0ab2146ef2055c969a1893b453b2023cf4darylm def spilldescriptors(msg, attrs, predicate): 11693b553e0ab2146ef2055c969a1893b453b2023cf4darylm ok, attrs = _split_list(attrs, predicate) 11703b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ok: 11713b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr.maybe() 11723b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(msg) 11733b553e0ab2146ef2055c969a1893b453b2023cf4darylm for name, kind, homecls, value in ok: 11743b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(self._docdescriptor(name, value, mod)) 11753b553e0ab2146ef2055c969a1893b453b2023cf4darylm return attrs 11763b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11773b553e0ab2146ef2055c969a1893b453b2023cf4darylm def spilldata(msg, attrs, predicate): 11783b553e0ab2146ef2055c969a1893b453b2023cf4darylm ok, attrs = _split_list(attrs, predicate) 11793b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ok: 11803b553e0ab2146ef2055c969a1893b453b2023cf4darylm hr.maybe() 11813b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(msg) 11823b553e0ab2146ef2055c969a1893b453b2023cf4darylm for name, kind, homecls, value in ok: 11833b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (hasattr(value, '__call__') or 11843b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isdatadescriptor(value)): 11853b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = getdoc(value) 11863b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 11873b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = None 11883b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(self.docother(getattr(object, name), 11893b553e0ab2146ef2055c969a1893b453b2023cf4darylm name, mod, maxlen=70, doc=doc) + '\n') 11903b553e0ab2146ef2055c969a1893b453b2023cf4darylm return attrs 11913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 11923b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = filter(lambda data: visiblename(data[0], obj=object), 11933b553e0ab2146ef2055c969a1893b453b2023cf4darylm classify_class_attrs(object)) 11943b553e0ab2146ef2055c969a1893b453b2023cf4darylm while attrs: 11953b553e0ab2146ef2055c969a1893b453b2023cf4darylm if mro: 11963b553e0ab2146ef2055c969a1893b453b2023cf4darylm thisclass = mro.popleft() 11973b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 11983b553e0ab2146ef2055c969a1893b453b2023cf4darylm thisclass = attrs[0][2] 11993b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) 12003b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12013b553e0ab2146ef2055c969a1893b453b2023cf4darylm if thisclass is __builtin__.object: 12023b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = inherited 12033b553e0ab2146ef2055c969a1893b453b2023cf4darylm continue 12043b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif thisclass is object: 12053b553e0ab2146ef2055c969a1893b453b2023cf4darylm tag = "defined here" 12063b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 12073b553e0ab2146ef2055c969a1893b453b2023cf4darylm tag = "inherited from %s" % classname(thisclass, 12083b553e0ab2146ef2055c969a1893b453b2023cf4darylm object.__module__) 12093b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12103b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Sort attrs by name. 12113b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs.sort() 12123b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12133b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Pump out the attrs, segregated by kind. 12143b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spill("Methods %s:\n" % tag, attrs, 12153b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'method') 12163b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spill("Class methods %s:\n" % tag, attrs, 12173b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'class method') 12183b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spill("Static methods %s:\n" % tag, attrs, 12193b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'static method') 12203b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs, 12213b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'data descriptor') 12223b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = spilldata("Data and other attributes %s:\n" % tag, attrs, 12233b553e0ab2146ef2055c969a1893b453b2023cf4darylm lambda t: t[1] == 'data') 12243b553e0ab2146ef2055c969a1893b453b2023cf4darylm assert attrs == [] 12253b553e0ab2146ef2055c969a1893b453b2023cf4darylm attrs = inherited 12263b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12273b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = '\n'.join(contents) 12283b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not contents: 12293b553e0ab2146ef2055c969a1893b453b2023cf4darylm return title + '\n' 12303b553e0ab2146ef2055c969a1893b453b2023cf4darylm return title + '\n' + self.indent(rstrip(contents), ' | ') + '\n' 12313b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12323b553e0ab2146ef2055c969a1893b453b2023cf4darylm def formatvalue(self, object): 12333b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Format an argument default value as text.""" 12343b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '=' + self.repr(object) 12353b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12363b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docroutine(self, object, name=None, mod=None, cl=None): 12373b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce text documentation for a function or method object.""" 12383b553e0ab2146ef2055c969a1893b453b2023cf4darylm realname = object.__name__ 12393b553e0ab2146ef2055c969a1893b453b2023cf4darylm name = name or realname 12403b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = '' 12413b553e0ab2146ef2055c969a1893b453b2023cf4darylm skipdocs = 0 12423b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.ismethod(object): 12433b553e0ab2146ef2055c969a1893b453b2023cf4darylm imclass = object.im_class 12443b553e0ab2146ef2055c969a1893b453b2023cf4darylm if cl: 12453b553e0ab2146ef2055c969a1893b453b2023cf4darylm if imclass is not cl: 12463b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = ' from ' + classname(imclass, mod) 12473b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 12483b553e0ab2146ef2055c969a1893b453b2023cf4darylm if object.im_self is not None: 12493b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = ' method of %s instance' % classname( 12503b553e0ab2146ef2055c969a1893b453b2023cf4darylm object.im_self.__class__, mod) 12513b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 12523b553e0ab2146ef2055c969a1893b453b2023cf4darylm note = ' unbound %s method' % classname(imclass,mod) 12533b553e0ab2146ef2055c969a1893b453b2023cf4darylm object = object.im_func 12543b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12553b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name == realname: 12563b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = self.bold(realname) 12573b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 12583b553e0ab2146ef2055c969a1893b453b2023cf4darylm if (cl and realname in cl.__dict__ and 12593b553e0ab2146ef2055c969a1893b453b2023cf4darylm cl.__dict__[realname] is object): 12603b553e0ab2146ef2055c969a1893b453b2023cf4darylm skipdocs = 1 12613b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = self.bold(name) + ' = ' + realname 12623b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isfunction(object): 12633b553e0ab2146ef2055c969a1893b453b2023cf4darylm args, varargs, varkw, defaults = inspect.getargspec(object) 12643b553e0ab2146ef2055c969a1893b453b2023cf4darylm argspec = inspect.formatargspec( 12653b553e0ab2146ef2055c969a1893b453b2023cf4darylm args, varargs, varkw, defaults, formatvalue=self.formatvalue) 12663b553e0ab2146ef2055c969a1893b453b2023cf4darylm if realname == '<lambda>': 12673b553e0ab2146ef2055c969a1893b453b2023cf4darylm title = self.bold(name) + ' lambda ' 12683b553e0ab2146ef2055c969a1893b453b2023cf4darylm argspec = argspec[1:-1] # remove parentheses 12693b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 12703b553e0ab2146ef2055c969a1893b453b2023cf4darylm argspec = '(...)' 12713b553e0ab2146ef2055c969a1893b453b2023cf4darylm decl = title + argspec + note 12723b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12733b553e0ab2146ef2055c969a1893b453b2023cf4darylm if skipdocs: 12743b553e0ab2146ef2055c969a1893b453b2023cf4darylm return decl + '\n' 12753b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 12763b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = getdoc(object) or '' 12773b553e0ab2146ef2055c969a1893b453b2023cf4darylm return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n') 12783b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12793b553e0ab2146ef2055c969a1893b453b2023cf4darylm def _docdescriptor(self, name, value, mod): 12803b553e0ab2146ef2055c969a1893b453b2023cf4darylm results = [] 12813b553e0ab2146ef2055c969a1893b453b2023cf4darylm push = results.append 12823b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12833b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name: 12843b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(self.bold(name)) 12853b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('\n') 12863b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = getdoc(value) or '' 12873b553e0ab2146ef2055c969a1893b453b2023cf4darylm if doc: 12883b553e0ab2146ef2055c969a1893b453b2023cf4darylm push(self.indent(doc)) 12893b553e0ab2146ef2055c969a1893b453b2023cf4darylm push('\n') 12903b553e0ab2146ef2055c969a1893b453b2023cf4darylm return ''.join(results) 12913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12923b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docproperty(self, object, name=None, mod=None, cl=None): 12933b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce text documentation for a property.""" 12943b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self._docdescriptor(name, object, mod) 12953b553e0ab2146ef2055c969a1893b453b2023cf4darylm 12963b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docdata(self, object, name=None, mod=None, cl=None): 12973b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce text documentation for a data descriptor.""" 12983b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self._docdescriptor(name, object, mod) 12993b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13003b553e0ab2146ef2055c969a1893b453b2023cf4darylm def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None): 13013b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce text documentation for a data object.""" 13023b553e0ab2146ef2055c969a1893b453b2023cf4darylm repr = self.repr(object) 13033b553e0ab2146ef2055c969a1893b453b2023cf4darylm if maxlen: 13043b553e0ab2146ef2055c969a1893b453b2023cf4darylm line = (name and name + ' = ' or '') + repr 13053b553e0ab2146ef2055c969a1893b453b2023cf4darylm chop = maxlen - len(line) 13063b553e0ab2146ef2055c969a1893b453b2023cf4darylm if chop < 0: repr = repr[:chop] + '...' 13073b553e0ab2146ef2055c969a1893b453b2023cf4darylm line = (name and self.bold(name) + ' = ' or '') + repr 13083b553e0ab2146ef2055c969a1893b453b2023cf4darylm if doc is not None: 13093b553e0ab2146ef2055c969a1893b453b2023cf4darylm line += '\n' + self.indent(str(doc)) 13103b553e0ab2146ef2055c969a1893b453b2023cf4darylm return line 13113b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13123b553e0ab2146ef2055c969a1893b453b2023cf4darylm# --------------------------------------------------------- user interfaces 13133b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13143b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef pager(text): 13153b553e0ab2146ef2055c969a1893b453b2023cf4darylm """The first time this is called, determine what kind of pager to use.""" 13163b553e0ab2146ef2055c969a1893b453b2023cf4darylm global pager 13173b553e0ab2146ef2055c969a1893b453b2023cf4darylm pager = getpager() 13183b553e0ab2146ef2055c969a1893b453b2023cf4darylm pager(text) 13193b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13203b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef getpager(): 13213b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Decide what method to use for paging through text.""" 13223b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(sys.stdout) is not types.FileType: 13233b553e0ab2146ef2055c969a1893b453b2023cf4darylm return plainpager 13243b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not sys.stdin.isatty() or not sys.stdout.isatty(): 13253b553e0ab2146ef2055c969a1893b453b2023cf4darylm return plainpager 13263b553e0ab2146ef2055c969a1893b453b2023cf4darylm if 'PAGER' in os.environ: 13273b553e0ab2146ef2055c969a1893b453b2023cf4darylm if sys.platform == 'win32': # pipes completely broken in Windows 13283b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lambda text: tempfilepager(plain(text), os.environ['PAGER']) 13293b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif sys.platform == 'uefi': 13303b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lambda text: tempfilepager(plain(text), os.environ['PAGER']) 13313b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif os.environ.get('TERM') in ('dumb', 'emacs'): 13323b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lambda text: pipepager(plain(text), os.environ['PAGER']) 13333b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 13343b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lambda text: pipepager(text, os.environ['PAGER']) 13353b553e0ab2146ef2055c969a1893b453b2023cf4darylm if os.environ.get('TERM') in ('dumb', 'emacs'): 13363b553e0ab2146ef2055c969a1893b453b2023cf4darylm return plainpager 13373b553e0ab2146ef2055c969a1893b453b2023cf4darylm if sys.platform == 'uefi': 13383b553e0ab2146ef2055c969a1893b453b2023cf4darylm return plainpager 13393b553e0ab2146ef2055c969a1893b453b2023cf4darylm if sys.platform == 'win32' or sys.platform.startswith('os2'): 13403b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lambda text: tempfilepager(plain(text), 'more <') 13413b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0: 13423b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lambda text: pipepager(text, 'less') 13433b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13443b553e0ab2146ef2055c969a1893b453b2023cf4darylm import tempfile 13453b553e0ab2146ef2055c969a1893b453b2023cf4darylm (fd, filename) = tempfile.mkstemp() 13463b553e0ab2146ef2055c969a1893b453b2023cf4darylm os.close(fd) 13473b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 13483b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0: 13493b553e0ab2146ef2055c969a1893b453b2023cf4darylm return lambda text: pipepager(text, 'more') 13503b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 13513b553e0ab2146ef2055c969a1893b453b2023cf4darylm return ttypager 13523b553e0ab2146ef2055c969a1893b453b2023cf4darylm finally: 13533b553e0ab2146ef2055c969a1893b453b2023cf4darylm os.unlink(filename) 13543b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13553b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef plain(text): 13563b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Remove boldface formatting from text.""" 13573b553e0ab2146ef2055c969a1893b453b2023cf4darylm return re.sub('.\b', '', text) 13583b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13593b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef pipepager(text, cmd): 13603b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Page through text by feeding it to another program.""" 13613b553e0ab2146ef2055c969a1893b453b2023cf4darylm pipe = os.popen(cmd, 'w') 13623b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 13633b553e0ab2146ef2055c969a1893b453b2023cf4darylm pipe.write(text) 13643b553e0ab2146ef2055c969a1893b453b2023cf4darylm pipe.close() 13653b553e0ab2146ef2055c969a1893b453b2023cf4darylm except IOError: 13663b553e0ab2146ef2055c969a1893b453b2023cf4darylm pass # Ignore broken pipes caused by quitting the pager program. 13673b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13683b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef tempfilepager(text, cmd): 13693b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Page through text by invoking a program on a temporary file.""" 13703b553e0ab2146ef2055c969a1893b453b2023cf4darylm import tempfile 13713b553e0ab2146ef2055c969a1893b453b2023cf4darylm filename = tempfile.mktemp() 13723b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = open(filename, 'w') 13733b553e0ab2146ef2055c969a1893b453b2023cf4darylm file.write(text) 13743b553e0ab2146ef2055c969a1893b453b2023cf4darylm file.close() 13753b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 13763b553e0ab2146ef2055c969a1893b453b2023cf4darylm os.system(cmd + ' "' + filename + '"') 13773b553e0ab2146ef2055c969a1893b453b2023cf4darylm finally: 13783b553e0ab2146ef2055c969a1893b453b2023cf4darylm os.unlink(filename) 13793b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13803b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef ttypager(text): 13813b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Page through text on a text terminal.""" 13823b553e0ab2146ef2055c969a1893b453b2023cf4darylm lines = split(plain(text), '\n') 13833b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 13843b553e0ab2146ef2055c969a1893b453b2023cf4darylm import tty 13853b553e0ab2146ef2055c969a1893b453b2023cf4darylm fd = sys.stdin.fileno() 13863b553e0ab2146ef2055c969a1893b453b2023cf4darylm old = tty.tcgetattr(fd) 13873b553e0ab2146ef2055c969a1893b453b2023cf4darylm tty.setcbreak(fd) 13883b553e0ab2146ef2055c969a1893b453b2023cf4darylm getchar = lambda: sys.stdin.read(1) 13893b553e0ab2146ef2055c969a1893b453b2023cf4darylm except (ImportError, AttributeError): 13903b553e0ab2146ef2055c969a1893b453b2023cf4darylm tty = None 13913b553e0ab2146ef2055c969a1893b453b2023cf4darylm getchar = lambda: sys.stdin.readline()[:-1][:1] 13923b553e0ab2146ef2055c969a1893b453b2023cf4darylm 13933b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 13943b553e0ab2146ef2055c969a1893b453b2023cf4darylm r = inc = os.environ.get('LINES', 25) - 1 13953b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.stdout.write(join(lines[:inc], '\n') + '\n') 13963b553e0ab2146ef2055c969a1893b453b2023cf4darylm while lines[r:]: 13973b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.stdout.write('-- more --') 13983b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.stdout.flush() 13993b553e0ab2146ef2055c969a1893b453b2023cf4darylm c = getchar() 14003b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14013b553e0ab2146ef2055c969a1893b453b2023cf4darylm if c in ('q', 'Q'): 14023b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.stdout.write('\r \r') 14033b553e0ab2146ef2055c969a1893b453b2023cf4darylm break 14043b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif c in ('\r', '\n'): 14053b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.stdout.write('\r \r' + lines[r] + '\n') 14063b553e0ab2146ef2055c969a1893b453b2023cf4darylm r = r + 1 14073b553e0ab2146ef2055c969a1893b453b2023cf4darylm continue 14083b553e0ab2146ef2055c969a1893b453b2023cf4darylm if c in ('b', 'B', '\x1b'): 14093b553e0ab2146ef2055c969a1893b453b2023cf4darylm r = r - inc - inc 14103b553e0ab2146ef2055c969a1893b453b2023cf4darylm if r < 0: r = 0 14113b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.stdout.write('\n' + join(lines[r:r+inc], '\n') + '\n') 14123b553e0ab2146ef2055c969a1893b453b2023cf4darylm r = r + inc 14133b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14143b553e0ab2146ef2055c969a1893b453b2023cf4darylm finally: 14153b553e0ab2146ef2055c969a1893b453b2023cf4darylm if tty: 14163b553e0ab2146ef2055c969a1893b453b2023cf4darylm tty.tcsetattr(fd, tty.TCSAFLUSH, old) 14173b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14183b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef plainpager(text): 14193b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Simply print unformatted text. This is the ultimate fallback.""" 14203b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.stdout.write(plain(text)) 14213b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14223b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef describe(thing): 14233b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Produce a short description of the given thing.""" 14243b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.ismodule(thing): 14253b553e0ab2146ef2055c969a1893b453b2023cf4darylm if thing.__name__ in sys.builtin_module_names: 14263b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'built-in module ' + thing.__name__ 14273b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(thing, '__path__'): 14283b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'package ' + thing.__name__ 14293b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 14303b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'module ' + thing.__name__ 14313b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isbuiltin(thing): 14323b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'built-in function ' + thing.__name__ 14333b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isgetsetdescriptor(thing): 14343b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'getset descriptor %s.%s.%s' % ( 14353b553e0ab2146ef2055c969a1893b453b2023cf4darylm thing.__objclass__.__module__, thing.__objclass__.__name__, 14363b553e0ab2146ef2055c969a1893b453b2023cf4darylm thing.__name__) 14373b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.ismemberdescriptor(thing): 14383b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'member descriptor %s.%s.%s' % ( 14393b553e0ab2146ef2055c969a1893b453b2023cf4darylm thing.__objclass__.__module__, thing.__objclass__.__name__, 14403b553e0ab2146ef2055c969a1893b453b2023cf4darylm thing.__name__) 14413b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isclass(thing): 14423b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'class ' + thing.__name__ 14433b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.isfunction(thing): 14443b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'function ' + thing.__name__ 14453b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.ismethod(thing): 14463b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'method ' + thing.__name__ 14473b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(thing) is types.InstanceType: 14483b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 'instance of ' + thing.__class__.__name__ 14493b553e0ab2146ef2055c969a1893b453b2023cf4darylm return type(thing).__name__ 14503b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14513b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef locate(path, forceload=0): 14523b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Locate an object by name or dotted path, importing as necessary.""" 14533b553e0ab2146ef2055c969a1893b453b2023cf4darylm parts = [part for part in split(path, '.') if part] 14543b553e0ab2146ef2055c969a1893b453b2023cf4darylm module, n = None, 0 14553b553e0ab2146ef2055c969a1893b453b2023cf4darylm while n < len(parts): 14563b553e0ab2146ef2055c969a1893b453b2023cf4darylm nextmodule = safeimport(join(parts[:n+1], '.'), forceload) 14573b553e0ab2146ef2055c969a1893b453b2023cf4darylm if nextmodule: module, n = nextmodule, n + 1 14583b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: break 14593b553e0ab2146ef2055c969a1893b453b2023cf4darylm if module: 14603b553e0ab2146ef2055c969a1893b453b2023cf4darylm object = module 14613b553e0ab2146ef2055c969a1893b453b2023cf4darylm for part in parts[n:]: 14623b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: object = getattr(object, part) 14633b553e0ab2146ef2055c969a1893b453b2023cf4darylm except AttributeError: return None 14643b553e0ab2146ef2055c969a1893b453b2023cf4darylm return object 14653b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 14663b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(__builtin__, path): 14673b553e0ab2146ef2055c969a1893b453b2023cf4darylm return getattr(__builtin__, path) 14683b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14693b553e0ab2146ef2055c969a1893b453b2023cf4darylm# --------------------------------------- interactive interpreter interface 14703b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14713b553e0ab2146ef2055c969a1893b453b2023cf4darylmtext = TextDoc() 14723b553e0ab2146ef2055c969a1893b453b2023cf4darylmhtml = HTMLDoc() 14733b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14743b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass _OldStyleClass: pass 14753b553e0ab2146ef2055c969a1893b453b2023cf4darylm_OLD_INSTANCE_TYPE = type(_OldStyleClass()) 14763b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14773b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef resolve(thing, forceload=0): 14783b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Given an object or a path to an object, get the object and its name.""" 14793b553e0ab2146ef2055c969a1893b453b2023cf4darylm if isinstance(thing, str): 14803b553e0ab2146ef2055c969a1893b453b2023cf4darylm object = locate(thing, forceload) 14813b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not object: 14823b553e0ab2146ef2055c969a1893b453b2023cf4darylm raise ImportError, 'no Python documentation found for %r' % thing 14833b553e0ab2146ef2055c969a1893b453b2023cf4darylm return object, thing 14843b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 14853b553e0ab2146ef2055c969a1893b453b2023cf4darylm return thing, getattr(thing, '__name__', None) 14863b553e0ab2146ef2055c969a1893b453b2023cf4darylm 14873b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef render_doc(thing, title='Python Library Documentation: %s', forceload=0): 14883b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Render text documentation, given an object or a path to an object.""" 14893b553e0ab2146ef2055c969a1893b453b2023cf4darylm object, name = resolve(thing, forceload) 14903b553e0ab2146ef2055c969a1893b453b2023cf4darylm desc = describe(object) 14913b553e0ab2146ef2055c969a1893b453b2023cf4darylm module = inspect.getmodule(object) 14923b553e0ab2146ef2055c969a1893b453b2023cf4darylm if name and '.' in name: 14933b553e0ab2146ef2055c969a1893b453b2023cf4darylm desc += ' in ' + name[:name.rfind('.')] 14943b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif module and module is not object: 14953b553e0ab2146ef2055c969a1893b453b2023cf4darylm desc += ' in module ' + module.__name__ 14963b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(object) is _OLD_INSTANCE_TYPE: 14973b553e0ab2146ef2055c969a1893b453b2023cf4darylm # If the passed object is an instance of an old-style class, 14983b553e0ab2146ef2055c969a1893b453b2023cf4darylm # document its available methods instead of its value. 14993b553e0ab2146ef2055c969a1893b453b2023cf4darylm object = object.__class__ 15003b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif not (inspect.ismodule(object) or 15013b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isclass(object) or 15023b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isroutine(object) or 15033b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.isgetsetdescriptor(object) or 15043b553e0ab2146ef2055c969a1893b453b2023cf4darylm inspect.ismemberdescriptor(object) or 15053b553e0ab2146ef2055c969a1893b453b2023cf4darylm isinstance(object, property)): 15063b553e0ab2146ef2055c969a1893b453b2023cf4darylm # If the passed object is a piece of data or an instance, 15073b553e0ab2146ef2055c969a1893b453b2023cf4darylm # document its available methods instead of its value. 15083b553e0ab2146ef2055c969a1893b453b2023cf4darylm object = type(object) 15093b553e0ab2146ef2055c969a1893b453b2023cf4darylm desc += ' object' 15103b553e0ab2146ef2055c969a1893b453b2023cf4darylm return title % desc + '\n\n' + text.document(object, name) 15113b553e0ab2146ef2055c969a1893b453b2023cf4darylm 15123b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef doc(thing, title='Python Library Documentation: %s', forceload=0): 15133b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Display text documentation, given an object or a path to an object.""" 15143b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 15153b553e0ab2146ef2055c969a1893b453b2023cf4darylm pager(render_doc(thing, title, forceload)) 15163b553e0ab2146ef2055c969a1893b453b2023cf4darylm except (ImportError, ErrorDuringImport), value: 15173b553e0ab2146ef2055c969a1893b453b2023cf4darylm print value 15183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 15193b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef writedoc(thing, forceload=0): 15203b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Write HTML documentation to a file in the current directory.""" 15213b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 15223b553e0ab2146ef2055c969a1893b453b2023cf4darylm object, name = resolve(thing, forceload) 15233b553e0ab2146ef2055c969a1893b453b2023cf4darylm page = html.page(describe(object), html.document(object, name)) 15243b553e0ab2146ef2055c969a1893b453b2023cf4darylm file = open(name + '.html', 'w') 15253b553e0ab2146ef2055c969a1893b453b2023cf4darylm file.write(page) 15263b553e0ab2146ef2055c969a1893b453b2023cf4darylm file.close() 15273b553e0ab2146ef2055c969a1893b453b2023cf4darylm print 'wrote', name + '.html' 15283b553e0ab2146ef2055c969a1893b453b2023cf4darylm except (ImportError, ErrorDuringImport), value: 15293b553e0ab2146ef2055c969a1893b453b2023cf4darylm print value 15303b553e0ab2146ef2055c969a1893b453b2023cf4darylm 15313b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef writedocs(dir, pkgpath='', done=None): 15323b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Write out HTML documentation for all modules in a directory tree.""" 15333b553e0ab2146ef2055c969a1893b453b2023cf4darylm if done is None: done = {} 15343b553e0ab2146ef2055c969a1893b453b2023cf4darylm for importer, modname, ispkg in pkgutil.walk_packages([dir], pkgpath): 15353b553e0ab2146ef2055c969a1893b453b2023cf4darylm writedoc(modname) 15363b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 15373b553e0ab2146ef2055c969a1893b453b2023cf4darylm 15383b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass Helper: 15393b553e0ab2146ef2055c969a1893b453b2023cf4darylm 15403b553e0ab2146ef2055c969a1893b453b2023cf4darylm # These dictionaries map a topic name to either an alias, or a tuple 15413b553e0ab2146ef2055c969a1893b453b2023cf4darylm # (label, seealso-items). The "label" is the label of the corresponding 15423b553e0ab2146ef2055c969a1893b453b2023cf4darylm # section in the .rst file under Doc/ and an index into the dictionary 15433b553e0ab2146ef2055c969a1893b453b2023cf4darylm # in pydoc_data/topics.py. 15443b553e0ab2146ef2055c969a1893b453b2023cf4darylm # 15453b553e0ab2146ef2055c969a1893b453b2023cf4darylm # CAUTION: if you change one of these dictionaries, be sure to adapt the 15463b553e0ab2146ef2055c969a1893b453b2023cf4darylm # list of needed labels in Doc/tools/sphinxext/pyspecific.py and 15473b553e0ab2146ef2055c969a1893b453b2023cf4darylm # regenerate the pydoc_data/topics.py file by running 15483b553e0ab2146ef2055c969a1893b453b2023cf4darylm # make pydoc-topics 15493b553e0ab2146ef2055c969a1893b453b2023cf4darylm # in Doc/ and copying the output file into the Lib/ directory. 15503b553e0ab2146ef2055c969a1893b453b2023cf4darylm 15513b553e0ab2146ef2055c969a1893b453b2023cf4darylm keywords = { 15523b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'and': 'BOOLEAN', 15533b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'as': 'with', 15543b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'assert': ('assert', ''), 15553b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'break': ('break', 'while for'), 15563b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'class': ('class', 'CLASSES SPECIALMETHODS'), 15573b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'continue': ('continue', 'while for'), 15583b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'def': ('function', ''), 15593b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'del': ('del', 'BASICMETHODS'), 15603b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'elif': 'if', 15613b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'else': ('else', 'while for'), 15623b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'except': 'try', 15633b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'exec': ('exec', ''), 15643b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'finally': 'try', 15653b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'for': ('for', 'break continue while'), 15663b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'from': 'import', 15673b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'global': ('global', 'NAMESPACES'), 15683b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'if': ('if', 'TRUTHVALUE'), 15693b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'import': ('import', 'MODULES'), 15703b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'in': ('in', 'SEQUENCEMETHODS2'), 15713b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'is': 'COMPARISON', 15723b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'lambda': ('lambda', 'FUNCTIONS'), 15733b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'not': 'BOOLEAN', 15743b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'or': 'BOOLEAN', 15753b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'pass': ('pass', ''), 15763b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'print': ('print', ''), 15773b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'raise': ('raise', 'EXCEPTIONS'), 15783b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'return': ('return', 'FUNCTIONS'), 15793b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'try': ('try', 'EXCEPTIONS'), 15803b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'while': ('while', 'break continue if TRUTHVALUE'), 15813b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'), 15823b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'yield': ('yield', ''), 15833b553e0ab2146ef2055c969a1893b453b2023cf4darylm } 15843b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Either add symbols to this dictionary or to the symbols dictionary 15853b553e0ab2146ef2055c969a1893b453b2023cf4darylm # directly: Whichever is easier. They are merged later. 15863b553e0ab2146ef2055c969a1893b453b2023cf4darylm _symbols_inverse = { 15873b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'), 15883b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', 15893b553e0ab2146ef2055c969a1893b453b2023cf4darylm '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'), 15903b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'), 15913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'UNARY' : ('-', '~'), 15923b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=', 15933b553e0ab2146ef2055c969a1893b453b2023cf4darylm '^=', '<<=', '>>=', '**=', '//='), 15943b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'), 15953b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'COMPLEX' : ('j', 'J') 15963b553e0ab2146ef2055c969a1893b453b2023cf4darylm } 15973b553e0ab2146ef2055c969a1893b453b2023cf4darylm symbols = { 15983b553e0ab2146ef2055c969a1893b453b2023cf4darylm '%': 'OPERATORS FORMATTING', 15993b553e0ab2146ef2055c969a1893b453b2023cf4darylm '**': 'POWER', 16003b553e0ab2146ef2055c969a1893b453b2023cf4darylm ',': 'TUPLES LISTS FUNCTIONS', 16013b553e0ab2146ef2055c969a1893b453b2023cf4darylm '.': 'ATTRIBUTES FLOAT MODULES OBJECTS', 16023b553e0ab2146ef2055c969a1893b453b2023cf4darylm '...': 'ELLIPSIS', 16033b553e0ab2146ef2055c969a1893b453b2023cf4darylm ':': 'SLICINGS DICTIONARYLITERALS', 16043b553e0ab2146ef2055c969a1893b453b2023cf4darylm '@': 'def class', 16053b553e0ab2146ef2055c969a1893b453b2023cf4darylm '\\': 'STRINGS', 16063b553e0ab2146ef2055c969a1893b453b2023cf4darylm '_': 'PRIVATENAMES', 16073b553e0ab2146ef2055c969a1893b453b2023cf4darylm '__': 'PRIVATENAMES SPECIALMETHODS', 16083b553e0ab2146ef2055c969a1893b453b2023cf4darylm '`': 'BACKQUOTES', 16093b553e0ab2146ef2055c969a1893b453b2023cf4darylm '(': 'TUPLES FUNCTIONS CALLS', 16103b553e0ab2146ef2055c969a1893b453b2023cf4darylm ')': 'TUPLES FUNCTIONS CALLS', 16113b553e0ab2146ef2055c969a1893b453b2023cf4darylm '[': 'LISTS SUBSCRIPTS SLICINGS', 16123b553e0ab2146ef2055c969a1893b453b2023cf4darylm ']': 'LISTS SUBSCRIPTS SLICINGS' 16133b553e0ab2146ef2055c969a1893b453b2023cf4darylm } 16143b553e0ab2146ef2055c969a1893b453b2023cf4darylm for topic, symbols_ in _symbols_inverse.iteritems(): 16153b553e0ab2146ef2055c969a1893b453b2023cf4darylm for symbol in symbols_: 16163b553e0ab2146ef2055c969a1893b453b2023cf4darylm topics = symbols.get(symbol, topic) 16173b553e0ab2146ef2055c969a1893b453b2023cf4darylm if topic not in topics: 16183b553e0ab2146ef2055c969a1893b453b2023cf4darylm topics = topics + ' ' + topic 16193b553e0ab2146ef2055c969a1893b453b2023cf4darylm symbols[symbol] = topics 16203b553e0ab2146ef2055c969a1893b453b2023cf4darylm 16213b553e0ab2146ef2055c969a1893b453b2023cf4darylm topics = { 16223b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS ' 16233b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FUNCTIONS CLASSES MODULES FILES inspect'), 16243b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING ' 16253b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TYPES'), 16263b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'), 16273b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FORMATTING': ('formatstrings', 'OPERATORS'), 16283b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS ' 16293b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FORMATTING TYPES'), 16303b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'), 16313b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'INTEGER': ('integers', 'int range'), 16323b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FLOAT': ('floating', 'float math'), 16333b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'COMPLEX': ('imaginary', 'complex cmath'), 16343b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING xrange LISTS'), 16353b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'MAPPINGS': 'DICTIONARIES', 16363b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FUNCTIONS': ('typesfunctions', 'def TYPES'), 16373b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'METHODS': ('typesmethods', 'class def CLASSES TYPES'), 16383b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'), 16393b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'), 16403b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FRAMEOBJECTS': 'TYPES', 16413b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TRACEBACKS': 'TYPES', 16423b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'NONE': ('bltin-null-object', ''), 16433b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'), 16443b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FILES': ('bltin-file-objects', ''), 16453b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SPECIALATTRIBUTES': ('specialattrs', ''), 16463b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'), 16473b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'MODULES': ('typesmodules', 'import'), 16483b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'PACKAGES': 'import', 16493b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN ' 16503b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER ' 16513b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES ' 16523b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'LISTS DICTIONARIES BACKQUOTES'), 16533b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'OPERATORS': 'EXPRESSIONS', 16543b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'PRECEDENCE': 'EXPRESSIONS', 16553b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'OBJECTS': ('objects', 'TYPES'), 16563b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS ' 16573b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS ' 16583b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'), 16593b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'), 16603b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'), 16613b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'), 16623b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SEQUENCEMETHODS1': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 ' 16633b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SPECIALMETHODS'), 16643b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SEQUENCEMETHODS2': ('sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 ' 16653b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SPECIALMETHODS'), 16663b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'), 16673b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT ' 16683b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SPECIALMETHODS'), 16693b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'), 16703b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'), 16713b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'DYNAMICFEATURES': ('dynamic-features', ''), 16723b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SCOPING': 'NAMESPACES', 16733b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'FRAMES': 'NAMESPACES', 16743b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'EXCEPTIONS': ('exceptions', 'try except finally raise'), 16753b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'COERCIONS': ('coercion-rules','CONVERSIONS'), 16763b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CONVERSIONS': ('conversions', 'COERCIONS'), 16773b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'), 16783b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SPECIALIDENTIFIERS': ('id-classes', ''), 16793b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'PRIVATENAMES': ('atom-identifiers', ''), 16803b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'LITERALS': ('atom-literals', 'STRINGS BACKQUOTES NUMBERS ' 16813b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'), 16823b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TUPLES': 'SEQUENCES', 16833b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'), 16843b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'LISTS': ('typesseq-mutable', 'LISTLITERALS'), 16853b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'LISTLITERALS': ('lists', 'LISTS LITERALS'), 16863b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'), 16873b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'), 16883b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'BACKQUOTES': ('string-conversions', 'repr str STRINGS LITERALS'), 16893b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ' 16903b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'ATTRIBUTEMETHODS'), 16913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'), 16923b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'), 16933b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CALLS': ('calls', 'EXPRESSIONS'), 16943b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'POWER': ('power', 'EXPRESSIONS'), 16953b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'UNARY': ('unary', 'EXPRESSIONS'), 16963b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'BINARY': ('binary', 'EXPRESSIONS'), 16973b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'SHIFTING': ('shifting', 'EXPRESSIONS'), 16983b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'BITWISE': ('bitwise', 'EXPRESSIONS'), 16993b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'), 17003b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'), 17013b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'ASSERTION': 'assert', 17023b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'), 17033b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'), 17043b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'DELETION': 'del', 17053b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'PRINTING': 'print', 17063b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'RETURNING': 'return', 17073b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'IMPORTING': 'import', 17083b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CONDITIONAL': 'if', 17093b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'LOOPING': ('compound', 'for while break continue'), 17103b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'), 17113b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'DEBUGGING': ('debugger', 'pdb'), 17123b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'CONTEXTMANAGERS': ('context-managers', 'with'), 17133b553e0ab2146ef2055c969a1893b453b2023cf4darylm } 17143b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17153b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self, input=None, output=None): 17163b553e0ab2146ef2055c969a1893b453b2023cf4darylm self._input = input 17173b553e0ab2146ef2055c969a1893b453b2023cf4darylm self._output = output 17183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17193b553e0ab2146ef2055c969a1893b453b2023cf4darylm input = property(lambda self: self._input or sys.stdin) 17203b553e0ab2146ef2055c969a1893b453b2023cf4darylm output = property(lambda self: self._output or sys.stdout) 17213b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17223b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __repr__(self): 17233b553e0ab2146ef2055c969a1893b453b2023cf4darylm if inspect.stack()[1][3] == '?': 17243b553e0ab2146ef2055c969a1893b453b2023cf4darylm self() 17253b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '' 17263b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<pydoc.Helper instance>' 17273b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17283b553e0ab2146ef2055c969a1893b453b2023cf4darylm _GoInteractive = object() 17293b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __call__(self, request=_GoInteractive): 17303b553e0ab2146ef2055c969a1893b453b2023cf4darylm if request is not self._GoInteractive: 17313b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.help(request) 17323b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 17333b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.intro() 17343b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.interact() 17353b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 17363b553e0ab2146ef2055c969a1893b453b2023cf4darylmYou are now leaving help and returning to the Python interpreter. 17373b553e0ab2146ef2055c969a1893b453b2023cf4darylmIf you want to ask for help on a particular object directly from the 17383b553e0ab2146ef2055c969a1893b453b2023cf4darylminterpreter, you can type "help(object)". Executing "help('string')" 17393b553e0ab2146ef2055c969a1893b453b2023cf4darylmhas the same effect as typing a particular string at the help> prompt. 17403b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 17413b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17423b553e0ab2146ef2055c969a1893b453b2023cf4darylm def interact(self): 17433b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write('\n') 17443b553e0ab2146ef2055c969a1893b453b2023cf4darylm while True: 17453b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 17463b553e0ab2146ef2055c969a1893b453b2023cf4darylm request = self.getline('help> ') 17473b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not request: break 17483b553e0ab2146ef2055c969a1893b453b2023cf4darylm except (KeyboardInterrupt, EOFError): 17493b553e0ab2146ef2055c969a1893b453b2023cf4darylm break 17503b553e0ab2146ef2055c969a1893b453b2023cf4darylm request = strip(replace(request, '"', '', "'", '')) 17513b553e0ab2146ef2055c969a1893b453b2023cf4darylm if lower(request) in ('q', 'quit'): break 17523b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.help(request) 17533b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17543b553e0ab2146ef2055c969a1893b453b2023cf4darylm def getline(self, prompt): 17553b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Read one line, using raw_input when available.""" 17563b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.input is sys.stdin: 17573b553e0ab2146ef2055c969a1893b453b2023cf4darylm return raw_input(prompt) 17583b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 17593b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(prompt) 17603b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.flush() 17613b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.input.readline() 17623b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17633b553e0ab2146ef2055c969a1893b453b2023cf4darylm def help(self, request): 17643b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(request) is type(''): 17653b553e0ab2146ef2055c969a1893b453b2023cf4darylm request = request.strip() 17663b553e0ab2146ef2055c969a1893b453b2023cf4darylm if request == 'help': self.intro() 17673b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request == 'keywords': self.listkeywords() 17683b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request == 'symbols': self.listsymbols() 17693b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request == 'topics': self.listtopics() 17703b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request == 'modules': self.listmodules() 17713b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request[:8] == 'modules ': 17723b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.listmodules(split(request)[1]) 17733b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request in self.symbols: self.showsymbol(request) 17743b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request in self.keywords: self.showtopic(request) 17753b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request in self.topics: self.showtopic(request) 17763b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif request: doc(request, 'Help on %s:') 17773b553e0ab2146ef2055c969a1893b453b2023cf4darylm elif isinstance(request, Helper): self() 17783b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: doc(request, 'Help on %s:') 17793b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write('\n') 17803b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17813b553e0ab2146ef2055c969a1893b453b2023cf4darylm def intro(self): 17823b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 17833b553e0ab2146ef2055c969a1893b453b2023cf4darylmWelcome to Python %s! This is the online help utility. 17843b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17853b553e0ab2146ef2055c969a1893b453b2023cf4darylmIf this is your first time using Python, you should definitely check out 17863b553e0ab2146ef2055c969a1893b453b2023cf4darylmthe tutorial on the Internet at http://docs.python.org/tutorial/. 17873b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17883b553e0ab2146ef2055c969a1893b453b2023cf4darylmEnter the name of any module, keyword, or topic to get help on writing 17893b553e0ab2146ef2055c969a1893b453b2023cf4darylmPython programs and using Python modules. To quit this help utility and 17903b553e0ab2146ef2055c969a1893b453b2023cf4darylmreturn to the interpreter, just type "quit". 17913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17923b553e0ab2146ef2055c969a1893b453b2023cf4darylmTo get a list of available modules, keywords, or topics, type "modules", 17933b553e0ab2146ef2055c969a1893b453b2023cf4darylm"keywords", or "topics". Each module also comes with a one-line summary 17943b553e0ab2146ef2055c969a1893b453b2023cf4darylmof what it does; to list the modules whose summaries contain a given word 17953b553e0ab2146ef2055c969a1893b453b2023cf4darylmsuch as "spam", type "modules spam". 17963b553e0ab2146ef2055c969a1893b453b2023cf4darylm''' % sys.version[:3]) 17973b553e0ab2146ef2055c969a1893b453b2023cf4darylm 17983b553e0ab2146ef2055c969a1893b453b2023cf4darylm def list(self, items, columns=4, width=80): 17993b553e0ab2146ef2055c969a1893b453b2023cf4darylm items = items[:] 18003b553e0ab2146ef2055c969a1893b453b2023cf4darylm items.sort() 18013b553e0ab2146ef2055c969a1893b453b2023cf4darylm colw = width / columns 18023b553e0ab2146ef2055c969a1893b453b2023cf4darylm rows = (len(items) + columns - 1) / columns 18033b553e0ab2146ef2055c969a1893b453b2023cf4darylm for row in range(rows): 18043b553e0ab2146ef2055c969a1893b453b2023cf4darylm for col in range(columns): 18053b553e0ab2146ef2055c969a1893b453b2023cf4darylm i = col * rows + row 18063b553e0ab2146ef2055c969a1893b453b2023cf4darylm if i < len(items): 18073b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(items[i]) 18083b553e0ab2146ef2055c969a1893b453b2023cf4darylm if col < columns - 1: 18093b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(' ' + ' ' * (colw-1 - len(items[i]))) 18103b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write('\n') 18113b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18123b553e0ab2146ef2055c969a1893b453b2023cf4darylm def listkeywords(self): 18133b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 18143b553e0ab2146ef2055c969a1893b453b2023cf4darylmHere is a list of the Python keywords. Enter any keyword to get more help. 18153b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18163b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 18173b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.list(self.keywords.keys()) 18183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18193b553e0ab2146ef2055c969a1893b453b2023cf4darylm def listsymbols(self): 18203b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 18213b553e0ab2146ef2055c969a1893b453b2023cf4darylmHere is a list of the punctuation symbols which Python assigns special meaning 18223b553e0ab2146ef2055c969a1893b453b2023cf4darylmto. Enter any symbol to get more help. 18233b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18243b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 18253b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.list(self.symbols.keys()) 18263b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18273b553e0ab2146ef2055c969a1893b453b2023cf4darylm def listtopics(self): 18283b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 18293b553e0ab2146ef2055c969a1893b453b2023cf4darylmHere is a list of available topics. Enter any topic name to get more help. 18303b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18313b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 18323b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.list(self.topics.keys()) 18333b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18343b553e0ab2146ef2055c969a1893b453b2023cf4darylm def showtopic(self, topic, more_xrefs=''): 18353b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 18363b553e0ab2146ef2055c969a1893b453b2023cf4darylm import pydoc_data.topics 18373b553e0ab2146ef2055c969a1893b453b2023cf4darylm except ImportError: 18383b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 18393b553e0ab2146ef2055c969a1893b453b2023cf4darylmSorry, topic and keyword documentation is not available because the 18403b553e0ab2146ef2055c969a1893b453b2023cf4darylmmodule "pydoc_data.topics" could not be found. 18413b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 18423b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 18433b553e0ab2146ef2055c969a1893b453b2023cf4darylm target = self.topics.get(topic, self.keywords.get(topic)) 18443b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not target: 18453b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write('no documentation found for %s\n' % repr(topic)) 18463b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 18473b553e0ab2146ef2055c969a1893b453b2023cf4darylm if type(target) is type(''): 18483b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.showtopic(target, more_xrefs) 18493b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18503b553e0ab2146ef2055c969a1893b453b2023cf4darylm label, xrefs = target 18513b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 18523b553e0ab2146ef2055c969a1893b453b2023cf4darylm doc = pydoc_data.topics.topics[label] 18533b553e0ab2146ef2055c969a1893b453b2023cf4darylm except KeyError: 18543b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write('no documentation found for %s\n' % repr(topic)) 18553b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 18563b553e0ab2146ef2055c969a1893b453b2023cf4darylm pager(strip(doc) + '\n') 18573b553e0ab2146ef2055c969a1893b453b2023cf4darylm if more_xrefs: 18583b553e0ab2146ef2055c969a1893b453b2023cf4darylm xrefs = (xrefs or '') + ' ' + more_xrefs 18593b553e0ab2146ef2055c969a1893b453b2023cf4darylm if xrefs: 18603b553e0ab2146ef2055c969a1893b453b2023cf4darylm import StringIO, formatter 18613b553e0ab2146ef2055c969a1893b453b2023cf4darylm buffer = StringIO.StringIO() 18623b553e0ab2146ef2055c969a1893b453b2023cf4darylm formatter.DumbWriter(buffer).send_flowing_data( 18633b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Related help topics: ' + join(split(xrefs), ', ') + '\n') 18643b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write('\n%s\n' % buffer.getvalue()) 18653b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18663b553e0ab2146ef2055c969a1893b453b2023cf4darylm def showsymbol(self, symbol): 18673b553e0ab2146ef2055c969a1893b453b2023cf4darylm target = self.symbols[symbol] 18683b553e0ab2146ef2055c969a1893b453b2023cf4darylm topic, _, xrefs = target.partition(' ') 18693b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.showtopic(topic, xrefs) 18703b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18713b553e0ab2146ef2055c969a1893b453b2023cf4darylm def listmodules(self, key=''): 18723b553e0ab2146ef2055c969a1893b453b2023cf4darylm if key: 18733b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 18743b553e0ab2146ef2055c969a1893b453b2023cf4darylmHere is a list of matching modules. Enter any module name to get more help. 18753b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18763b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 18773b553e0ab2146ef2055c969a1893b453b2023cf4darylm apropos(key) 18783b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 18793b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 18803b553e0ab2146ef2055c969a1893b453b2023cf4darylmPlease wait a moment while I gather a list of all available modules... 18813b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18823b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 18833b553e0ab2146ef2055c969a1893b453b2023cf4darylm modules = {} 18843b553e0ab2146ef2055c969a1893b453b2023cf4darylm def callback(path, modname, desc, modules=modules): 18853b553e0ab2146ef2055c969a1893b453b2023cf4darylm if modname and modname[-9:] == '.__init__': 18863b553e0ab2146ef2055c969a1893b453b2023cf4darylm modname = modname[:-9] + ' (package)' 18873b553e0ab2146ef2055c969a1893b453b2023cf4darylm if find(modname, '.') < 0: 18883b553e0ab2146ef2055c969a1893b453b2023cf4darylm modules[modname] = 1 18893b553e0ab2146ef2055c969a1893b453b2023cf4darylm def onerror(modname): 18903b553e0ab2146ef2055c969a1893b453b2023cf4darylm callback(None, modname, None) 18913b553e0ab2146ef2055c969a1893b453b2023cf4darylm ModuleScanner().run(callback, onerror=onerror) 18923b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.list(modules.keys()) 18933b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.output.write(''' 18943b553e0ab2146ef2055c969a1893b453b2023cf4darylmEnter any module name to get more help. Or, type "modules spam" to search 18953b553e0ab2146ef2055c969a1893b453b2023cf4darylmfor modules whose descriptions contain the word "spam". 18963b553e0ab2146ef2055c969a1893b453b2023cf4darylm''') 18973b553e0ab2146ef2055c969a1893b453b2023cf4darylm 18983b553e0ab2146ef2055c969a1893b453b2023cf4darylmhelp = Helper() 18993b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19003b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass Scanner: 19013b553e0ab2146ef2055c969a1893b453b2023cf4darylm """A generic tree iterator.""" 19023b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self, roots, children, descendp): 19033b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.roots = roots[:] 19043b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.state = [] 19053b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.children = children 19063b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.descendp = descendp 19073b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19083b553e0ab2146ef2055c969a1893b453b2023cf4darylm def next(self): 19093b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not self.state: 19103b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not self.roots: 19113b553e0ab2146ef2055c969a1893b453b2023cf4darylm return None 19123b553e0ab2146ef2055c969a1893b453b2023cf4darylm root = self.roots.pop(0) 19133b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.state = [(root, self.children(root))] 19143b553e0ab2146ef2055c969a1893b453b2023cf4darylm node, children = self.state[-1] 19153b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not children: 19163b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.state.pop() 19173b553e0ab2146ef2055c969a1893b453b2023cf4darylm return self.next() 19183b553e0ab2146ef2055c969a1893b453b2023cf4darylm child = children.pop(0) 19193b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.descendp(child): 19203b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.state.append((child, self.children(child))) 19213b553e0ab2146ef2055c969a1893b453b2023cf4darylm return child 19223b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19233b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19243b553e0ab2146ef2055c969a1893b453b2023cf4darylmclass ModuleScanner: 19253b553e0ab2146ef2055c969a1893b453b2023cf4darylm """An interruptible scanner that searches module synopses.""" 19263b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19273b553e0ab2146ef2055c969a1893b453b2023cf4darylm def run(self, callback, key=None, completer=None, onerror=None): 19283b553e0ab2146ef2055c969a1893b453b2023cf4darylm if key: key = lower(key) 19293b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.quit = False 19303b553e0ab2146ef2055c969a1893b453b2023cf4darylm seen = {} 19313b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19323b553e0ab2146ef2055c969a1893b453b2023cf4darylm for modname in sys.builtin_module_names: 19333b553e0ab2146ef2055c969a1893b453b2023cf4darylm if modname != '__main__': 19343b553e0ab2146ef2055c969a1893b453b2023cf4darylm seen[modname] = 1 19353b553e0ab2146ef2055c969a1893b453b2023cf4darylm if key is None: 19363b553e0ab2146ef2055c969a1893b453b2023cf4darylm callback(None, modname, '') 19373b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 19383b553e0ab2146ef2055c969a1893b453b2023cf4darylm desc = split(__import__(modname).__doc__ or '', '\n')[0] 19393b553e0ab2146ef2055c969a1893b453b2023cf4darylm if find(lower(modname + ' - ' + desc), key) >= 0: 19403b553e0ab2146ef2055c969a1893b453b2023cf4darylm callback(None, modname, desc) 19413b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19423b553e0ab2146ef2055c969a1893b453b2023cf4darylm for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror): 19433b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.quit: 19443b553e0ab2146ef2055c969a1893b453b2023cf4darylm break 19453b553e0ab2146ef2055c969a1893b453b2023cf4darylm if key is None: 19463b553e0ab2146ef2055c969a1893b453b2023cf4darylm callback(None, modname, '') 19473b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 19483b553e0ab2146ef2055c969a1893b453b2023cf4darylm loader = importer.find_module(modname) 19493b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(loader,'get_source'): 19503b553e0ab2146ef2055c969a1893b453b2023cf4darylm import StringIO 19513b553e0ab2146ef2055c969a1893b453b2023cf4darylm desc = source_synopsis( 19523b553e0ab2146ef2055c969a1893b453b2023cf4darylm StringIO.StringIO(loader.get_source(modname)) 19533b553e0ab2146ef2055c969a1893b453b2023cf4darylm ) or '' 19543b553e0ab2146ef2055c969a1893b453b2023cf4darylm if hasattr(loader,'get_filename'): 19553b553e0ab2146ef2055c969a1893b453b2023cf4darylm path = loader.get_filename(modname) 19563b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 19573b553e0ab2146ef2055c969a1893b453b2023cf4darylm path = None 19583b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 19593b553e0ab2146ef2055c969a1893b453b2023cf4darylm module = loader.load_module(modname) 19603b553e0ab2146ef2055c969a1893b453b2023cf4darylm desc = (module.__doc__ or '').splitlines()[0] 19613b553e0ab2146ef2055c969a1893b453b2023cf4darylm path = getattr(module,'__file__',None) 19623b553e0ab2146ef2055c969a1893b453b2023cf4darylm if find(lower(modname + ' - ' + desc), key) >= 0: 19633b553e0ab2146ef2055c969a1893b453b2023cf4darylm callback(path, modname, desc) 19643b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19653b553e0ab2146ef2055c969a1893b453b2023cf4darylm if completer: 19663b553e0ab2146ef2055c969a1893b453b2023cf4darylm completer() 19673b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19683b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef apropos(key): 19693b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Print all the one-line module summaries that contain a substring.""" 19703b553e0ab2146ef2055c969a1893b453b2023cf4darylm def callback(path, modname, desc): 19713b553e0ab2146ef2055c969a1893b453b2023cf4darylm if modname[-9:] == '.__init__': 19723b553e0ab2146ef2055c969a1893b453b2023cf4darylm modname = modname[:-9] + ' (package)' 19733b553e0ab2146ef2055c969a1893b453b2023cf4darylm print modname, desc and '- ' + desc 19743b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: import warnings 19753b553e0ab2146ef2055c969a1893b453b2023cf4darylm except ImportError: pass 19763b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: warnings.filterwarnings('ignore') # ignore problems during import 19773b553e0ab2146ef2055c969a1893b453b2023cf4darylm ModuleScanner().run(callback, key) 19783b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19793b553e0ab2146ef2055c969a1893b453b2023cf4darylm# --------------------------------------------------- web browser interface 19803b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19813b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef serve(port, callback=None, completer=None): 19823b553e0ab2146ef2055c969a1893b453b2023cf4darylm import BaseHTTPServer, mimetools, select 19833b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19843b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded. 19853b553e0ab2146ef2055c969a1893b453b2023cf4darylm class Message(mimetools.Message): 19863b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self, fp, seekable=1): 19873b553e0ab2146ef2055c969a1893b453b2023cf4darylm Message = self.__class__ 19883b553e0ab2146ef2055c969a1893b453b2023cf4darylm Message.__bases__[0].__bases__[0].__init__(self, fp, seekable) 19893b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.encodingheader = self.getheader('content-transfer-encoding') 19903b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.typeheader = self.getheader('content-type') 19913b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.parsetype() 19923b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.parseplist() 19933b553e0ab2146ef2055c969a1893b453b2023cf4darylm 19943b553e0ab2146ef2055c969a1893b453b2023cf4darylm class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler): 19953b553e0ab2146ef2055c969a1893b453b2023cf4darylm def send_document(self, title, contents): 19963b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 19973b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.send_response(200) 19983b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.send_header('Content-Type', 'text/html') 19993b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.end_headers() 20003b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.wfile.write(html.page(title, contents)) 20013b553e0ab2146ef2055c969a1893b453b2023cf4darylm except IOError: pass 20023b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20033b553e0ab2146ef2055c969a1893b453b2023cf4darylm def do_GET(self): 20043b553e0ab2146ef2055c969a1893b453b2023cf4darylm path = self.path 20053b553e0ab2146ef2055c969a1893b453b2023cf4darylm if path[-5:] == '.html': path = path[:-5] 20063b553e0ab2146ef2055c969a1893b453b2023cf4darylm if path[:1] == '/': path = path[1:] 20073b553e0ab2146ef2055c969a1893b453b2023cf4darylm if path and path != '.': 20083b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 20093b553e0ab2146ef2055c969a1893b453b2023cf4darylm obj = locate(path, forceload=1) 20103b553e0ab2146ef2055c969a1893b453b2023cf4darylm except ErrorDuringImport, value: 20113b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.send_document(path, html.escape(str(value))) 20123b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 20133b553e0ab2146ef2055c969a1893b453b2023cf4darylm if obj: 20143b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.send_document(describe(obj), html.document(obj, path)) 20153b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 20163b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.send_document(path, 20173b553e0ab2146ef2055c969a1893b453b2023cf4darylm'no Python documentation found for %s' % repr(path)) 20183b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 20193b553e0ab2146ef2055c969a1893b453b2023cf4darylm heading = html.heading( 20203b553e0ab2146ef2055c969a1893b453b2023cf4darylm'<big><big><strong>Python: Index of Modules</strong></big></big>', 20213b553e0ab2146ef2055c969a1893b453b2023cf4darylm'#ffffff', '#7799ee') 20223b553e0ab2146ef2055c969a1893b453b2023cf4darylm def bltinlink(name): 20233b553e0ab2146ef2055c969a1893b453b2023cf4darylm return '<a href="%s.html">%s</a>' % (name, name) 20243b553e0ab2146ef2055c969a1893b453b2023cf4darylm names = filter(lambda x: x != '__main__', 20253b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.builtin_module_names) 20263b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = html.multicolumn(names, bltinlink) 20273b553e0ab2146ef2055c969a1893b453b2023cf4darylm indices = ['<p>' + html.bigsection( 20283b553e0ab2146ef2055c969a1893b453b2023cf4darylm 'Built-in Modules', '#ffffff', '#ee77aa', contents)] 20293b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20303b553e0ab2146ef2055c969a1893b453b2023cf4darylm seen = {} 20313b553e0ab2146ef2055c969a1893b453b2023cf4darylm for dir in sys.path: 20323b553e0ab2146ef2055c969a1893b453b2023cf4darylm indices.append(html.index(dir, seen)) 20333b553e0ab2146ef2055c969a1893b453b2023cf4darylm contents = heading + join(indices) + '''<p align=right> 20343b553e0ab2146ef2055c969a1893b453b2023cf4darylm<font color="#909090" face="helvetica, arial"><strong> 20353b553e0ab2146ef2055c969a1893b453b2023cf4darylmpydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>''' 20363b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.send_document('Index of Modules', contents) 20373b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20383b553e0ab2146ef2055c969a1893b453b2023cf4darylm def log_message(self, *args): pass 20393b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20403b553e0ab2146ef2055c969a1893b453b2023cf4darylm class DocServer(BaseHTTPServer.HTTPServer): 20413b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self, port, callback): 20423b553e0ab2146ef2055c969a1893b453b2023cf4darylm host = 'localhost' 20433b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.address = (host, port) 20443b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.url = 'http://%s:%d/' % (host, port) 20453b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.callback = callback 20463b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.base.__init__(self, self.address, self.handler) 20473b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20483b553e0ab2146ef2055c969a1893b453b2023cf4darylm def serve_until_quit(self): 20493b553e0ab2146ef2055c969a1893b453b2023cf4darylm import select 20503b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.quit = False 20513b553e0ab2146ef2055c969a1893b453b2023cf4darylm while not self.quit: 20523b553e0ab2146ef2055c969a1893b453b2023cf4darylm rd, wr, ex = select.select([self.socket.fileno()], [], [], 1) 20533b553e0ab2146ef2055c969a1893b453b2023cf4darylm if rd: self.handle_request() 20543b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20553b553e0ab2146ef2055c969a1893b453b2023cf4darylm def server_activate(self): 20563b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.base.server_activate(self) 20573b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.callback: self.callback(self) 20583b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20593b553e0ab2146ef2055c969a1893b453b2023cf4darylm DocServer.base = BaseHTTPServer.HTTPServer 20603b553e0ab2146ef2055c969a1893b453b2023cf4darylm DocServer.handler = DocHandler 20613b553e0ab2146ef2055c969a1893b453b2023cf4darylm DocHandler.MessageClass = Message 20623b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 20633b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 20643b553e0ab2146ef2055c969a1893b453b2023cf4darylm DocServer(port, callback).serve_until_quit() 20653b553e0ab2146ef2055c969a1893b453b2023cf4darylm except (KeyboardInterrupt, select.error): 20663b553e0ab2146ef2055c969a1893b453b2023cf4darylm pass 20673b553e0ab2146ef2055c969a1893b453b2023cf4darylm finally: 20683b553e0ab2146ef2055c969a1893b453b2023cf4darylm if completer: completer() 20693b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20703b553e0ab2146ef2055c969a1893b453b2023cf4darylm# ----------------------------------------------------- graphical interface 20713b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20723b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef gui(): 20733b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Graphical interface (starts web server and pops up a control window).""" 20743b553e0ab2146ef2055c969a1893b453b2023cf4darylm class GUI: 20753b553e0ab2146ef2055c969a1893b453b2023cf4darylm def __init__(self, window, port=7464): 20763b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window = window 20773b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.server = None 20783b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.scanner = None 20793b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20803b553e0ab2146ef2055c969a1893b453b2023cf4darylm import Tkinter 20813b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.server_frm = Tkinter.Frame(window) 20823b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.title_lbl = Tkinter.Label(self.server_frm, 20833b553e0ab2146ef2055c969a1893b453b2023cf4darylm text='Starting server...\n ') 20843b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.open_btn = Tkinter.Button(self.server_frm, 20853b553e0ab2146ef2055c969a1893b453b2023cf4darylm text='open browser', command=self.open, state='disabled') 20863b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.quit_btn = Tkinter.Button(self.server_frm, 20873b553e0ab2146ef2055c969a1893b453b2023cf4darylm text='quit serving', command=self.quit, state='disabled') 20883b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20893b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_frm = Tkinter.Frame(window) 20903b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_lbl = Tkinter.Label(self.search_frm, text='Search for') 20913b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_ent = Tkinter.Entry(self.search_frm) 20923b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_ent.bind('<Return>', self.search) 20933b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.stop_btn = Tkinter.Button(self.search_frm, 20943b553e0ab2146ef2055c969a1893b453b2023cf4darylm text='stop', pady=0, command=self.stop, state='disabled') 20953b553e0ab2146ef2055c969a1893b453b2023cf4darylm if sys.platform == 'win32': 20963b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Trying to hide and show this button crashes under Windows. 20973b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.stop_btn.pack(side='right') 20983b553e0ab2146ef2055c969a1893b453b2023cf4darylm 20993b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.title('pydoc') 21003b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.protocol('WM_DELETE_WINDOW', self.quit) 21013b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.title_lbl.pack(side='top', fill='x') 21023b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.open_btn.pack(side='left', fill='x', expand=1) 21033b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.quit_btn.pack(side='right', fill='x', expand=1) 21043b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.server_frm.pack(side='top', fill='x') 21053b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21063b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_lbl.pack(side='left') 21073b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_ent.pack(side='right', fill='x', expand=1) 21083b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_frm.pack(side='top', fill='x') 21093b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_ent.focus_set() 21103b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21113b553e0ab2146ef2055c969a1893b453b2023cf4darylm font = ('helvetica', sys.platform == 'win32' and 8 or 10) 21123b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst = Tkinter.Listbox(window, font=font, height=6) 21133b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.bind('<Button-1>', self.select) 21143b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.bind('<Double-Button-1>', self.goto) 21153b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_scr = Tkinter.Scrollbar(window, 21163b553e0ab2146ef2055c969a1893b453b2023cf4darylm orient='vertical', command=self.result_lst.yview) 21173b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.config(yscrollcommand=self.result_scr.set) 21183b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21193b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_frm = Tkinter.Frame(window) 21203b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.goto_btn = Tkinter.Button(self.result_frm, 21213b553e0ab2146ef2055c969a1893b453b2023cf4darylm text='go to selected', command=self.goto) 21223b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.hide_btn = Tkinter.Button(self.result_frm, 21233b553e0ab2146ef2055c969a1893b453b2023cf4darylm text='hide results', command=self.hide) 21243b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.goto_btn.pack(side='left', fill='x', expand=1) 21253b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.hide_btn.pack(side='right', fill='x', expand=1) 21263b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21273b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.update() 21283b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.minwidth = self.window.winfo_width() 21293b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.minheight = self.window.winfo_height() 21303b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.bigminheight = (self.server_frm.winfo_reqheight() + 21313b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_frm.winfo_reqheight() + 21323b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.winfo_reqheight() + 21333b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_frm.winfo_reqheight()) 21343b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.bigwidth, self.bigheight = self.minwidth, self.bigminheight 21353b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.expanded = 0 21363b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight)) 21373b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.wm_minsize(self.minwidth, self.minheight) 21383b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.tk.willdispatch() 21393b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21403b553e0ab2146ef2055c969a1893b453b2023cf4darylm import threading 21413b553e0ab2146ef2055c969a1893b453b2023cf4darylm threading.Thread( 21423b553e0ab2146ef2055c969a1893b453b2023cf4darylm target=serve, args=(port, self.ready, self.quit)).start() 21433b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21443b553e0ab2146ef2055c969a1893b453b2023cf4darylm def ready(self, server): 21453b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.server = server 21463b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.title_lbl.config( 21473b553e0ab2146ef2055c969a1893b453b2023cf4darylm text='Python documentation server at\n' + server.url) 21483b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.open_btn.config(state='normal') 21493b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.quit_btn.config(state='normal') 21503b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21513b553e0ab2146ef2055c969a1893b453b2023cf4darylm def open(self, event=None, url=None): 21523b553e0ab2146ef2055c969a1893b453b2023cf4darylm url = url or self.server.url 21533b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 21543b553e0ab2146ef2055c969a1893b453b2023cf4darylm import webbrowser 21553b553e0ab2146ef2055c969a1893b453b2023cf4darylm webbrowser.open(url) 21563b553e0ab2146ef2055c969a1893b453b2023cf4darylm except ImportError: # pre-webbrowser.py compatibility 21573b553e0ab2146ef2055c969a1893b453b2023cf4darylm if sys.platform == 'win32': 21583b553e0ab2146ef2055c969a1893b453b2023cf4darylm os.system('start "%s"' % url) 21593b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 21603b553e0ab2146ef2055c969a1893b453b2023cf4darylm rc = os.system('netscape -remote "openURL(%s)" &' % url) 21613b553e0ab2146ef2055c969a1893b453b2023cf4darylm if rc: os.system('netscape "%s" &' % url) 21623b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21633b553e0ab2146ef2055c969a1893b453b2023cf4darylm def quit(self, event=None): 21643b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.server: 21653b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.server.quit = 1 21663b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.quit() 21673b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21683b553e0ab2146ef2055c969a1893b453b2023cf4darylm def search(self, event=None): 21693b553e0ab2146ef2055c969a1893b453b2023cf4darylm key = self.search_ent.get() 21703b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.stop_btn.pack(side='right') 21713b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.stop_btn.config(state='normal') 21723b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_lbl.config(text='Searching for "%s"...' % key) 21733b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_ent.forget() 21743b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_lbl.pack(side='left') 21753b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.delete(0, 'end') 21763b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.goto_btn.config(state='disabled') 21773b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.expand() 21783b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21793b553e0ab2146ef2055c969a1893b453b2023cf4darylm import threading 21803b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.scanner: 21813b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.scanner.quit = 1 21823b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.scanner = ModuleScanner() 21833b553e0ab2146ef2055c969a1893b453b2023cf4darylm threading.Thread(target=self.scanner.run, 21843b553e0ab2146ef2055c969a1893b453b2023cf4darylm args=(self.update, key, self.done)).start() 21853b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21863b553e0ab2146ef2055c969a1893b453b2023cf4darylm def update(self, path, modname, desc): 21873b553e0ab2146ef2055c969a1893b453b2023cf4darylm if modname[-9:] == '.__init__': 21883b553e0ab2146ef2055c969a1893b453b2023cf4darylm modname = modname[:-9] + ' (package)' 21893b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.insert('end', 21903b553e0ab2146ef2055c969a1893b453b2023cf4darylm modname + ' - ' + (desc or '(no description)')) 21913b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21923b553e0ab2146ef2055c969a1893b453b2023cf4darylm def stop(self, event=None): 21933b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.scanner: 21943b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.scanner.quit = 1 21953b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.scanner = None 21963b553e0ab2146ef2055c969a1893b453b2023cf4darylm 21973b553e0ab2146ef2055c969a1893b453b2023cf4darylm def done(self): 21983b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.scanner = None 21993b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_lbl.config(text='Search for') 22003b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_lbl.pack(side='left') 22013b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.search_ent.pack(side='right', fill='x', expand=1) 22023b553e0ab2146ef2055c969a1893b453b2023cf4darylm if sys.platform != 'win32': self.stop_btn.forget() 22033b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.stop_btn.config(state='disabled') 22043b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22053b553e0ab2146ef2055c969a1893b453b2023cf4darylm def select(self, event=None): 22063b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.goto_btn.config(state='normal') 22073b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22083b553e0ab2146ef2055c969a1893b453b2023cf4darylm def goto(self, event=None): 22093b553e0ab2146ef2055c969a1893b453b2023cf4darylm selection = self.result_lst.curselection() 22103b553e0ab2146ef2055c969a1893b453b2023cf4darylm if selection: 22113b553e0ab2146ef2055c969a1893b453b2023cf4darylm modname = split(self.result_lst.get(selection[0]))[0] 22123b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.open(url=self.server.url + modname + '.html') 22133b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22143b553e0ab2146ef2055c969a1893b453b2023cf4darylm def collapse(self): 22153b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not self.expanded: return 22163b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_frm.forget() 22173b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_scr.forget() 22183b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.forget() 22193b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.bigwidth = self.window.winfo_width() 22203b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.bigheight = self.window.winfo_height() 22213b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight)) 22223b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.wm_minsize(self.minwidth, self.minheight) 22233b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.expanded = 0 22243b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22253b553e0ab2146ef2055c969a1893b453b2023cf4darylm def expand(self): 22263b553e0ab2146ef2055c969a1893b453b2023cf4darylm if self.expanded: return 22273b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_frm.pack(side='bottom', fill='x') 22283b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_scr.pack(side='right', fill='y') 22293b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.result_lst.pack(side='top', fill='both', expand=1) 22303b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight)) 22313b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.window.wm_minsize(self.minwidth, self.bigminheight) 22323b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.expanded = 1 22333b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22343b553e0ab2146ef2055c969a1893b453b2023cf4darylm def hide(self, event=None): 22353b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.stop() 22363b553e0ab2146ef2055c969a1893b453b2023cf4darylm self.collapse() 22373b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22383b553e0ab2146ef2055c969a1893b453b2023cf4darylm import Tkinter 22393b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 22403b553e0ab2146ef2055c969a1893b453b2023cf4darylm root = Tkinter.Tk() 22413b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Tk will crash if pythonw.exe has an XP .manifest 22423b553e0ab2146ef2055c969a1893b453b2023cf4darylm # file and the root has is not destroyed explicitly. 22433b553e0ab2146ef2055c969a1893b453b2023cf4darylm # If the problem is ever fixed in Tk, the explicit 22443b553e0ab2146ef2055c969a1893b453b2023cf4darylm # destroy can go. 22453b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 22463b553e0ab2146ef2055c969a1893b453b2023cf4darylm gui = GUI(root) 22473b553e0ab2146ef2055c969a1893b453b2023cf4darylm root.mainloop() 22483b553e0ab2146ef2055c969a1893b453b2023cf4darylm finally: 22493b553e0ab2146ef2055c969a1893b453b2023cf4darylm root.destroy() 22503b553e0ab2146ef2055c969a1893b453b2023cf4darylm except KeyboardInterrupt: 22513b553e0ab2146ef2055c969a1893b453b2023cf4darylm pass 22523b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22533b553e0ab2146ef2055c969a1893b453b2023cf4darylm# -------------------------------------------------- command-line interface 22543b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22553b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef ispath(x): 22563b553e0ab2146ef2055c969a1893b453b2023cf4darylm return isinstance(x, str) and find(x, os.sep) >= 0 22573b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22583b553e0ab2146ef2055c969a1893b453b2023cf4darylmdef cli(): 22593b553e0ab2146ef2055c969a1893b453b2023cf4darylm """Command-line interface (looks at sys.argv to decide what to do).""" 22603b553e0ab2146ef2055c969a1893b453b2023cf4darylm import getopt 22613b553e0ab2146ef2055c969a1893b453b2023cf4darylm class BadUsage: pass 22623b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22633b553e0ab2146ef2055c969a1893b453b2023cf4darylm # Scripts don't get the current directory in their path by default 22643b553e0ab2146ef2055c969a1893b453b2023cf4darylm # unless they are run with the '-m' switch 22653b553e0ab2146ef2055c969a1893b453b2023cf4darylm if '' not in sys.path: 22663b553e0ab2146ef2055c969a1893b453b2023cf4darylm scriptdir = os.path.dirname(sys.argv[0]) 22673b553e0ab2146ef2055c969a1893b453b2023cf4darylm if scriptdir in sys.path: 22683b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.path.remove(scriptdir) 22693b553e0ab2146ef2055c969a1893b453b2023cf4darylm sys.path.insert(0, '.') 22703b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22713b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 22723b553e0ab2146ef2055c969a1893b453b2023cf4darylm opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w') 22733b553e0ab2146ef2055c969a1893b453b2023cf4darylm writing = 0 22743b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22753b553e0ab2146ef2055c969a1893b453b2023cf4darylm for opt, val in opts: 22763b553e0ab2146ef2055c969a1893b453b2023cf4darylm if opt == '-g': 22773b553e0ab2146ef2055c969a1893b453b2023cf4darylm gui() 22783b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 22793b553e0ab2146ef2055c969a1893b453b2023cf4darylm if opt == '-k': 22803b553e0ab2146ef2055c969a1893b453b2023cf4darylm apropos(val) 22813b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 22823b553e0ab2146ef2055c969a1893b453b2023cf4darylm if opt == '-p': 22833b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 22843b553e0ab2146ef2055c969a1893b453b2023cf4darylm port = int(val) 22853b553e0ab2146ef2055c969a1893b453b2023cf4darylm except ValueError: 22863b553e0ab2146ef2055c969a1893b453b2023cf4darylm raise BadUsage 22873b553e0ab2146ef2055c969a1893b453b2023cf4darylm def ready(server): 22883b553e0ab2146ef2055c969a1893b453b2023cf4darylm print 'pydoc server ready at %s' % server.url 22893b553e0ab2146ef2055c969a1893b453b2023cf4darylm def stopped(): 22903b553e0ab2146ef2055c969a1893b453b2023cf4darylm print 'pydoc server stopped' 22913b553e0ab2146ef2055c969a1893b453b2023cf4darylm serve(port, ready, stopped) 22923b553e0ab2146ef2055c969a1893b453b2023cf4darylm return 22933b553e0ab2146ef2055c969a1893b453b2023cf4darylm if opt == '-w': 22943b553e0ab2146ef2055c969a1893b453b2023cf4darylm writing = 1 22953b553e0ab2146ef2055c969a1893b453b2023cf4darylm 22963b553e0ab2146ef2055c969a1893b453b2023cf4darylm if not args: raise BadUsage 22973b553e0ab2146ef2055c969a1893b453b2023cf4darylm for arg in args: 22983b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ispath(arg) and not os.path.exists(arg): 22993b553e0ab2146ef2055c969a1893b453b2023cf4darylm print 'file %r does not exist' % arg 23003b553e0ab2146ef2055c969a1893b453b2023cf4darylm break 23013b553e0ab2146ef2055c969a1893b453b2023cf4darylm try: 23023b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ispath(arg) and os.path.isfile(arg): 23033b553e0ab2146ef2055c969a1893b453b2023cf4darylm arg = importfile(arg) 23043b553e0ab2146ef2055c969a1893b453b2023cf4darylm if writing: 23053b553e0ab2146ef2055c969a1893b453b2023cf4darylm if ispath(arg) and os.path.isdir(arg): 23063b553e0ab2146ef2055c969a1893b453b2023cf4darylm writedocs(arg) 23073b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 23083b553e0ab2146ef2055c969a1893b453b2023cf4darylm writedoc(arg) 23093b553e0ab2146ef2055c969a1893b453b2023cf4darylm else: 23103b553e0ab2146ef2055c969a1893b453b2023cf4darylm help.help(arg) 23113b553e0ab2146ef2055c969a1893b453b2023cf4darylm except ErrorDuringImport, value: 23123b553e0ab2146ef2055c969a1893b453b2023cf4darylm print value 23133b553e0ab2146ef2055c969a1893b453b2023cf4darylm 23143b553e0ab2146ef2055c969a1893b453b2023cf4darylm except (getopt.error, BadUsage): 23153b553e0ab2146ef2055c969a1893b453b2023cf4darylm cmd = os.path.basename(sys.argv[0]) 23163b553e0ab2146ef2055c969a1893b453b2023cf4darylm print """pydoc - the Python documentation tool 23173b553e0ab2146ef2055c969a1893b453b2023cf4darylm 23183b553e0ab2146ef2055c969a1893b453b2023cf4darylm%s <name> ... 23193b553e0ab2146ef2055c969a1893b453b2023cf4darylm Show text documentation on something. <name> may be the name of a 23203b553e0ab2146ef2055c969a1893b453b2023cf4darylm Python keyword, topic, function, module, or package, or a dotted 23213b553e0ab2146ef2055c969a1893b453b2023cf4darylm reference to a class or function within a module or module in a 23223b553e0ab2146ef2055c969a1893b453b2023cf4darylm package. If <name> contains a '%s', it is used as the path to a 23233b553e0ab2146ef2055c969a1893b453b2023cf4darylm Python source file to document. If name is 'keywords', 'topics', 23243b553e0ab2146ef2055c969a1893b453b2023cf4darylm or 'modules', a listing of these things is displayed. 23253b553e0ab2146ef2055c969a1893b453b2023cf4darylm 23263b553e0ab2146ef2055c969a1893b453b2023cf4darylm%s -k <keyword> 23273b553e0ab2146ef2055c969a1893b453b2023cf4darylm Search for a keyword in the synopsis lines of all available modules. 23283b553e0ab2146ef2055c969a1893b453b2023cf4darylm 23293b553e0ab2146ef2055c969a1893b453b2023cf4darylm%s -p <port> 23303b553e0ab2146ef2055c969a1893b453b2023cf4darylm Start an HTTP server on the given port on the local machine. 23313b553e0ab2146ef2055c969a1893b453b2023cf4darylm 23323b553e0ab2146ef2055c969a1893b453b2023cf4darylm%s -g 23333b553e0ab2146ef2055c969a1893b453b2023cf4darylm Pop up a graphical interface for finding and serving documentation. 23343b553e0ab2146ef2055c969a1893b453b2023cf4darylm 23353b553e0ab2146ef2055c969a1893b453b2023cf4darylm%s -w <name> ... 23363b553e0ab2146ef2055c969a1893b453b2023cf4darylm Write out the HTML documentation for a module to a file in the current 23373b553e0ab2146ef2055c969a1893b453b2023cf4darylm directory. If <name> contains a '%s', it is treated as a filename; if 23383b553e0ab2146ef2055c969a1893b453b2023cf4darylm it names a directory, documentation is written for all the contents. 23393b553e0ab2146ef2055c969a1893b453b2023cf4darylm""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep) 23403b553e0ab2146ef2055c969a1893b453b2023cf4darylm 23413b553e0ab2146ef2055c969a1893b453b2023cf4darylmif __name__ == '__main__': cli() 2342