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