2 """Generate Python documentation in HTML or text for interactive use.
4 In the Python interpreter, do "from pydoc import help" to provide online
5 help. Calling help(thing) on a Python object documents the object.
7 Or, at the shell command line outside of Python:
9 Run "pydoc <name>" to show documentation on something. <name> may be
10 the name of a function, module, package, or a dotted reference to a
11 class or function within a module or module in a package. If the
12 argument contains a path segment delimiter (e.g. slash on Unix,
13 backslash on Windows) it is treated as the path to a Python source file.
15 Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines
16 of all available modules.
18 Run "pydoc -p <port>" to start an HTTP server on a given port on the
19 local machine to generate documentation web pages.
21 For platforms without a command line, "pydoc -g" starts the HTTP server
22 and also pops up a little window for controlling it.
24 Run "pydoc -w <name>" to write out the HTML documentation for a module
25 to a file named "<name>.html".
28 __author__ =
"Ka-Ping Yee <ping@lfw.org>"
29 __date__ =
"26 February 2001"
30 __version__ =
"$Revision: 5816 $"
31 __credits__ =
"""Guido van Rossum, for an excellent programming language.
32 Tommy Burnette, the original creator of manpy.
33 Paul Prescod, for all his work on onlinehelp.
34 Richard Chamberlain, for the first implementation of textdoc.
36 Mynd you, møøse bites Kan be pretty nasti..."""
46 import sys, imp, os, stat, re, types, inspect
48 from string
import expandtabs, find, join, lower, split, strip, rfind, rstrip
53 """Convert sys.path into a list of absolute, existing, unique paths."""
57 dir = os.path.abspath(dir
or '.')
58 normdir = os.path.normcase(dir)
59 if normdir
not in normdirs
and os.path.isdir(dir):
61 normdirs.append(normdir)
65 """Get the doc string or comments for an object."""
67 return result
and re.sub(
'^ *\n',
'',
rstrip(result))
or ''
70 """Split a doc string into a synopsis line (if any) and the rest."""
74 elif len(lines) >= 2
and not rstrip(lines[1]):
75 return lines[0],
join(lines[2:],
'\n')
76 return '',
join(lines,
'\n')
79 """Get a class name and qualify it with a module name if necessary."""
80 name = object.__name__
81 if object.__module__ != modname:
82 name = object.__module__ +
'.' + name
86 """Check if an object is of a type that probably means it's data."""
92 """Do a series of global replacements on a string."""
94 text =
join(
split(text, pairs[0]), pairs[1])
99 """Omit part of a string if needed to make it fit in a maximum length."""
100 if len(text) > maxlen:
101 pre =
max(0, (maxlen-3)/2)
102 post =
max(0, maxlen-3-pre)
103 return text[:pre] +
'...' + text[len(text)-post:]
107 """Remove the hexadecimal id from a Python object representation."""
109 for pattern
in [
' at 0x[0-9a-f]{6,}>$',
' at [0-9A-F]{8,}>$']:
110 if re.search(pattern,
repr(Exception)):
111 return re.sub(pattern,
'>', text)
114 def _is_some_method(object):
121 for base
in cl.__bases__:
123 for key
in methods.keys():
124 methods[key] = getattr(cl, key)
127 def _split_list(s, predicate):
128 """Split sequence s via predicate, and return pair ([true], [false]).
130 The return value is a 2-tuple of lists,
131 ([x for x in s if predicate(x)],
132 [x for x in s if not predicate(x)])
147 """Guess whether a path refers to a package directory."""
148 if os.path.isdir(path):
149 for ext
in [
'.py',
'.pyc',
'.pyo']:
150 if os.path.isfile(os.path.join(path,
'__init__' + ext)):
154 """Get the one-line summary out of a module file."""
155 mtime = os.stat(filename)[stat.ST_MTIME]
156 lastupdate, result = cache.get(filename, (0,
None))
157 if lastupdate < mtime:
159 file =
open(filename)
160 if info
and 'b' in info[2]:
161 try: module = imp.load_module(
'__temp__', file, filename, info[1:])
163 result =
split(module.__doc__
or '',
'\n')[0]
164 del sys.modules[
'__temp__']
166 line = file.readline()
167 while line[:1] ==
'#' or not strip(line):
168 line = file.readline()
171 if line[:4] ==
'r"""': line = line[1:]
172 if line[:3] ==
'"""':
174 if line[-1:] ==
'\\': line = line[:-1]
175 while not strip(line):
176 line = file.readline()
181 cache[filename] = (mtime, result)
185 """Errors that occurred while trying to import something to document it."""
194 if type(exc)
is types.ClassType:
196 return 'problem in %s - %s: %s' % (self.
filename, exc, self.
value)
199 """Import a Python source file or compiled file given its path."""
200 magic = imp.get_magic()
201 file =
open(path,
'r')
202 if file.read(len(magic)) == magic:
203 kind = imp.PY_COMPILED
207 filename = os.path.basename(path)
208 name, ext = os.path.splitext(filename)
209 file =
open(path,
'r')
211 module = imp.load_module(name, file, path, (ext,
'r', kind))
218 """Import a module; handle errors; return None if the module isn't found.
220 If the module *is* found but an exception occurs, it's wrapped in an
221 ErrorDuringImport exception and reraised. Unlike __import__, if a
222 package path is specified, the module at the end of the path is returned,
223 not the package at the beginning. If the optional 'forceload' argument
224 is 1, we reload the module from disk (unless it's a dynamic extension)."""
225 if forceload
and sys.modules.has_key(path):
229 if path
not in sys.builtin_module_names:
235 if info[3] != imp.C_EXTENSION:
236 cache[path] = sys.modules[path]
237 del sys.modules[path]
239 module = __import__(path)
242 (exc, value, tb) = info = sys.exc_info()
243 if sys.modules.has_key(path):
246 elif exc
is SyntaxError:
249 elif exc
is ImportError
and \
256 for part
in split(path,
'.')[1:]:
257 try: module = getattr(module, part)
258 except AttributeError:
return None
265 """Generate documentation for an object."""
266 args = (object, name) + args
270 return apply(self.docother, args)
272 def fail(self, object, name=None, *args):
273 """Raise an exception for unimplemented types."""
274 message =
"don't know how to document object%s of type %s" % (
275 name
and ' ' +
repr(name), type(object).__name__)
276 raise TypeError, message
278 docmodule = docclass = docroutine = docother = fail
283 """Class for safely making an HTML representation of a Python object."""
291 return replace(text,
'&',
'&',
'<',
'<',
'>',
'>')
294 return Repr.repr(self, object)
297 methodname =
'repr_' +
join(
split(type(x).__name__),
'_')
298 if hasattr(self, methodname):
299 return getattr(self, methodname)(x, level)
305 testrepr =
repr(test)
306 if '\\' in test
and '\\' not in replace(testrepr,
r'\\',
''):
309 return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
310 return re.sub(
r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
311 r'<font color="#c040c0">\1</font>',
314 repr_str = repr_string
320 return self.
escape(
'<%s instance>' % x.__class__.__name__)
322 repr_unicode = repr_string
325 """Formatter class for HTML documentation."""
330 repr = _repr_instance.repr
331 escape = _repr_instance.escape
333 def page(self, title, contents):
334 """Format an HTML page."""
336 <!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
337 <html><head><title>Python: %s</title>
338 <style type="text/css"><!--
339 TT { font-family: lucidatypewriter, lucida console, courier }
340 --></style></head><body bgcolor="#f0f0f8">
342 </body></html>''' % (title, contents)
344 def heading(self, title, fgcol, bgcol, extras=''):
345 """Format a page heading."""
347 <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
349 <td valign=bottom> <br>
350 <font color="%s" face="helvetica, arial"> <br>%s</font></td
351 ><td align=right valign=bottom
352 ><font color="%s" face="helvetica, arial">%s</font></td></tr></table>
353 ''' % (bgcol, fgcol, title, fgcol, extras
or ' ')
355 def section(self, title, fgcol, bgcol, contents, width=10,
356 prelude=
'', marginalia=
None, gap=
' '):
357 """Format a section with a heading."""
358 if marginalia
is None:
359 marginalia =
'<tt>' +
' ' * width +
'</tt>'
361 <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
363 <td colspan=3 valign=bottom> <br>
364 <font color="%s" face="helvetica, arial">%s</font></td></tr>
365 ''' % (bgcol, fgcol, title)
367 result = result +
'''
368 <tr bgcolor="%s"><td rowspan=2>%s</td>
369 <td colspan=2>%s</td></tr>
370 <tr><td>%s</td>''' % (bgcol, marginalia, prelude, gap)
372 result = result +
'''
373 <tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol, marginalia, gap)
375 return result +
'\n<td width="100%%">%s</td></tr></table>' % contents
378 """Format a section with a big heading."""
379 title =
'<big><strong>%s</strong></big>' % title
380 return apply(self.
section, (title,) + args)
383 """Format literal preformatted text."""
385 return replace(text,
'\n\n',
'\n \n',
'\n\n',
'\n \n',
386 ' ',
' ',
'\n',
'<br>\n')
389 """Format a list of items into a multi-column list."""
391 rows = (len(list)+cols-1)/cols
392 for col
in range(cols):
393 result = result +
'<td width="%d%%" valign=top>' % (100/cols)
394 for i
in range(rows*col, rows*col+rows):
396 result = result +
format(list[i]) +
'<br>\n'
397 result = result +
'</td>'
398 return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
400 def grey(self, text):
return '<font color="#909090">%s</font>' % text
403 """Make a link for an identifier, given name-to-URL mappings."""
405 if dict.has_key(name):
406 return '<a href="%s">%s</a>' % (dict[name], name)
410 """Make a link for a class."""
411 name, module = object.__name__, sys.modules.get(object.__module__)
412 if hasattr(module, name)
and getattr(module, name)
is object:
413 return '<a href="%s.html#%s">%s</a>' % (
414 module.__name__, name,
classname(object, modname))
418 """Make a link for a module."""
419 return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__)
422 """Make a link for a module or package to display in an index."""
424 return self.
grey(name)
426 url =
'%s.%s.html' % (path, name)
428 url =
'%s.html' % name
430 text =
'<strong>%s</strong> (package)' % name
433 return '<a href="%s">%s</a>' % (url, text)
435 def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
436 """Mark up some plain text, given a context of symbols to look for.
437 Each context dictionary maps object names to anchor names."""
438 escape = escape
or self.
escape
441 pattern = re.compile(
r'\b((http|ftp)://\S+[\w/]|'
446 match = pattern.search(text, here)
448 start, end = match.span()
449 results.append(
escape(text[here:start]))
451 all, scheme, rfc, pep, selfdot, name = match.groups()
454 results.append(
'<a href="%s">%s</a>' % (url, url))
456 url =
'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
457 results.append(
'<a href="%s">%s</a>' % (url,
escape(all)))
459 url =
'http://www.python.org/peps/pep-%04d.html' % int(pep)
460 results.append(
'<a href="%s">%s</a>' % (url,
escape(all)))
461 elif text[end:end+1] ==
'(':
462 results.append(self.
namelink(name, methods, funcs, classes))
464 results.append(
'self.<strong>%s</strong>' % name)
466 results.append(self.
namelink(name, classes))
468 results.append(
escape(text[here:]))
469 return join(results,
'')
474 """Produce HTML for a class tree as given by inspect.getclasstree()."""
477 if type(entry)
is type(()):
479 result = result +
'<dt><font face="helvetica, arial">'
480 result = result + self.
classlink(c, modname)
481 if bases
and bases != (parent,):
484 parents.append(self.
classlink(base, modname))
485 result = result +
'(' +
join(parents,
', ') +
')'
486 result = result +
'\n</font></dt>'
487 elif type(entry)
is type([]):
488 result = result +
'<dd>\n%s</dd>\n' % self.
formattree(
490 return '<dl>\n%s</dl>\n' % result
492 def docmodule(self, object, name=None, mod=None, *ignored):
493 """Produce HTML documentation for a module object."""
494 name = object.__name__
495 parts =
split(name,
'.')
497 for i
in range(len(parts)-1):
499 '<a href="%s.html"><font color="#ffffff">%s</font></a>' %
500 (
join(parts[:i+1],
'.'), parts[i]))
501 linkedname =
join(links + parts[-1:],
'.')
502 head =
'<big><big><strong>%s</strong></big></big>' % linkedname
506 if sys.platform ==
'win32':
509 filelink =
'<a href="file:%s">%s</a>' % (url, path)
511 filelink =
'(built-in)'
513 if hasattr(object,
'__version__'):
514 version =
str(object.__version__)
515 if version[:11] ==
'$' +
'Revision: ' and version[-1:] ==
'$':
516 version =
strip(version[11:-1])
517 info.append(
'version %s' % self.
escape(version))
518 if hasattr(object,
'__date__'):
519 info.append(self.
escape(
str(object.__date__)))
521 head = head +
' (%s)' %
join(info,
', ')
523 head,
'#ffffff',
'#7799ee',
'<a href=".">index</a><br>' + filelink)
527 classes, cdict = [], {}
530 classes.append((key, value))
531 cdict[key] = cdict[value] =
'#' + key
532 for key, value
in classes:
533 for base
in value.__bases__:
534 key, modname = base.__name__, base.__module__
535 module = sys.modules.get(modname)
536 if modname != name
and module
and hasattr(module, key):
537 if getattr(module, key)
is base:
538 if not cdict.has_key(key):
539 cdict[key] = cdict[base] = modname +
'.html#' + key
540 funcs, fdict = [], {}
543 funcs.append((key, value))
544 fdict[key] =
'#-' + key
548 if key
not in [
'__builtins__',
'__doc__']:
549 data.append((key, value))
552 doc = doc
and '<tt>%s</tt>' % doc
553 result = result +
'<p>%s</p>\n' % doc
555 if hasattr(object,
'__path__'):
558 for file
in os.listdir(object.__path__[0]):
559 path = os.path.join(object.__path__[0], file)
561 if modname
and modname
not in modnames:
562 modpkgs.append((modname, name, 0, 0))
563 modnames.append(modname)
565 modpkgs.append((file, name, 1, 0))
569 'Package Contents',
'#ffffff',
'#aa55cc', contents)
572 modules,
lambda (key, value), s=self: s.modulelink(value))
574 'Modules',
'#fffff',
'#aa55cc', contents)
577 classlist = map(
lambda (key, value): value, classes)
580 for key, value
in classes:
581 contents.append(self.
document(value, key, name, fdict, cdict))
583 'Classes',
'#ffffff',
'#ee77aa',
join(contents))
586 for key, value
in funcs:
587 contents.append(self.
document(value, key, name, fdict, cdict))
589 'Functions',
'#ffffff',
'#eeaa77',
join(contents))
592 for key, value
in data:
593 contents.append(self.
document(value, key))
595 'Data',
'#ffffff',
'#55aa55',
join(contents,
'<br>\n'))
596 if hasattr(object,
'__author__'):
599 'Author',
'#ffffff',
'#7799ee', contents)
600 if hasattr(object,
'__credits__'):
603 'Credits',
'#ffffff',
'#7799ee', contents)
607 def docclass(self, object, name=None, mod=None, funcs={}, classes={},
609 """Produce HTML documentation for a class object."""
610 realname = object.__name__
611 name = name
or realname
612 bases = object.__bases__
615 push = contents.append
618 class HorizontalRule:
625 hr = HorizontalRule()
631 push(
'<dl><dt>Method resolution order:</dt>\n')
633 push(
'<dd>%s</dd>\n' % self.
classlink(base,
637 def spill(msg, attrs, predicate):
638 ok, attrs = _split_list(attrs, predicate)
642 for name, kind, homecls, value
in ok:
643 push(self.
document(getattr(object, name), name, mod,
644 funcs, classes, mdict, object))
648 def spillproperties(msg, attrs, predicate):
649 ok, attrs = _split_list(attrs, predicate)
653 for name, kind, homecls, value
in ok:
654 push(
'<dl><dt><strong>%s</strong></dt>\n' % name)
655 if value.__doc__
is not None:
657 funcs, classes, mdict)
658 push(
'<dd><tt>%s</tt></dd>\n' % doc)
659 for attr, tag
in [(
"fget",
" getter"),
661 (
"fdel",
" deleter")]:
662 func = getattr(value, attr)
664 base = self.
document(func, name + tag, mod,
665 funcs, classes, mdict, object)
666 push(
'<dd>%s</dd>\n' % base)
670 def spilldata(msg, attrs, predicate):
671 ok, attrs = _split_list(attrs, predicate)
675 for name, kind, homecls, value
in ok:
676 base = self.
docother(getattr(object, name), name, mod)
677 doc = getattr(value,
"__doc__",
None)
679 push(
'<dl><dt>%s</dl>\n' % base)
682 funcs, classes, mdict)
683 doc =
'<dd><tt>%s</tt>' % doc
684 push(
'<dl><dt>%s%s</dl>\n' % (base, doc))
690 for key, kind, homecls, value
in attrs:
691 mdict[key] = anchor =
'#' + name +
'-' + key
692 value = getattr(object, key)
696 mdict[value] = anchor
702 thisclass = mro.pop(0)
704 thisclass = attrs[0][2]
705 attrs, inherited = _split_list(attrs,
lambda t: t[2]
is thisclass)
707 if thisclass
is object:
710 tag =
"inherited from %s" % self.
classlink(thisclass,
715 attrs.sort(
lambda t1, t2:
cmp(t1[0], t2[0]))
718 attrs = spill(
"Methods %s" % tag, attrs,
719 lambda t: t[1] ==
'method')
720 attrs = spill(
"Class methods %s" % tag, attrs,
721 lambda t: t[1] ==
'class method')
722 attrs = spill(
"Static methods %s" % tag, attrs,
723 lambda t: t[1] ==
'static method')
724 attrs = spillproperties(
"Properties %s" % tag, attrs,
725 lambda t: t[1] ==
'property')
726 attrs = spilldata(
"Data and non-method functions %s" % tag, attrs,
727 lambda t: t[1] ==
'data')
731 contents =
''.
join(contents)
734 title =
'<a name="%s">class <strong>%s</strong></a>' % (
737 title =
'<strong>%s</strong> = <a name="%s">class %s</a>' % (
738 name, name, realname)
742 parents.append(self.
classlink(base, object.__module__))
743 title = title +
'(%s)' %
join(parents,
', ')
745 doc = doc
and '<tt>%s<br> </tt>' % doc
or ' '
747 return self.
section(title,
'#000000',
'#ffc8d8', contents, 5, doc)
750 """Format an argument default value as text."""
751 return self.
grey(
'=' + self.
repr(object))
753 def docroutine(self, object, name=None, mod=None,
754 funcs={}, classes={}, methods={}, cl=
None):
755 """Produce HTML documentation for a function or method object."""
756 realname = object.__name__
757 name = name
or realname
758 anchor = (cl
and cl.__name__
or '') +
'-' + name
762 imclass = object.im_class
764 if imclass
is not cl:
765 note =
' from ' + self.
classlink(imclass, mod)
768 note =
' method of %s instance' % self.
classlink(
769 object.im_self.__class__, mod)
771 note =
' unbound %s method' % self.
classlink(imclass,mod)
772 object = object.im_func
775 title =
'<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
777 if (cl
and cl.__dict__.has_key(realname)
and
778 cl.__dict__[realname]
is object):
779 reallink =
'<a href="#%s">%s</a>' % (
780 cl.__name__ +
'-' + realname, realname)
784 title =
'<a name="%s"><strong>%s</strong></a> = %s' % (
785 anchor, name, reallink)
789 args, varargs, varkw, defaults, formatvalue=self.
formatvalue)
790 if realname ==
'<lambda>':
791 title =
'<strong>%s</strong> <em>lambda</em> ' % name
792 argspec = argspec[1:-1]
796 decl = title + argspec + (note
and self.
grey(
797 '<font face="helvetica, arial">%s</font>' % note))
800 return '<dl><dt>%s</dt></dl>\n' % decl
804 doc = doc
and '<dd><tt>%s</tt></dd>' % doc
805 return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
807 def docother(self, object, name=None, mod=None, *ignored):
808 """Produce HTML documentation for a data object."""
809 lhs = name
and '<strong>%s</strong> = ' % name
or ''
810 return lhs + self.
repr(object)
812 def index(self, dir, shadowed=None):
813 """Generate an HTML index for a directory of modules."""
815 if shadowed
is None: shadowed = {}
817 files = os.listdir(dir)
819 def found(name, ispackage,
820 modpkgs=modpkgs, shadowed=shadowed, seen=seen):
821 if not seen.has_key(name):
822 modpkgs.append((name,
'', ispackage, shadowed.has_key(name)))
828 path = os.path.join(dir, file)
831 path = os.path.join(dir, file)
832 if os.path.isfile(path):
834 if modname: found(modname, 0)
838 return self.
bigsection(dir,
'#ffffff',
'#ee77aa', contents)
843 """Class for safely making a text representation of a Python object."""
851 methodname =
'repr_' +
join(
split(type(x).__name__),
'_')
852 if hasattr(self, methodname):
853 return getattr(self, methodname)(x, level)
859 testrepr =
repr(test)
860 if '\\' in test
and '\\' not in replace(testrepr,
r'\\',
''):
863 return 'r' + testrepr[0] + test + testrepr[0]
866 repr_str = repr_string
872 return '<%s instance>' % x.__class__.__name__
875 """Formatter class for text documentation."""
880 repr = _repr_instance.repr
883 """Format a string in bold by overstriking."""
884 return join(map(
lambda ch: ch +
'\b' + ch, text),
'')
887 """Indent text by prepending a given prefix to each line."""
888 if not text:
return ''
889 lines =
split(text,
'\n')
890 lines = map(
lambda line, prefix=prefix: prefix + line, lines)
891 if lines: lines[-1] =
rstrip(lines[-1])
892 return join(lines,
'\n')
895 """Format a section with a given heading."""
901 """Render in text a class tree as returned by inspect.getclasstree()."""
904 if type(entry)
is type(()):
906 result = result + prefix +
classname(c, modname)
907 if bases
and bases != (parent,):
908 parents = map(
lambda c, m=modname:
classname(c, m), bases)
909 result = result +
'(%s)' %
join(parents,
', ')
910 result = result +
'\n'
911 elif type(entry)
is type([]):
913 entry, modname, c, prefix +
' ')
917 """Produce text documentation for a given module object."""
918 name = object.__name__
920 result = self.
section(
'NAME', name + (synop
and ' - ' + synop))
926 result = result + self.
section(
'FILE', file)
928 result = result + self.
section(
'DESCRIPTION', desc)
933 classes.append((key, value))
937 funcs.append((key, value))
940 if key
not in [
'__builtins__',
'__doc__']:
941 data.append((key, value))
943 if hasattr(object,
'__path__'):
945 for file
in os.listdir(object.__path__[0]):
946 path = os.path.join(object.__path__[0], file)
948 if modname
and modname
not in modpkgs:
949 modpkgs.append(modname)
951 modpkgs.append(file +
' (package)')
953 result = result + self.
section(
954 'PACKAGE CONTENTS',
join(modpkgs,
'\n'))
957 classlist = map(
lambda (key, value): value, classes)
960 for key, value
in classes:
961 contents.append(self.
document(value, key, name))
962 result = result + self.
section(
'CLASSES',
join(contents,
'\n'))
966 for key, value
in funcs:
967 contents.append(self.
document(value, key, name))
968 result = result + self.
section(
'FUNCTIONS',
join(contents,
'\n'))
972 for key, value
in data:
973 contents.append(self.
docother(value, key, name, 70))
974 result = result + self.
section(
'DATA',
join(contents,
'\n'))
976 if hasattr(object,
'__version__'):
977 version =
str(object.__version__)
978 if version[:11] ==
'$' +
'Revision: ' and version[-1:] ==
'$':
979 version =
strip(version[11:-1])
980 result = result + self.
section(
'VERSION', version)
981 if hasattr(object,
'__date__'):
982 result = result + self.
section(
'DATE',
str(object.__date__))
983 if hasattr(object,
'__author__'):
984 result = result + self.
section(
'AUTHOR',
str(object.__author__))
985 if hasattr(object,
'__credits__'):
986 result = result + self.
section(
'CREDITS',
str(object.__credits__))
990 """Produce text documentation for a given class object."""
991 realname = object.__name__
992 name = name
or realname
993 bases = object.__bases__
995 def makename(c, m=object.__module__):
999 title =
'class ' + self.
bold(realname)
1001 title = self.
bold(name) +
' = class ' + realname
1003 parents = map(makename, bases)
1004 title = title +
'(%s)' %
join(parents,
', ')
1007 contents = doc
and [doc +
'\n']
or []
1008 push = contents.append
1013 push(
"Method resolution order:")
1015 push(
' ' + makename(base))
1019 class HorizontalRule:
1026 hr = HorizontalRule()
1028 def spill(msg, attrs, predicate):
1029 ok, attrs = _split_list(attrs, predicate)
1033 for name, kind, homecls, value
in ok:
1034 push(self.
document(getattr(object, name),
1038 def spillproperties(msg, attrs, predicate):
1039 ok, attrs = _split_list(attrs, predicate)
1043 for name, kind, homecls, value
in ok:
1045 need_blank_after_doc = 0
1046 doc =
getdoc(value)
or ''
1049 need_blank_after_doc = 1
1050 for attr, tag
in [(
"fget",
" getter"),
1051 (
"fset",
" setter"),
1052 (
"fdel",
" deleter")]:
1053 func = getattr(value, attr)
1054 if func
is not None:
1055 if need_blank_after_doc:
1057 need_blank_after_doc = 0
1058 base = self.
docother(func, name + tag, mod, 70)
1063 def spilldata(msg, attrs, predicate):
1064 ok, attrs = _split_list(attrs, predicate)
1068 for name, kind, homecls, value
in ok:
1069 doc = getattr(value,
"__doc__",
None)
1070 push(self.
docother(getattr(object, name),
1071 name, mod, 70, doc) +
'\n')
1077 thisclass = mro.pop(0)
1079 thisclass = attrs[0][2]
1080 attrs, inherited = _split_list(attrs,
lambda t: t[2]
is thisclass)
1082 if thisclass
is object:
1083 tag =
"defined here"
1085 tag =
"inherited from %s" %
classname(thisclass,
1089 attrs.sort(
lambda t1, t2:
cmp(t1[0], t2[0]))
1092 attrs = spill(
"Methods %s:\n" % tag, attrs,
1093 lambda t: t[1] ==
'method')
1094 attrs = spill(
"Class methods %s:\n" % tag, attrs,
1095 lambda t: t[1] ==
'class method')
1096 attrs = spill(
"Static methods %s:\n" % tag, attrs,
1097 lambda t: t[1] ==
'static method')
1098 attrs = spillproperties(
"Properties %s:\n" % tag, attrs,
1099 lambda t: t[1] ==
'property')
1100 attrs = spilldata(
"Data and non-method functions %s:\n" % tag,
1101 attrs,
lambda t: t[1] ==
'data')
1105 contents =
'\n'.
join(contents)
1108 return title +
'\n' + self.
indent(
rstrip(contents),
' | ') +
'\n'
1111 """Format an argument default value as text."""
1112 return '=' + self.
repr(object)
1115 """Produce text documentation for a function or method object."""
1116 realname = object.__name__
1117 name = name
or realname
1121 imclass = object.im_class
1123 if imclass
is not cl:
1124 note =
' from ' +
classname(imclass, mod)
1127 note =
' method of %s instance' %
classname(
1128 object.im_self.__class__, mod)
1130 note =
' unbound %s method' %
classname(imclass,mod)
1131 object = object.im_func
1133 if name == realname:
1134 title = self.
bold(realname)
1136 if (cl
and cl.__dict__.has_key(realname)
and
1137 cl.__dict__[realname]
is object):
1139 title = self.
bold(name) +
' = ' + realname
1143 args, varargs, varkw, defaults, formatvalue=self.
formatvalue)
1144 if realname ==
'<lambda>':
1146 argspec = argspec[1:-1]
1149 decl = title + argspec + note
1154 doc =
getdoc(object)
or ''
1155 return decl +
'\n' + (doc
and rstrip(self.
indent(doc)) +
'\n')
1157 def docother(self, object, name=None, mod=None, maxlen=None, doc=None):
1158 """Produce text documentation for a data object."""
1159 repr = self.
repr(object)
1161 line = (name
and name +
' = ' or '') + repr
1162 chop = maxlen - len(line)
1163 if chop < 0: repr = repr[:chop] +
'...'
1164 line = (name
and self.
bold(name) +
' = ' or '') + repr
1172 """The first time this is called, determine what kind of pager to use."""
1178 """Decide what method to use for paging through text."""
1179 if type(sys.stdout)
is not types.FileType:
1181 if not sys.stdin.isatty()
or not sys.stdout.isatty():
1183 if os.environ.get(
'TERM')
in [
'dumb',
'emacs']:
1185 if os.environ.has_key(
'PAGER'):
1186 if sys.platform ==
'win32':
1188 elif os.environ.get(
'TERM')
in [
'dumb',
'emacs']:
1191 return lambda text:
pipepager(text, os.environ[
'PAGER'])
1192 if sys.platform ==
'win32':
1194 if hasattr(os,
'system')
and os.system(
'less 2>/dev/null') == 0:
1195 return lambda text:
pipepager(text,
'less')
1201 if hasattr(os,
'system')
and os.system(
'more %s' % filename) == 0:
1202 return lambda text:
pipepager(text,
'more')
1209 """Remove boldface formatting from text."""
1210 return re.sub(
'.\b',
'', text)
1213 """Page through text by feeding it to another program."""
1214 pipe = os.popen(cmd,
'w')
1222 """Page through text by invoking a program on a temporary file."""
1225 file =
open(filename,
'w')
1229 os.system(cmd +
' ' + filename)
1234 """Page through text on a text terminal."""
1238 fd = sys.stdin.fileno()
1239 old = tty.tcgetattr(fd)
1241 getchar =
lambda: sys.stdin.read(1)
1242 except (ImportError, AttributeError):
1244 getchar =
lambda: sys.stdin.readline()[:-1][:1]
1247 r = inc = os.environ.get(
'LINES', 25) - 1
1248 sys.stdout.write(
join(lines[:inc],
'\n') +
'\n')
1250 sys.stdout.write(
'-- more --')
1255 sys.stdout.write(
'\r \r')
1257 elif c
in [
'\r',
'\n']:
1258 sys.stdout.write(
'\r \r' + lines[r] +
'\n')
1261 if c
in [
'b',
'B',
'\x1b']:
1264 sys.stdout.write(
'\n' +
join(lines[r:r+inc],
'\n') +
'\n')
1269 tty.tcsetattr(fd, tty.TCSAFLUSH, old)
1272 """Simply print unformatted text. This is the ultimate fallback."""
1273 sys.stdout.write(
plain(text))
1276 """Produce a short description of the given thing."""
1278 if thing.__name__
in sys.builtin_module_names:
1279 return 'built-in module ' + thing.__name__
1280 if hasattr(thing,
'__path__'):
1281 return 'package ' + thing.__name__
1283 return 'module ' + thing.__name__
1285 return 'built-in function ' + thing.__name__
1287 return 'class ' + thing.__name__
1289 return 'function ' + thing.__name__
1291 return 'method ' + thing.__name__
1292 if type(thing)
is types.InstanceType:
1293 return 'instance of ' + thing.__class__.__name__
1294 return type(thing).__name__
1297 """Locate an object by name or dotted path, importing as necessary."""
1298 parts =
split(path,
'.')
1300 while n < len(parts):
1302 if nextmodule: module, n = nextmodule, n + 1
1306 for part
in parts[n:]:
1307 try: object = getattr(object, part)
1308 except AttributeError:
return None
1312 if hasattr(__builtin__, path):
1313 return getattr(__builtin__, path)
1320 def doc(thing, title='Python Library Documentation: %s
', forceload=0):
1321 """Display text documentation, given an object or a path to an object."""
1322 suffix, name =
'',
None
1323 if type(thing)
is type(
''):
1325 object =
locate(thing, forceload)
1326 except ErrorDuringImport, value:
1330 print 'no Python documentation found for %s' %
repr(thing)
1332 parts =
split(thing,
'.')
1333 if len(parts) > 1: suffix =
' in ' +
join(parts[:-1],
'.')
1339 if not suffix
and module
and module
is not thing:
1340 suffix =
' in module ' + module.__name__
1341 pager(title % (desc + suffix) +
'\n\n' + text.document(thing, name))
1344 """Write HTML documentation to a file in the current directory."""
1346 object =
locate(key, forceload)
1347 except ErrorDuringImport, value:
1352 html.document(object, object.__name__))
1353 file =
open(key +
'.html',
'w')
1356 print 'wrote', key +
'.html'
1358 print 'no Python documentation found for %s' %
repr(key)
1361 """Write out HTML documentation for all modules in a directory tree."""
1362 if done
is None: done = {}
1363 for file
in os.listdir(dir):
1364 path = os.path.join(dir, file)
1366 writedocs(path, pkgpath + file +
'.', done)
1367 elif os.path.isfile(path):
1370 modname = pkgpath + modname
1371 if not done.has_key(modname):
1378 'assert': (
'ref/assert',
''),
1379 'break': (
'ref/break',
'while for'),
1380 'class': (
'ref/class',
'CLASSES SPECIALMETHODS'),
1381 'continue': (
'ref/continue',
'while for'),
1382 'def': (
'ref/function',
''),
1383 'del': (
'ref/del',
'BASICMETHODS'),
1385 'else': (
'ref/if',
'while for'),
1387 'exec': (
'ref/exec',
''),
1389 'for': (
'ref/for',
'break continue while'),
1391 'global': (
'ref/global',
'NAMESPACES'),
1392 'if': (
'ref/if',
'TRUTHVALUE'),
1393 'import': (
'ref/import',
'MODULES'),
1394 'in': (
'ref/comparisons',
'SEQUENCEMETHODS2'),
1396 'lambda': (
'ref/lambda',
'FUNCTIONS'),
1400 'print': (
'ref/print',
''),
1401 'raise': (
'ref/raise',
'EXCEPTIONS'),
1402 'return': (
'ref/return',
'FUNCTIONS'),
1403 'try': (
'ref/try',
'EXCEPTIONS'),
1404 'while': (
'ref/while',
'break continue if TRUTHVALUE'),
1408 'TYPES': (
'ref/types',
'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS FUNCTIONS CLASSES MODULES FILES inspect'),
1409 'STRINGS': (
'ref/strings',
'str UNICODE SEQUENCES STRINGMETHODS FORMATTING TYPES'),
1410 'STRINGMETHODS': (
'lib/string-methods',
'STRINGS FORMATTING'),
1411 'FORMATTING': (
'lib/typesseq-strings',
'OPERATORS'),
1412 'UNICODE': (
'ref/unicode',
'encodings unicode TYPES STRING'),
1413 'NUMBERS': (
'ref/numbers',
'INTEGER FLOAT COMPLEX TYPES'),
1414 'INTEGER': (
'ref/integers',
'int range'),
1415 'FLOAT': (
'ref/floating',
'float math'),
1416 'COMPLEX': (
'ref/imaginary',
'complex cmath'),
1417 'SEQUENCES': (
'lib/typesseq',
'STRINGMETHODS FORMATTING xrange LISTS'),
1418 'MAPPINGS':
'DICTIONARIES',
1419 'FUNCTIONS': (
'lib/typesfunctions',
'def TYPES'),
1420 'METHODS': (
'lib/typesmethods',
'class def CLASSES TYPES'),
1421 'CODEOBJECTS': (
'lib/bltin-code-objects',
'compile FUNCTIONS TYPES'),
1422 'TYPEOBJECTS': (
'lib/bltin-type-objects',
'types TYPES'),
1423 'FRAMEOBJECTS':
'TYPES',
1424 'TRACEBACKS':
'TYPES',
1425 'NONE': (
'lib/bltin-null-object',
''),
1426 'ELLIPSIS': (
'lib/bltin-ellipsis-object',
'SLICINGS'),
1427 'FILES': (
'lib/bltin-file-objects',
''),
1428 'SPECIALATTRIBUTES': (
'lib/specialattrs',
''),
1429 'CLASSES': (
'ref/types',
'class SPECIALMETHODS PRIVATENAMES'),
1430 'MODULES': (
'lib/typesmodules',
'import'),
1431 'PACKAGES':
'import',
1432 'EXPRESSIONS': (
'ref/summary',
'lambda or and not in is BOOLEAN COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES LISTS DICTIONARIES BACKQUOTES'),
1433 'OPERATORS':
'EXPRESSIONS',
1434 'PRECEDENCE':
'EXPRESSIONS',
1435 'OBJECTS': (
'ref/objects',
'TYPES'),
1436 'SPECIALMETHODS': (
'ref/specialnames',
'BASICMETHODS ATTRIBUTEMETHODS CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
1437 'BASICMETHODS': (
'ref/customization',
'cmp hash repr str SPECIALMETHODS'),
1438 'ATTRIBUTEMETHODS': (
'ref/attribute-access',
'ATTRIBUTES SPECIALMETHODS'),
1439 'CALLABLEMETHODS': (
'ref/callable-types',
'CALLS SPECIALMETHODS'),
1440 'SEQUENCEMETHODS1': (
'ref/sequence-types',
'SEQUENCES SEQUENCEMETHODS2 SPECIALMETHODS'),
1441 'SEQUENCEMETHODS2': (
'ref/sequence-methods',
'SEQUENCES SEQUENCEMETHODS1 SPECIALMETHODS'),
1442 'MAPPINGMETHODS': (
'ref/sequence-types',
'MAPPINGS SPECIALMETHODS'),
1443 'NUMBERMETHODS': (
'ref/numeric-types',
'NUMBERS AUGMENTEDASSIGNMENT SPECIALMETHODS'),
1444 'EXECUTION': (
'ref/execframes',
''),
1445 'NAMESPACES': (
'ref/execframes',
'global ASSIGNMENT DELETION'),
1446 'SCOPING':
'NAMESPACES',
1447 'FRAMES':
'NAMESPACES',
1448 'EXCEPTIONS': (
'ref/exceptions',
'try except finally raise'),
1449 'COERCIONS':
'CONVERSIONS',
1450 'CONVERSIONS': (
'ref/conversions',
''),
1451 'IDENTIFIERS': (
'ref/identifiers',
'keywords SPECIALIDENTIFIERS'),
1452 'SPECIALIDENTIFIERS': (
'ref/id-classes',
''),
1453 'PRIVATENAMES': (
'ref/atom-identifiers',
''),
1454 'LITERALS': (
'ref/atom-literals',
'STRINGS BACKQUOTES NUMBERS TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'),
1455 'TUPLES':
'SEQUENCES',
1456 'TUPLELITERALS': (
'ref/exprlists',
'TUPLES LITERALS'),
1457 'LISTS': (
'lib/typesseq-mutable',
'LISTLITERALS'),
1458 'LISTLITERALS': (
'ref/lists',
'LISTS LITERALS'),
1459 'DICTIONARIES': (
'lib/typesmapping',
'DICTIONARYLITERALS'),
1460 'DICTIONARYLITERALS': (
'ref/dict',
'DICTIONARIES LITERALS'),
1461 'BACKQUOTES': (
'ref/string-conversions',
'repr str STRINGS LITERALS'),
1462 'ATTRIBUTES': (
'ref/attribute-references',
'getattr hasattr setattr ATTRIBUTEMETHODS'),
1463 'SUBSCRIPTS': (
'ref/subscriptions',
'SEQUENCEMETHODS1'),
1464 'SLICINGS': (
'ref/slicings',
'SEQUENCEMETHODS2'),
1465 'CALLS': (
'ref/calls',
'EXPRESSIONS'),
1466 'POWER': (
'ref/power',
'EXPRESSIONS'),
1467 'UNARY': (
'ref/unary',
'EXPRESSIONS'),
1468 'BINARY': (
'ref/binary',
'EXPRESSIONS'),
1469 'SHIFTING': (
'ref/shifting',
'EXPRESSIONS'),
1470 'BITWISE': (
'ref/bitwise',
'EXPRESSIONS'),
1471 'COMPARISON': (
'ref/comparisons',
'EXPRESSIONS BASICMETHODS'),
1472 'BOOLEAN': (
'ref/lambda',
'EXPRESSIONS TRUTHVALUE'),
1473 'ASSERTION':
'assert',
1474 'ASSIGNMENT': (
'ref/assignment',
'AUGMENTEDASSIGNMENT'),
1475 'AUGMENTEDASSIGNMENT': (
'ref/augassign',
'NUMBERMETHODS'),
1477 'PRINTING':
'print',
1478 'RETURNING':
'return',
1479 'IMPORTING':
'import',
1480 'CONDITIONAL':
'if',
1481 'LOOPING': (
'ref/compound',
'for while break continue'),
1482 'TRUTHVALUE': (
'lib/truth',
'if while and or not BASICMETHODS'),
1483 'DEBUGGING': (
'lib/module-pdb',
'pdb'),
1490 execdir = os.path.dirname(sys.executable)
1491 homedir = os.environ.get(
'PYTHONHOME')
1492 for dir
in [os.environ.get(
'PYTHONDOCS'),
1493 homedir
and os.path.join(homedir,
'doc'),
1494 os.path.join(execdir,
'doc'),
1495 '/usr/doc/python-docs-' +
split(sys.version)[0],
1496 '/usr/doc/python-' +
split(sys.version)[0],
1497 '/usr/doc/python-docs-' + sys.version[:3],
1498 '/usr/doc/python-' + sys.version[:3]]:
1499 if dir
and os.path.isdir(os.path.join(dir,
'lib')):
1506 return '<pydoc.Helper instance>'
1509 if request
is not None:
1514 self.output.write(
'''
1515 You are now leaving help and returning to the Python interpreter.
1516 If you want to ask for help on a particular object directly from the
1517 interpreter, you can type "help(object)". Executing "help('string')"
1518 has the same effect as typing a particular string at the help> prompt.
1522 self.output.write(
'\n')
1524 self.output.write(
'help> ')
1527 request = self.input.readline()
1528 if not request:
break
1529 except KeyboardInterrupt:
break
1531 if lower(request)
in [
'q',
'quit']:
break
1535 if type(request)
is type(
''):
1536 if request ==
'help': self.
intro()
1540 elif request[:8] ==
'modules ':
1542 elif self.keywords.has_key(request): self.
showtopic(request)
1543 elif self.topics.has_key(request): self.
showtopic(request)
1544 elif request:
doc(request,
'Help on %s:')
1545 elif isinstance(request, Helper): self()
1546 else:
doc(request,
'Help on %s:')
1547 self.output.write(
'\n')
1550 self.output.write(
'''
1551 Welcome to Python %s! This is the online help utility.
1553 If this is your first time using Python, you should definitely check out
1554 the tutorial on the Internet at http://www.python.org/doc/tut/.
1556 Enter the name of any module, keyword, or topic to get help on writing
1557 Python programs and using Python modules. To quit this help utility and
1558 return to the interpreter, just type "quit".
1560 To get a list of available modules, keywords, or topics, type "modules",
1561 "keywords", or "topics". Each module also comes with a one-line summary
1562 of what it does; to list the modules whose summaries contain a given word
1563 such as "spam", type "modules spam".
1564 ''' % sys.version[:3])
1566 def list(self, items, columns=4, width=80):
1569 colw = width / columns
1570 rows = (len(items) + columns - 1) / columns
1571 for row
in range(rows):
1572 for col
in range(columns):
1573 i = col * rows + row
1575 self.output.write(items[i])
1576 if col < columns - 1:
1577 self.output.write(
' ' +
' ' * (colw-1 - len(items[i])))
1578 self.output.write(
'\n')
1581 self.output.write(
'''
1582 Here is a list of the Python keywords. Enter any keyword to get more help.
1585 self.
list(self.keywords.keys())
1588 self.output.write(
'''
1589 Here is a list of available topics. Enter any topic name to get more help.
1592 self.
list(self.topics.keys())
1596 self.output.write(
'''
1597 Sorry, topic and keyword documentation is not available because the Python
1598 HTML documentation files could not be found. If you have installed them,
1599 please set the environment variable PYTHONDOCS to indicate their location.
1602 target = self.topics.get(topic, self.keywords.get(topic))
1604 self.output.write(
'no documentation found for %s\n' %
repr(topic))
1606 if type(target)
is type(
''):
1609 filename, xrefs = target
1610 filename = self.
docdir +
'/' + filename +
'.html'
1612 file =
open(filename)
1614 self.output.write(
'could not read docs from %s\n' % filename)
1617 divpat = re.compile(
'<div[^>]*navigat.*?</div.*?>', re.I | re.S)
1618 addrpat = re.compile(
'<address.*?>.*?</address.*?>', re.I | re.S)
1619 document = re.sub(addrpat,
'', re.sub(divpat,
'', file.read()))
1622 import htmllib, formatter, StringIO
1626 parser.start_table = parser.do_p
1627 parser.end_table =
lambda parser=parser: parser.do_p({})
1628 parser.start_tr = parser.do_br
1629 parser.start_td = parser.start_th =
lambda a, b=buffer: b.write(
'\t')
1630 parser.feed(document)
1631 buffer =
replace(buffer.getvalue(),
'\xa0',
' ',
'\n',
'\n ')
1636 'Related help topics: ' +
join(
split(xrefs),
', ') +
'\n')
1637 self.output.write(
'\n%s\n' % buffer.getvalue())
1641 self.output.write(
'''
1642 Here is a list of matching modules. Enter any module name to get more help.
1647 self.output.write(
'''
1648 Please wait a moment while I gather a list of all available modules...
1652 def callback(path, modname, desc, modules=modules):
1653 if modname
and modname[-9:] ==
'.__init__':
1654 modname = modname[:-9] +
' (package)'
1655 if find(modname,
'.') < 0:
1656 modules[modname] = 1
1658 self.
list(modules.keys())
1659 self.output.write(
'''
1660 Enter any module name to get more help. Or, type "modules spam" to search
1661 for modules whose descriptions contain the word "spam".
1667 """A generic tree iterator."""
1678 root = self.roots.pop(0)
1680 node, children = self.
state[-1]
1684 child = children.pop(0)
1686 self.state.append((child, self.
children(child)))
1690 """An interruptible scanner that searches module synopses."""
1692 roots = map(
lambda dir: (dir,
''),
pathdirs())
1694 self.
inodes = map(
lambda (dir, pkg): os.stat(dir)[1], roots)
1698 for file
in os.listdir(dir):
1699 path = os.path.join(dir, file)
1701 children.append((path, package + (package
and '.') + file))
1703 children.append((path, package))
1708 inode = os.path.exists(dir)
and os.stat(dir)[1]
1709 if not (os.path.islink(dir)
and inode
in self.
inodes):
1710 self.inodes.append(inode)
1713 def run(self, callback, key=None, completer=None):
1714 if key: key =
lower(key)
1718 for modname
in sys.builtin_module_names:
1719 if modname !=
'__main__':
1724 desc =
split(__import__(modname).__doc__
or '',
'\n')[0]
1725 if find(
lower(modname +
' - ' + desc), key) >= 0:
1728 while not self.
quit:
1731 path, package = node
1733 if os.path.isfile(path)
and modname:
1734 modname = package + (package
and '.') + modname
1735 if not seen.has_key(modname):
1741 if find(
lower(modname +
' - ' + desc), key) >= 0:
1743 if completer: completer()
1746 """Print all the one-line module summaries that contain a substring."""
1748 if modname[-9:] ==
'.__init__':
1749 modname = modname[:-9] +
' (package)'
1750 print modname, desc
and '- ' + desc
1751 try:
import warnings
1752 except ImportError:
pass
1758 def serve(port, callback=None, completer=None):
1759 import BaseHTTPServer, mimetools, select
1763 def __init__(self, fp, seekable=1):
1764 Message = self.__class__
1765 Message.__bases__[0].__bases__[0].
__init__(self, fp, seekable)
1766 self.encodingheader = self.getheader(
'content-transfer-encoding')
1767 self.typeheader = self.getheader(
'content-type')
1772 def send_document(self, title, contents):
1774 self.send_response(200)
1775 self.send_header(
'Content-Type',
'text/html')
1777 self.wfile.write(html.page(title, contents))
1778 except IOError:
pass
1782 if path[-5:] ==
'.html': path = path[:-5]
1783 if path[:1] ==
'/': path = path[1:]
1784 if path
and path !=
'.':
1786 obj =
locate(path, forceload=1)
1787 except ErrorDuringImport, value:
1788 self.send_document(path, html.escape(
str(value)))
1791 self.send_document(
describe(obj), html.document(obj, path))
1793 self.send_document(path,
1794 'no Python documentation found for %s' %
repr(path))
1796 heading = html.heading(
1797 '<big><big><strong>Python: Index of Modules</strong></big></big>',
1798 '#ffffff',
'#7799ee')
1799 def bltinlink(name):
1800 return '<a href="%s.html">%s</a>' % (name, name)
1801 names =
filter(
lambda x: x !=
'__main__',
1802 sys.builtin_module_names)
1803 contents = html.multicolumn(names, bltinlink)
1804 indices = [
'<p>' + html.bigsection(
1805 'Built-in Modules',
'#ffffff',
'#ee77aa', contents)]
1809 indices.append(html.index(dir, seen))
1810 contents = heading +
join(indices) +
'''<p align=right>
1811 <font color="#909090" face="helvetica, arial"><strong>
1812 pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''
1813 self.send_document(
'Index of Modules', contents)
1815 def log_message(self, *args):
pass
1818 def __init__(self, port, callback):
1819 host = (sys.platform ==
'mac')
and '127.0.0.1' or 'localhost'
1820 self.address = (
'', port)
1821 self.url =
'http://%s:%d/' % (host, port)
1822 self.callback = callback
1823 self.base.__init__(self, self.address, self.handler)
1825 def serve_until_quit(self):
1828 while not self.quit:
1829 rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)
1830 if rd: self.handle_request()
1832 def server_activate(self):
1833 self.base.server_activate(self)
1834 if self.callback: self.callback(self)
1837 DocServer.handler = DocHandler
1838 DocHandler.MessageClass = Message
1841 DocServer(port, callback).serve_until_quit()
1842 except (KeyboardInterrupt, select.error):
1845 if completer: completer()
1850 """Graphical interface (starts web server and pops up a control window)."""
1852 def __init__(self, window, port=7464):
1853 self.window = window
1858 self.server_frm = Tkinter.Frame(window)
1859 self.title_lbl = Tkinter.Label(self.server_frm,
1860 text=
'Starting server...\n ')
1861 self.open_btn = Tkinter.Button(self.server_frm,
1862 text=
'open browser', command=self.open, state=
'disabled')
1863 self.quit_btn = Tkinter.Button(self.server_frm,
1864 text=
'quit serving', command=self.quit, state=
'disabled')
1866 self.search_frm = Tkinter.Frame(window)
1867 self.search_lbl = Tkinter.Label(self.search_frm, text=
'Search for')
1868 self.search_ent = Tkinter.Entry(self.search_frm)
1869 self.search_ent.bind(
'<Return>', self.search)
1870 self.stop_btn = Tkinter.Button(self.search_frm,
1871 text=
'stop', pady=0, command=self.stop, state=
'disabled')
1872 if sys.platform ==
'win32':
1874 self.stop_btn.pack(side=
'right')
1876 self.window.title(
'pydoc')
1877 self.window.protocol(
'WM_DELETE_WINDOW', self.quit)
1878 self.title_lbl.pack(side=
'top', fill=
'x')
1879 self.open_btn.pack(side=
'left', fill=
'x', expand=1)
1880 self.quit_btn.pack(side=
'right', fill=
'x', expand=1)
1881 self.server_frm.pack(side=
'top', fill=
'x')
1883 self.search_lbl.pack(side=
'left')
1884 self.search_ent.pack(side=
'right', fill=
'x', expand=1)
1885 self.search_frm.pack(side=
'top', fill=
'x')
1886 self.search_ent.focus_set()
1888 font = (
'helvetica', sys.platform ==
'win32' and 8
or 10)
1889 self.result_lst = Tkinter.Listbox(window, font=font, height=6)
1890 self.result_lst.bind(
'<Button-1>', self.select)
1891 self.result_lst.bind(
'<Double-Button-1>', self.goto)
1892 self.result_scr = Tkinter.Scrollbar(window,
1893 orient=
'vertical', command=self.result_lst.yview)
1894 self.result_lst.config(yscrollcommand=self.result_scr.set)
1896 self.result_frm = Tkinter.Frame(window)
1897 self.goto_btn = Tkinter.Button(self.result_frm,
1898 text=
'go to selected', command=self.goto)
1899 self.hide_btn = Tkinter.Button(self.result_frm,
1900 text=
'hide results', command=self.hide)
1901 self.goto_btn.pack(side=
'left', fill=
'x', expand=1)
1902 self.hide_btn.pack(side=
'right', fill=
'x', expand=1)
1904 self.window.update()
1905 self.minwidth = self.window.winfo_width()
1906 self.minheight = self.window.winfo_height()
1907 self.bigminheight = (self.server_frm.winfo_reqheight() +
1908 self.search_frm.winfo_reqheight() +
1909 self.result_lst.winfo_reqheight() +
1910 self.result_frm.winfo_reqheight())
1911 self.bigwidth, self.bigheight = self.minwidth, self.bigminheight
1913 self.window.wm_geometry(
'%dx%d' % (self.minwidth, self.minheight))
1914 self.window.wm_minsize(self.minwidth, self.minheight)
1918 target=serve, args=(port, self.ready, self.quit)).
start()
1920 def ready(self, server):
1921 self.server = server
1922 self.title_lbl.config(
1923 text=
'Python documentation server at\n' + server.url)
1924 self.open_btn.config(state=
'normal')
1925 self.quit_btn.config(state=
'normal')
1927 def open(self, event=None, url=None):
1928 url = url
or self.server.url
1933 if sys.platform ==
'win32':
1934 os.system(
'start "%s"' % url)
1935 elif sys.platform ==
'mac':
1937 except ImportError:
pass
1938 else: ic.launchurl(url)
1940 rc = os.system(
'netscape -remote "openURL(%s)" &' % url)
1941 if rc: os.system(
'netscape "%s" &' % url)
1943 def quit(self, event=None):
1945 self.server.quit = 1
1948 def search(self, event=None):
1949 key = self.search_ent.get()
1950 self.stop_btn.pack(side=
'right')
1951 self.stop_btn.config(state=
'normal')
1952 self.search_lbl.config(text=
'Searching for "%s"...' % key)
1953 self.search_ent.forget()
1954 self.search_lbl.pack(side=
'left')
1955 self.result_lst.delete(0,
'end')
1956 self.goto_btn.config(state=
'disabled')
1961 self.scanner.quit = 1
1964 args=(self.update, key, self.done)).
start()
1966 def update(self, path, modname, desc):
1967 if modname[-9:] ==
'.__init__':
1968 modname = modname[:-9] +
' (package)'
1969 self.result_lst.insert(
'end',
1970 modname +
' - ' + (desc
or '(no description)'))
1972 def stop(self, event=None):
1974 self.scanner.quit = 1
1979 self.search_lbl.config(text=
'Search for')
1980 self.search_lbl.pack(side=
'left')
1981 self.search_ent.pack(side=
'right', fill=
'x', expand=1)
1982 if sys.platform !=
'win32': self.stop_btn.forget()
1983 self.stop_btn.config(state=
'disabled')
1985 def select(self, event=None):
1986 self.goto_btn.config(state=
'normal')
1988 def goto(self, event=None):
1989 selection = self.result_lst.curselection()
1991 modname =
split(self.result_lst.get(selection[0]))[0]
1992 self.open(url=self.server.url + modname +
'.html')
1995 if not self.expanded:
return
1996 self.result_frm.forget()
1997 self.result_scr.forget()
1998 self.result_lst.forget()
1999 self.bigwidth = self.window.winfo_width()
2000 self.bigheight = self.window.winfo_height()
2001 self.window.wm_geometry(
'%dx%d' % (self.minwidth, self.minheight))
2002 self.window.wm_minsize(self.minwidth, self.minheight)
2006 if self.expanded:
return
2007 self.result_frm.pack(side=
'bottom', fill=
'x')
2008 self.result_scr.pack(side=
'right', fill=
'y')
2009 self.result_lst.pack(side=
'top', fill=
'both', expand=1)
2010 self.window.wm_geometry(
'%dx%d' % (self.bigwidth, self.bigheight))
2011 self.window.wm_minsize(self.minwidth, self.bigminheight)
2014 def hide(self, event=None):
2020 gui =
GUI(Tkinter.Tk())
2022 except KeyboardInterrupt:
2028 return type(x)
is types.StringType
and find(x, os.sep) >= 0
2031 """Command-line interface (looks at sys.argv to decide what to do)."""
2033 class BadUsage:
pass
2036 scriptdir = os.path.dirname(sys.argv[0])
2037 if scriptdir
in sys.path:
2038 sys.path.remove(scriptdir)
2039 sys.path.insert(0,
'.')
2045 for opt, val
in opts:
2058 print 'pydoc server ready at %s' % server.url
2060 print 'pydoc server stopped'
2061 serve(port, ready, stopped)
2066 if not args:
raise BadUsage
2069 if ispath(arg)
and os.path.isfile(arg):
2072 if ispath(arg)
and os.path.isdir(arg):
2078 except ErrorDuringImport, value:
2081 except (getopt.error, BadUsage):
2083 print """pydoc - the Python documentation tool
2086 Show text documentation on something. <name> may be the name of a
2087 function, module, or package, or a dotted reference to a class or
2088 function within a module or module in a package. If <name> contains
2089 a '%s', it is used as the path to a Python source file to document.
2092 Search for a keyword in the synopsis lines of all available modules.
2095 Start an HTTP server on the given port on the local machine.
2098 Pop up a graphical interface for finding and serving documentation.
2101 Write out the HTML documentation for a module to a file in the current
2102 directory. If <name> contains a '%s', it is treated as a filename; if
2103 it names a directory, documentation is written for all the contents.
2104 """ % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep)
2106 if __name__ ==
'__main__':
cli()