]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/pydoc.py
2 # -*- coding: latin-1 -*-
3 """Generate Python documentation in HTML or text for interactive use.
5 In the Python interpreter, do "from pydoc import help" to provide online
6 help. Calling help(thing) on a Python object documents the object.
8 Or, at the shell command line outside of Python:
10 Run "pydoc <name>" to show documentation on something. <name> may be
11 the name of a function, module, package, or a dotted reference to a
12 class or function within a module or module in a package. If the
13 argument contains a path segment delimiter (e.g. slash on Unix,
14 backslash on Windows) it is treated as the path to a Python source file.
16 Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines
17 of all available modules.
19 Run "pydoc -p <port>" to start an HTTP server on a given port on the
20 local machine to generate documentation web pages. Port number 0 can be
21 used to get an arbitrary unused port.
23 For platforms without a command line, "pydoc -g" starts the HTTP server
24 and also pops up a little window for controlling it.
26 Run "pydoc -w <name>" to write out the HTML documentation for a module
27 to a file named "<name>.html".
29 Module docs for core modules are assumed to be in
31 http://docs.python.org/library/
33 This can be overridden by setting the PYTHONDOCS environment variable
34 to a different URL or to a local directory containing the Library
35 Reference Manual pages.
38 __author__
= "Ka-Ping Yee <ping@lfw.org>"
39 __date__
= "26 February 2001"
41 __version__
= "$Revision: 88564 $"
42 __credits__
= """Guido van Rossum, for an excellent programming language.
43 Tommy Burnette, the original creator of manpy.
44 Paul Prescod, for all his work on onlinehelp.
45 Richard Chamberlain, for the first implementation of textdoc.
48 # Known bugs that can't be fixed here:
49 # - imp.load_module() cannot be prevented from clobbering existing
50 # loaded modules, so calling synopsis() on a binary module file
51 # changes the contents of any existing module with the same name.
52 # - If the __file__ attribute on a module is a relative path and
53 # the current directory is changed with os.chdir(), an incorrect
54 # path will be displayed.
56 import sys
, imp
, os
, re
, types
, inspect
, __builtin__
, pkgutil
, warnings
58 from string
import expandtabs
, find
, join
, lower
, split
, strip
, rfind
, rstrip
59 from traceback
import extract_tb
61 from collections
import deque
63 # Python 2.3 compatibility
68 # --------------------------------------------------------- common routines
71 """Convert sys.path into a list of absolute, existing, unique paths."""
75 dir = os
.path
.abspath(dir or '.')
76 normdir
= os
.path
.normcase(dir)
77 if normdir
not in normdirs
and os
.path
.isdir(dir):
79 normdirs
.append(normdir
)
83 """Get the doc string or comments for an object."""
84 result
= inspect
.getdoc(object) or inspect
.getcomments(object)
85 result
= _encode(result
)
86 return result
and re
.sub('^ *\n', '', rstrip(result
)) or ''
89 """Split a doc string into a synopsis line (if any) and the rest."""
90 lines
= split(strip(doc
), '\n')
93 elif len(lines
) >= 2 and not rstrip(lines
[1]):
94 return lines
[0], join(lines
[2:], '\n')
95 return '', join(lines
, '\n')
97 def classname(object, modname
):
98 """Get a class name and qualify it with a module name if necessary."""
99 name
= object.__name
__
100 if object.__module
__ != modname
:
101 name
= object.__module
__ + '.' + name
105 """Check if an object is of a type that probably means it's data."""
106 return not (inspect
.ismodule(object) or inspect
.isclass(object) or
107 inspect
.isroutine(object) or inspect
.isframe(object) or
108 inspect
.istraceback(object) or inspect
.iscode(object))
110 def replace(text
, *pairs
):
111 """Do a series of global replacements on a string."""
113 text
= join(split(text
, pairs
[0]), pairs
[1])
117 def cram(text
, maxlen
):
118 """Omit part of a string if needed to make it fit in a maximum length."""
119 if len(text
) > maxlen
:
120 pre
= max(0, (maxlen
-3)//2)
121 post
= max(0, maxlen
-3-pre
)
122 return text
[:pre
] + '...' + text
[len(text
)-post
:]
125 _re_stripid
= re
.compile(r
' at 0x[0-9a-f]{6,16}(>+)$', re
.IGNORECASE
)
127 """Remove the hexadecimal id from a Python object representation."""
128 # The behaviour of %p is implementation-dependent in terms of case.
129 return _re_stripid
.sub(r
'\1', text
)
131 def _is_some_method(obj
):
132 return inspect
.ismethod(obj
) or inspect
.ismethoddescriptor(obj
)
136 for key
, value
in inspect
.getmembers(cl
, _is_some_method
):
138 for base
in cl
.__bases
__:
139 methods
.update(allmethods(base
)) # all your base are belong to us
140 for key
in methods
.keys():
141 methods
[key
] = getattr(cl
, key
)
144 def _split_list(s
, predicate
):
145 """Split sequence s via predicate, and return pair ([true], [false]).
147 The return value is a 2-tuple of lists,
148 ([x for x in s if predicate(x)],
149 [x for x in s if not predicate(x)])
161 def visiblename(name
, all
=None, obj
=None):
162 """Decide whether to show documentation on a variable."""
163 # Certain special names are redundant.
164 _hidden_names
= ('__builtins__', '__doc__', '__file__', '__path__',
165 '__module__', '__name__', '__slots__', '__package__')
166 if name
in _hidden_names
: return 0
167 # Private names are hidden, but special names are displayed.
168 if name
.startswith('__') and name
.endswith('__'): return 1
169 # Namedtuples have public fields and methods with a single leading underscore
170 if name
.startswith('_') and hasattr(obj
, '_fields'):
173 # only document that which the programmer exported in __all__
176 return not name
.startswith('_')
178 def classify_class_attrs(object):
179 """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
181 name
, kind
, cls
, value
= data
182 if inspect
.isdatadescriptor(value
):
183 kind
= 'data descriptor'
184 return name
, kind
, cls
, value
185 return map(fixup
, inspect
.classify_class_attrs(object))
187 # ----------------------------------------------------- Unicode support helpers
192 # If Python is built without Unicode support, the unicode type
193 # will not exist. Fake one that nothing will match, and make
194 # the _encode function that do nothing.
195 class _unicode(object):
198 def _encode(text
, encoding
='ascii'):
202 _encoding
= locale
.getpreferredencoding()
204 def _encode(text
, encoding
=None):
205 if isinstance(text
, unicode):
206 return text
.encode(encoding
or _encoding
, 'xmlcharrefreplace')
211 # Ensure that we have an encoded (binary) string representation of obj,
212 # even if it is a unicode string.
213 if isinstance(obj
, _unicode
):
214 return obj
.encode(_encoding
, 'xmlcharrefreplace')
217 # ----------------------------------------------------- module manipulation
220 """Guess whether a path refers to a package directory."""
221 if os
.path
.isdir(path
):
222 for ext
in ('.py', '.pyc', '.pyo'):
223 if os
.path
.isfile(os
.path
.join(path
, '__init__' + ext
)):
227 def source_synopsis(file):
228 line
= file.readline()
229 while line
[:1] == '#' or not strip(line
):
230 line
= file.readline()
233 if line
[:4] == 'r"""': line
= line
[1:]
234 if line
[:3] == '"""':
236 if line
[-1:] == '\\': line
= line
[:-1]
237 while not strip(line
):
238 line
= file.readline()
240 result
= strip(split(line
, '"""')[0])
244 def synopsis(filename
, cache
={}):
245 """Get the one-line summary out of a module file."""
246 mtime
= os
.stat(filename
).st_mtime
247 lastupdate
, result
= cache
.get(filename
, (None, None))
248 if lastupdate
is None or lastupdate
< mtime
:
249 info
= inspect
.getmoduleinfo(filename
)
251 file = open(filename
)
253 # module can't be opened, so skip it
255 if info
and 'b' in info
[2]: # binary modules have to be imported
256 try: module
= imp
.load_module('__temp__', file, filename
, info
[1:])
258 result
= module
.__doc
__.splitlines()[0] if module
.__doc
__ else None
259 del sys
.modules
['__temp__']
260 else: # text modules can be directly examined
261 result
= source_synopsis(file)
263 cache
[filename
] = (mtime
, result
)
266 class ErrorDuringImport(Exception):
267 """Errors that occurred while trying to import something to document it."""
268 def __init__(self
, filename
, exc_info
):
269 exc
, value
, tb
= exc_info
270 self
.filename
= filename
277 if type(exc
) is types
.ClassType
:
279 return 'problem in %s - %s: %s' % (self
.filename
, exc
, self
.value
)
281 def importfile(path
):
282 """Import a Python source file or compiled file given its path."""
283 magic
= imp
.get_magic()
284 file = open(path
, 'r')
285 if file.read(len(magic
)) == magic
:
286 kind
= imp
.PY_COMPILED
290 filename
= os
.path
.basename(path
)
291 name
, ext
= os
.path
.splitext(filename
)
292 file = open(path
, 'r')
294 module
= imp
.load_module(name
, file, path
, (ext
, 'r', kind
))
296 raise ErrorDuringImport(path
, sys
.exc_info())
300 def safeimport(path
, forceload
=0, cache
={}):
301 """Import a module; handle errors; return None if the module isn't found.
303 If the module *is* found but an exception occurs, it's wrapped in an
304 ErrorDuringImport exception and reraised. Unlike __import__, if a
305 package path is specified, the module at the end of the path is returned,
306 not the package at the beginning. If the optional 'forceload' argument
307 is 1, we reload the module from disk (unless it's a dynamic extension)."""
309 # If forceload is 1 and the module has been previously loaded from
310 # disk, we always have to reload the module. Checking the file's
311 # mtime isn't good enough (e.g. the module could contain a class
312 # that inherits from another module that has changed).
313 if forceload
and path
in sys
.modules
:
314 if path
not in sys
.builtin_module_names
:
315 # Avoid simply calling reload() because it leaves names in
316 # the currently loaded module lying around if they're not
317 # defined in the new source file. Instead, remove the
318 # module from sys.modules and re-import. Also remove any
319 # submodules because they won't appear in the newly loaded
320 # module's namespace if they're already in sys.modules.
321 subs
= [m
for m
in sys
.modules
if m
.startswith(path
+ '.')]
322 for key
in [path
] + subs
:
323 # Prevent garbage collection.
324 cache
[key
] = sys
.modules
[key
]
326 module
= __import__(path
)
328 # Did the error occur before or after the module was found?
329 (exc
, value
, tb
) = info
= sys
.exc_info()
330 if path
in sys
.modules
:
331 # An error occurred while executing the imported module.
332 raise ErrorDuringImport(sys
.modules
[path
].__file
__, info
)
333 elif exc
is SyntaxError:
334 # A SyntaxError occurred before we could execute the module.
335 raise ErrorDuringImport(value
.filename
, info
)
336 elif exc
is ImportError and extract_tb(tb
)[-1][2]=='safeimport':
337 # The import error occurred directly in this function,
338 # which means there is no such module in the path.
341 # Some other error occurred during the importing process.
342 raise ErrorDuringImport(path
, sys
.exc_info())
343 for part
in split(path
, '.')[1:]:
344 try: module
= getattr(module
, part
)
345 except AttributeError: return None
348 # ---------------------------------------------------- formatter base class
351 def document(self
, object, name
=None, *args
):
352 """Generate documentation for an object."""
353 args
= (object, name
) + args
354 # 'try' clause is to attempt to handle the possibility that inspect
355 # identifies something in a way that pydoc itself has issues handling;
356 # think 'super' and how it is a descriptor (which raises the exception
357 # by lacking a __name__ attribute) and an instance.
358 if inspect
.isgetsetdescriptor(object): return self
.docdata(*args
)
359 if inspect
.ismemberdescriptor(object): return self
.docdata(*args
)
361 if inspect
.ismodule(object): return self
.docmodule(*args
)
362 if inspect
.isclass(object): return self
.docclass(*args
)
363 if inspect
.isroutine(object): return self
.docroutine(*args
)
364 except AttributeError:
366 if isinstance(object, property): return self
.docproperty(*args
)
367 return self
.docother(*args
)
369 def fail(self
, object, name
=None, *args
):
370 """Raise an exception for unimplemented types."""
371 message
= "don't know how to document object%s of type %s" % (
372 name
and ' ' + repr(name
), type(object).__name
__)
373 raise TypeError, message
375 docmodule
= docclass
= docroutine
= docother
= docproperty
= docdata
= fail
377 def getdocloc(self
, object):
378 """Return the location of module docs or None"""
381 file = inspect
.getabsfile(object)
385 docloc
= os
.environ
.get("PYTHONDOCS",
386 "http://docs.python.org/library")
387 basedir
= os
.path
.join(sys
.exec_prefix
, "lib",
388 "python"+sys
.version
[0:3])
389 if (isinstance(object, type(os
)) and
390 (object.__name
__ in ('errno', 'exceptions', 'gc', 'imp',
391 'marshal', 'posix', 'signal', 'sys',
392 'thread', 'zipimport') or
393 (file.startswith(basedir
) and
394 not file.startswith(os
.path
.join(basedir
, 'site-packages')))) and
395 object.__name
__ not in ('xml.etree', 'test.pydoc_mod')):
396 if docloc
.startswith("http://"):
397 docloc
= "%s/%s" % (docloc
.rstrip("/"), object.__name
__)
399 docloc
= os
.path
.join(docloc
, object.__name
__ + ".html")
404 # -------------------------------------------- HTML documentation generator
406 class HTMLRepr(Repr
):
407 """Class for safely making an HTML representation of a Python object."""
410 self
.maxlist
= self
.maxtuple
= 20
412 self
.maxstring
= self
.maxother
= 100
414 def escape(self
, text
):
415 return replace(text
, '&', '&', '<', '<', '>', '>')
417 def repr(self
, object):
418 return Repr
.repr(self
, object)
420 def repr1(self
, x
, level
):
421 if hasattr(type(x
), '__name__'):
422 methodname
= 'repr_' + join(split(type(x
).__name
__), '_')
423 if hasattr(self
, methodname
):
424 return getattr(self
, methodname
)(x
, level
)
425 return self
.escape(cram(stripid(repr(x
)), self
.maxother
))
427 def repr_string(self
, x
, level
):
428 test
= cram(x
, self
.maxstring
)
429 testrepr
= repr(test
)
430 if '\\' in test
and '\\' not in replace(testrepr
, r
'\\', ''):
431 # Backslashes are only literal in the string and are never
432 # needed to make any special characters, so show a raw string.
433 return 'r' + testrepr
[0] + self
.escape(test
) + testrepr
[0]
434 return re
.sub(r
'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
435 r'<font color="#c040c0">\1</font>',
436 self
.escape(testrepr
))
438 repr_str
= repr_string
440 def repr_instance(self
, x
, level
):
442 return self
.escape(cram(stripid(repr(x
)), self
.maxstring
))
444 return self
.escape('<%s instance>' % x
.__class
__.__name
__)
446 repr_unicode
= repr_string
449 """Formatter class for HTML documentation."""
451 # ------------------------------------------- HTML formatting utilities
453 _repr_instance
= HTMLRepr()
454 repr = _repr_instance
.repr
455 escape
= _repr_instance
.escape
457 def page(self
, title
, contents
):
458 """Format an HTML page."""
460 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
461 <html><head><title>Python: %s</title>
462 <meta charset="utf-8">
463 </head><body bgcolor="#f0f0f8">
465 </body></html>''' % (title
, contents
), 'ascii')
467 def heading(self
, title
, fgcol
, bgcol
, extras
=''):
468 """Format a page heading."""
470 <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
472 <td valign=bottom> <br>
473 <font color="%s" face="helvetica, arial"> <br>%s</font></td
474 ><td align=right valign=bottom
475 ><font color="%s" face="helvetica, arial">%s</font></td></tr></table>
476 ''' % (bgcol
, fgcol
, title
, fgcol
, extras
or ' ')
478 def section(self
, title
, fgcol
, bgcol
, contents
, width
=6,
479 prelude
='', marginalia
=None, gap
=' '):
480 """Format a section with a heading."""
481 if marginalia
is None:
482 marginalia
= '<tt>' + ' ' * width
+ '</tt>'
484 <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
486 <td colspan=3 valign=bottom> <br>
487 <font color="%s" face="helvetica, arial">%s</font></td></tr>
488 ''' % (bgcol
, fgcol
, title
)
490 result
= result
+ '''
491 <tr bgcolor="%s"><td rowspan=2>%s</td>
492 <td colspan=2>%s</td></tr>
493 <tr><td>%s</td>''' % (bgcol
, marginalia
, prelude
, gap
)
495 result
= result
+ '''
496 <tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol
, marginalia
, gap
)
498 return result
+ '\n<td width="100%%">%s</td></tr></table>' % contents
500 def bigsection(self
, title
, *args
):
501 """Format a section with a big heading."""
502 title
= '<big><strong>%s</strong></big>' % title
503 return self
.section(title
, *args
)
505 def preformat(self
, text
):
506 """Format literal preformatted text."""
507 text
= self
.escape(expandtabs(text
))
508 return replace(text
, '\n\n', '\n \n', '\n\n', '\n \n',
509 ' ', ' ', '\n', '<br>\n')
511 def multicolumn(self
, list, format
, cols
=4):
512 """Format a list of items into a multi-column list."""
514 rows
= (len(list)+cols
-1)//cols
515 for col
in range(cols
):
516 result
= result
+ '<td width="%d%%" valign=top>' % (100//cols
)
517 for i
in range(rows
*col
, rows
*col
+rows
):
519 result
= result
+ format(list[i
]) + '<br>\n'
520 result
= result
+ '</td>'
521 return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
523 def grey(self
, text
): return '<font color="#909090">%s</font>' % text
525 def namelink(self
, name
, *dicts
):
526 """Make a link for an identifier, given name-to-URL mappings."""
529 return '<a href="%s">%s</a>' % (dict[name
], name
)
532 def classlink(self
, object, modname
):
533 """Make a link for a class."""
534 name
, module
= object.__name
__, sys
.modules
.get(object.__module
__)
535 if hasattr(module
, name
) and getattr(module
, name
) is object:
536 return '<a href="%s.html#%s">%s</a>' % (
537 module
.__name
__, name
, classname(object, modname
))
538 return classname(object, modname
)
540 def modulelink(self
, object):
541 """Make a link for a module."""
542 return '<a href="%s.html">%s</a>' % (object.__name
__, object.__name
__)
544 def modpkglink(self
, data
):
545 """Make a link for a module or package to display in an index."""
546 name
, path
, ispackage
, shadowed
= data
548 return self
.grey(name
)
550 url
= '%s.%s.html' % (path
, name
)
552 url
= '%s.html' % name
554 text
= '<strong>%s</strong> (package)' % name
557 return '<a href="%s">%s</a>' % (url
, text
)
559 def markup(self
, text
, escape
=None, funcs
={}, classes
={}, methods
={}):
560 """Mark up some plain text, given a context of symbols to look for.
561 Each context dictionary maps object names to anchor names."""
562 escape
= escape
or self
.escape
565 pattern
= re
.compile(r
'\b((http|ftp)://\S+[\w/]|'
570 match
= pattern
.search(text
, here
)
572 start
, end
= match
.span()
573 results
.append(escape(text
[here
:start
]))
575 all
, scheme
, rfc
, pep
, selfdot
, name
= match
.groups()
577 url
= escape(all
).replace('"', '"')
578 results
.append('<a href="%s">%s</a>' % (url
, url
))
580 url
= 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc
)
581 results
.append('<a href="%s">%s</a>' % (url
, escape(all
)))
583 url
= 'http://www.python.org/dev/peps/pep-%04d/' % int(pep
)
584 results
.append('<a href="%s">%s</a>' % (url
, escape(all
)))
586 # Create a link for methods like 'self.method(...)'
587 # and use <strong> for attributes like 'self.attr'
588 if text
[end
:end
+1] == '(':
589 results
.append('self.' + self
.namelink(name
, methods
))
591 results
.append('self.<strong>%s</strong>' % name
)
592 elif text
[end
:end
+1] == '(':
593 results
.append(self
.namelink(name
, methods
, funcs
, classes
))
595 results
.append(self
.namelink(name
, classes
))
597 results
.append(escape(text
[here
:]))
598 return join(results
, '')
600 # ---------------------------------------------- type-specific routines
602 def formattree(self
, tree
, modname
, parent
=None):
603 """Produce HTML for a class tree as given by inspect.getclasstree()."""
606 if type(entry
) is type(()):
608 result
= result
+ '<dt><font face="helvetica, arial">'
609 result
= result
+ self
.classlink(c
, modname
)
610 if bases
and bases
!= (parent
,):
613 parents
.append(self
.classlink(base
, modname
))
614 result
= result
+ '(' + join(parents
, ', ') + ')'
615 result
= result
+ '\n</font></dt>'
616 elif type(entry
) is type([]):
617 result
= result
+ '<dd>\n%s</dd>\n' % self
.formattree(
619 return '<dl>\n%s</dl>\n' % result
621 def docmodule(self
, object, name
=None, mod
=None, *ignored
):
622 """Produce HTML documentation for a module object."""
623 name
= object.__name
__ # ignore the passed-in name
626 except AttributeError:
628 parts
= split(name
, '.')
630 for i
in range(len(parts
)-1):
632 '<a href="%s.html"><font color="#ffffff">%s</font></a>' %
633 (join(parts
[:i
+1], '.'), parts
[i
]))
634 linkedname
= join(links
+ parts
[-1:], '.')
635 head
= '<big><big><strong>%s</strong></big></big>' % linkedname
637 path
= inspect
.getabsfile(object)
639 if sys
.platform
== 'win32':
641 url
= nturl2path
.pathname2url(path
)
642 filelink
= '<a href="file:%s">%s</a>' % (url
, path
)
644 filelink
= '(built-in)'
646 if hasattr(object, '__version__'):
647 version
= _binstr(object.__version
__)
648 if version
[:11] == '$' + 'Revision: ' and version
[-1:] == '$':
649 version
= strip(version
[11:-1])
650 info
.append('version %s' % self
.escape(version
))
651 if hasattr(object, '__date__'):
652 info
.append(self
.escape(_binstr(object.__date
__)))
654 head
= head
+ ' (%s)' % join(info
, ', ')
655 docloc
= self
.getdocloc(object)
656 if docloc
is not None:
657 docloc
= '<br><a href="%(docloc)s">Module Docs</a>' % locals()
660 result
= self
.heading(
661 head
, '#ffffff', '#7799ee',
662 '<a href=".">index</a><br>' + filelink
+ docloc
)
664 modules
= inspect
.getmembers(object, inspect
.ismodule
)
666 classes
, cdict
= [], {}
667 for key
, value
in inspect
.getmembers(object, inspect
.isclass
):
668 # if __all__ exists, believe it. Otherwise use old heuristic.
669 if (all
is not None or
670 (inspect
.getmodule(value
) or object) is object):
671 if visiblename(key
, all
, object):
672 classes
.append((key
, value
))
673 cdict
[key
] = cdict
[value
] = '#' + key
674 for key
, value
in classes
:
675 for base
in value
.__bases
__:
676 key
, modname
= base
.__name
__, base
.__module
__
677 module
= sys
.modules
.get(modname
)
678 if modname
!= name
and module
and hasattr(module
, key
):
679 if getattr(module
, key
) is base
:
681 cdict
[key
] = cdict
[base
] = modname
+ '.html#' + key
682 funcs
, fdict
= [], {}
683 for key
, value
in inspect
.getmembers(object, inspect
.isroutine
):
684 # if __all__ exists, believe it. Otherwise use old heuristic.
685 if (all
is not None or
686 inspect
.isbuiltin(value
) or inspect
.getmodule(value
) is object):
687 if visiblename(key
, all
, object):
688 funcs
.append((key
, value
))
689 fdict
[key
] = '#-' + key
690 if inspect
.isfunction(value
): fdict
[value
] = fdict
[key
]
692 for key
, value
in inspect
.getmembers(object, isdata
):
693 if visiblename(key
, all
, object):
694 data
.append((key
, value
))
696 doc
= self
.markup(getdoc(object), self
.preformat
, fdict
, cdict
)
697 doc
= doc
and '<tt>%s</tt>' % doc
698 result
= result
+ '<p>%s</p>\n' % doc
700 if hasattr(object, '__path__'):
702 for importer
, modname
, ispkg
in pkgutil
.iter_modules(object.__path
__):
703 modpkgs
.append((modname
, name
, ispkg
, 0))
705 contents
= self
.multicolumn(modpkgs
, self
.modpkglink
)
706 result
= result
+ self
.bigsection(
707 'Package Contents', '#ffffff', '#aa55cc', contents
)
709 contents
= self
.multicolumn(
710 modules
, lambda key_value
, s
=self
: s
.modulelink(key_value
[1]))
711 result
= result
+ self
.bigsection(
712 'Modules', '#ffffff', '#aa55cc', contents
)
715 classlist
= map(lambda key_value
: key_value
[1], classes
)
717 self
.formattree(inspect
.getclasstree(classlist
, 1), name
)]
718 for key
, value
in classes
:
719 contents
.append(self
.document(value
, key
, name
, fdict
, cdict
))
720 result
= result
+ self
.bigsection(
721 'Classes', '#ffffff', '#ee77aa', join(contents
))
724 for key
, value
in funcs
:
725 contents
.append(self
.document(value
, key
, name
, fdict
, cdict
))
726 result
= result
+ self
.bigsection(
727 'Functions', '#ffffff', '#eeaa77', join(contents
))
730 for key
, value
in data
:
731 contents
.append(self
.document(value
, key
))
732 result
= result
+ self
.bigsection(
733 'Data', '#ffffff', '#55aa55', join(contents
, '<br>\n'))
734 if hasattr(object, '__author__'):
735 contents
= self
.markup(_binstr(object.__author
__), self
.preformat
)
736 result
= result
+ self
.bigsection(
737 'Author', '#ffffff', '#7799ee', contents
)
738 if hasattr(object, '__credits__'):
739 contents
= self
.markup(_binstr(object.__credits
__), self
.preformat
)
740 result
= result
+ self
.bigsection(
741 'Credits', '#ffffff', '#7799ee', contents
)
745 def docclass(self
, object, name
=None, mod
=None, funcs
={}, classes
={},
747 """Produce HTML documentation for a class object."""
748 realname
= object.__name
__
749 name
= name
or realname
750 bases
= object.__bases
__
753 push
= contents
.append
755 # Cute little class to pump out a horizontal rule between sections.
756 class HorizontalRule
:
763 hr
= HorizontalRule()
765 # List the mro, if non-trivial.
766 mro
= deque(inspect
.getmro(object))
769 push('<dl><dt>Method resolution order:</dt>\n')
771 push('<dd>%s</dd>\n' % self
.classlink(base
,
775 def spill(msg
, attrs
, predicate
):
776 ok
, attrs
= _split_list(attrs
, predicate
)
780 for name
, kind
, homecls
, value
in ok
:
782 value
= getattr(object, name
)
784 # Some descriptors may meet a failure in their __get__.
786 push(self
._docdescriptor
(name
, value
, mod
))
788 push(self
.document(value
, name
, mod
,
789 funcs
, classes
, mdict
, object))
793 def spilldescriptors(msg
, attrs
, predicate
):
794 ok
, attrs
= _split_list(attrs
, predicate
)
798 for name
, kind
, homecls
, value
in ok
:
799 push(self
._docdescriptor
(name
, value
, mod
))
802 def spilldata(msg
, attrs
, predicate
):
803 ok
, attrs
= _split_list(attrs
, predicate
)
807 for name
, kind
, homecls
, value
in ok
:
808 base
= self
.docother(getattr(object, name
), name
, mod
)
809 if (hasattr(value
, '__call__') or
810 inspect
.isdatadescriptor(value
)):
811 doc
= getattr(value
, "__doc__", None)
815 push('<dl><dt>%s</dl>\n' % base
)
817 doc
= self
.markup(getdoc(value
), self
.preformat
,
818 funcs
, classes
, mdict
)
819 doc
= '<dd><tt>%s</tt>' % doc
820 push('<dl><dt>%s%s</dl>\n' % (base
, doc
))
824 attrs
= filter(lambda data
: visiblename(data
[0], obj
=object),
825 classify_class_attrs(object))
827 for key
, kind
, homecls
, value
in attrs
:
828 mdict
[key
] = anchor
= '#' + name
+ '-' + key
830 value
= getattr(object, name
)
832 # Some descriptors may meet a failure in their __get__.
836 # The value may not be hashable (e.g., a data attr with
837 # a dict or list value).
838 mdict
[value
] = anchor
844 thisclass
= mro
.popleft()
846 thisclass
= attrs
[0][2]
847 attrs
, inherited
= _split_list(attrs
, lambda t
: t
[2] is thisclass
)
849 if thisclass
is __builtin__
.object:
852 elif thisclass
is object:
855 tag
= 'inherited from %s' % self
.classlink(thisclass
,
859 # Sort attrs by name.
861 attrs
.sort(key
=lambda t
: t
[0])
863 attrs
.sort(lambda t1
, t2
: cmp(t1
[0], t2
[0])) # 2.3 compat
865 # Pump out the attrs, segregated by kind.
866 attrs
= spill('Methods %s' % tag
, attrs
,
867 lambda t
: t
[1] == 'method')
868 attrs
= spill('Class methods %s' % tag
, attrs
,
869 lambda t
: t
[1] == 'class method')
870 attrs
= spill('Static methods %s' % tag
, attrs
,
871 lambda t
: t
[1] == 'static method')
872 attrs
= spilldescriptors('Data descriptors %s' % tag
, attrs
,
873 lambda t
: t
[1] == 'data descriptor')
874 attrs
= spilldata('Data and other attributes %s' % tag
, attrs
,
875 lambda t
: t
[1] == 'data')
879 contents
= ''.join(contents
)
882 title
= '<a name="%s">class <strong>%s</strong></a>' % (
885 title
= '<strong>%s</strong> = <a name="%s">class %s</a>' % (
886 name
, name
, realname
)
890 parents
.append(self
.classlink(base
, object.__module
__))
891 title
= title
+ '(%s)' % join(parents
, ', ')
892 doc
= self
.markup(getdoc(object), self
.preformat
, funcs
, classes
, mdict
)
893 doc
= doc
and '<tt>%s<br> </tt>' % doc
895 return self
.section(title
, '#000000', '#ffc8d8', contents
, 3, doc
)
897 def formatvalue(self
, object):
898 """Format an argument default value as text."""
899 return self
.grey('=' + self
.repr(object))
901 def docroutine(self
, object, name
=None, mod
=None,
902 funcs
={}, classes
={}, methods
={}, cl
=None):
903 """Produce HTML documentation for a function or method object."""
904 realname
= object.__name
__
905 name
= name
or realname
906 anchor
= (cl
and cl
.__name
__ or '') + '-' + name
909 if inspect
.ismethod(object):
910 imclass
= object.im_class
912 if imclass
is not cl
:
913 note
= ' from ' + self
.classlink(imclass
, mod
)
915 if object.im_self
is not None:
916 note
= ' method of %s instance' % self
.classlink(
917 object.im_self
.__class
__, mod
)
919 note
= ' unbound %s method' % self
.classlink(imclass
,mod
)
920 object = object.im_func
923 title
= '<a name="%s"><strong>%s</strong></a>' % (anchor
, realname
)
925 if (cl
and realname
in cl
.__dict
__ and
926 cl
.__dict
__[realname
] is object):
927 reallink
= '<a href="#%s">%s</a>' % (
928 cl
.__name
__ + '-' + realname
, realname
)
932 title
= '<a name="%s"><strong>%s</strong></a> = %s' % (
933 anchor
, name
, reallink
)
934 if inspect
.isfunction(object):
935 args
, varargs
, varkw
, defaults
= inspect
.getargspec(object)
936 argspec
= inspect
.formatargspec(
937 args
, varargs
, varkw
, defaults
, formatvalue
=self
.formatvalue
)
938 if realname
== '<lambda>':
939 title
= '<strong>%s</strong> <em>lambda</em> ' % name
940 argspec
= argspec
[1:-1] # remove parentheses
944 decl
= title
+ argspec
+ (note
and self
.grey(
945 '<font face="helvetica, arial">%s</font>' % note
))
948 return '<dl><dt>%s</dt></dl>\n' % decl
951 getdoc(object), self
.preformat
, funcs
, classes
, methods
)
952 doc
= doc
and '<dd><tt>%s</tt></dd>' % doc
953 return '<dl><dt>%s</dt>%s</dl>\n' % (decl
, doc
)
955 def _docdescriptor(self
, name
, value
, mod
):
957 push
= results
.append
960 push('<dl><dt><strong>%s</strong></dt>\n' % name
)
961 if value
.__doc
__ is not None:
962 doc
= self
.markup(getdoc(value
), self
.preformat
)
963 push('<dd><tt>%s</tt></dd>\n' % doc
)
966 return ''.join(results
)
968 def docproperty(self
, object, name
=None, mod
=None, cl
=None):
969 """Produce html documentation for a property."""
970 return self
._docdescriptor
(name
, object, mod
)
972 def docother(self
, object, name
=None, mod
=None, *ignored
):
973 """Produce HTML documentation for a data object."""
974 lhs
= name
and '<strong>%s</strong> = ' % name
or ''
975 return lhs
+ self
.repr(object)
977 def docdata(self
, object, name
=None, mod
=None, cl
=None):
978 """Produce html documentation for a data descriptor."""
979 return self
._docdescriptor
(name
, object, mod
)
981 def index(self
, dir, shadowed
=None):
982 """Generate an HTML index for a directory of modules."""
984 if shadowed
is None: shadowed
= {}
985 for importer
, name
, ispkg
in pkgutil
.iter_modules([dir]):
986 modpkgs
.append((name
, '', ispkg
, name
in shadowed
))
990 contents
= self
.multicolumn(modpkgs
, self
.modpkglink
)
991 return self
.bigsection(dir, '#ffffff', '#ee77aa', contents
)
993 # -------------------------------------------- text documentation generator
995 class TextRepr(Repr
):
996 """Class for safely making a text representation of a Python object."""
999 self
.maxlist
= self
.maxtuple
= 20
1001 self
.maxstring
= self
.maxother
= 100
1003 def repr1(self
, x
, level
):
1004 if hasattr(type(x
), '__name__'):
1005 methodname
= 'repr_' + join(split(type(x
).__name
__), '_')
1006 if hasattr(self
, methodname
):
1007 return getattr(self
, methodname
)(x
, level
)
1008 return cram(stripid(repr(x
)), self
.maxother
)
1010 def repr_string(self
, x
, level
):
1011 test
= cram(x
, self
.maxstring
)
1012 testrepr
= repr(test
)
1013 if '\\' in test
and '\\' not in replace(testrepr
, r
'\\', ''):
1014 # Backslashes are only literal in the string and are never
1015 # needed to make any special characters, so show a raw string.
1016 return 'r' + testrepr
[0] + test
+ testrepr
[0]
1019 repr_str
= repr_string
1021 def repr_instance(self
, x
, level
):
1023 return cram(stripid(repr(x
)), self
.maxstring
)
1025 return '<%s instance>' % x
.__class
__.__name
__
1028 """Formatter class for text documentation."""
1030 # ------------------------------------------- text formatting utilities
1032 _repr_instance
= TextRepr()
1033 repr = _repr_instance
.repr
1035 def bold(self
, text
):
1036 """Format a string in bold by overstriking."""
1037 return join(map(lambda ch
: ch
+ '\b' + ch
, text
), '')
1039 def indent(self
, text
, prefix
=' '):
1040 """Indent text by prepending a given prefix to each line."""
1041 if not text
: return ''
1042 lines
= split(text
, '\n')
1043 lines
= map(lambda line
, prefix
=prefix
: prefix
+ line
, lines
)
1044 if lines
: lines
[-1] = rstrip(lines
[-1])
1045 return join(lines
, '\n')
1047 def section(self
, title
, contents
):
1048 """Format a section with a given heading."""
1049 return self
.bold(title
) + '\n' + rstrip(self
.indent(contents
)) + '\n\n'
1051 # ---------------------------------------------- type-specific routines
1053 def formattree(self
, tree
, modname
, parent
=None, prefix
=''):
1054 """Render in text a class tree as returned by inspect.getclasstree()."""
1057 if type(entry
) is type(()):
1059 result
= result
+ prefix
+ classname(c
, modname
)
1060 if bases
and bases
!= (parent
,):
1061 parents
= map(lambda c
, m
=modname
: classname(c
, m
), bases
)
1062 result
= result
+ '(%s)' % join(parents
, ', ')
1063 result
= result
+ '\n'
1064 elif type(entry
) is type([]):
1065 result
= result
+ self
.formattree(
1066 entry
, modname
, c
, prefix
+ ' ')
1069 def docmodule(self
, object, name
=None, mod
=None):
1070 """Produce text documentation for a given module object."""
1071 name
= object.__name
__ # ignore the passed-in name
1072 synop
, desc
= splitdoc(getdoc(object))
1073 result
= self
.section('NAME', name
+ (synop
and ' - ' + synop
))
1076 all
= object.__all
__
1077 except AttributeError:
1081 file = inspect
.getabsfile(object)
1084 result
= result
+ self
.section('FILE', file)
1086 docloc
= self
.getdocloc(object)
1087 if docloc
is not None:
1088 result
= result
+ self
.section('MODULE DOCS', docloc
)
1091 result
= result
+ self
.section('DESCRIPTION', desc
)
1094 for key
, value
in inspect
.getmembers(object, inspect
.isclass
):
1095 # if __all__ exists, believe it. Otherwise use old heuristic.
1097 or (inspect
.getmodule(value
) or object) is object):
1098 if visiblename(key
, all
, object):
1099 classes
.append((key
, value
))
1101 for key
, value
in inspect
.getmembers(object, inspect
.isroutine
):
1102 # if __all__ exists, believe it. Otherwise use old heuristic.
1103 if (all
is not None or
1104 inspect
.isbuiltin(value
) or inspect
.getmodule(value
) is object):
1105 if visiblename(key
, all
, object):
1106 funcs
.append((key
, value
))
1108 for key
, value
in inspect
.getmembers(object, isdata
):
1109 if visiblename(key
, all
, object):
1110 data
.append((key
, value
))
1113 modpkgs_names
= set()
1114 if hasattr(object, '__path__'):
1115 for importer
, modname
, ispkg
in pkgutil
.iter_modules(object.__path
__):
1116 modpkgs_names
.add(modname
)
1118 modpkgs
.append(modname
+ ' (package)')
1120 modpkgs
.append(modname
)
1123 result
= result
+ self
.section(
1124 'PACKAGE CONTENTS', join(modpkgs
, '\n'))
1126 # Detect submodules as sometimes created by C extensions
1128 for key
, value
in inspect
.getmembers(object, inspect
.ismodule
):
1129 if value
.__name
__.startswith(name
+ '.') and key
not in modpkgs_names
:
1130 submodules
.append(key
)
1133 result
= result
+ self
.section(
1134 'SUBMODULES', join(submodules
, '\n'))
1137 classlist
= map(lambda key_value
: key_value
[1], classes
)
1138 contents
= [self
.formattree(
1139 inspect
.getclasstree(classlist
, 1), name
)]
1140 for key
, value
in classes
:
1141 contents
.append(self
.document(value
, key
, name
))
1142 result
= result
+ self
.section('CLASSES', join(contents
, '\n'))
1146 for key
, value
in funcs
:
1147 contents
.append(self
.document(value
, key
, name
))
1148 result
= result
+ self
.section('FUNCTIONS', join(contents
, '\n'))
1152 for key
, value
in data
:
1153 contents
.append(self
.docother(value
, key
, name
, maxlen
=70))
1154 result
= result
+ self
.section('DATA', join(contents
, '\n'))
1156 if hasattr(object, '__version__'):
1157 version
= _binstr(object.__version
__)
1158 if version
[:11] == '$' + 'Revision: ' and version
[-1:] == '$':
1159 version
= strip(version
[11:-1])
1160 result
= result
+ self
.section('VERSION', version
)
1161 if hasattr(object, '__date__'):
1162 result
= result
+ self
.section('DATE', _binstr(object.__date
__))
1163 if hasattr(object, '__author__'):
1164 result
= result
+ self
.section('AUTHOR', _binstr(object.__author
__))
1165 if hasattr(object, '__credits__'):
1166 result
= result
+ self
.section('CREDITS', _binstr(object.__credits
__))
1169 def docclass(self
, object, name
=None, mod
=None, *ignored
):
1170 """Produce text documentation for a given class object."""
1171 realname
= object.__name
__
1172 name
= name
or realname
1173 bases
= object.__bases
__
1175 def makename(c
, m
=object.__module
__):
1176 return classname(c
, m
)
1178 if name
== realname
:
1179 title
= 'class ' + self
.bold(realname
)
1181 title
= self
.bold(name
) + ' = class ' + realname
1183 parents
= map(makename
, bases
)
1184 title
= title
+ '(%s)' % join(parents
, ', ')
1186 doc
= getdoc(object)
1187 contents
= doc
and [doc
+ '\n'] or []
1188 push
= contents
.append
1190 # List the mro, if non-trivial.
1191 mro
= deque(inspect
.getmro(object))
1193 push("Method resolution order:")
1195 push(' ' + makename(base
))
1198 # Cute little class to pump out a horizontal rule between sections.
1199 class HorizontalRule
:
1206 hr
= HorizontalRule()
1208 def spill(msg
, attrs
, predicate
):
1209 ok
, attrs
= _split_list(attrs
, predicate
)
1213 for name
, kind
, homecls
, value
in ok
:
1215 value
= getattr(object, name
)
1217 # Some descriptors may meet a failure in their __get__.
1219 push(self
._docdescriptor
(name
, value
, mod
))
1221 push(self
.document(value
,
1225 def spilldescriptors(msg
, attrs
, predicate
):
1226 ok
, attrs
= _split_list(attrs
, predicate
)
1230 for name
, kind
, homecls
, value
in ok
:
1231 push(self
._docdescriptor
(name
, value
, mod
))
1234 def spilldata(msg
, attrs
, predicate
):
1235 ok
, attrs
= _split_list(attrs
, predicate
)
1239 for name
, kind
, homecls
, value
in ok
:
1240 if (hasattr(value
, '__call__') or
1241 inspect
.isdatadescriptor(value
)):
1245 push(self
.docother(getattr(object, name
),
1246 name
, mod
, maxlen
=70, doc
=doc
) + '\n')
1249 attrs
= filter(lambda data
: visiblename(data
[0], obj
=object),
1250 classify_class_attrs(object))
1253 thisclass
= mro
.popleft()
1255 thisclass
= attrs
[0][2]
1256 attrs
, inherited
= _split_list(attrs
, lambda t
: t
[2] is thisclass
)
1258 if thisclass
is __builtin__
.object:
1261 elif thisclass
is object:
1262 tag
= "defined here"
1264 tag
= "inherited from %s" % classname(thisclass
,
1267 # Sort attrs by name.
1270 # Pump out the attrs, segregated by kind.
1271 attrs
= spill("Methods %s:\n" % tag
, attrs
,
1272 lambda t
: t
[1] == 'method')
1273 attrs
= spill("Class methods %s:\n" % tag
, attrs
,
1274 lambda t
: t
[1] == 'class method')
1275 attrs
= spill("Static methods %s:\n" % tag
, attrs
,
1276 lambda t
: t
[1] == 'static method')
1277 attrs
= spilldescriptors("Data descriptors %s:\n" % tag
, attrs
,
1278 lambda t
: t
[1] == 'data descriptor')
1279 attrs
= spilldata("Data and other attributes %s:\n" % tag
, attrs
,
1280 lambda t
: t
[1] == 'data')
1284 contents
= '\n'.join(contents
)
1287 return title
+ '\n' + self
.indent(rstrip(contents
), ' | ') + '\n'
1289 def formatvalue(self
, object):
1290 """Format an argument default value as text."""
1291 return '=' + self
.repr(object)
1293 def docroutine(self
, object, name
=None, mod
=None, cl
=None):
1294 """Produce text documentation for a function or method object."""
1295 realname
= object.__name
__
1296 name
= name
or realname
1299 if inspect
.ismethod(object):
1300 imclass
= object.im_class
1302 if imclass
is not cl
:
1303 note
= ' from ' + classname(imclass
, mod
)
1305 if object.im_self
is not None:
1306 note
= ' method of %s instance' % classname(
1307 object.im_self
.__class
__, mod
)
1309 note
= ' unbound %s method' % classname(imclass
,mod
)
1310 object = object.im_func
1312 if name
== realname
:
1313 title
= self
.bold(realname
)
1315 if (cl
and realname
in cl
.__dict
__ and
1316 cl
.__dict
__[realname
] is object):
1318 title
= self
.bold(name
) + ' = ' + realname
1319 if inspect
.isfunction(object):
1320 args
, varargs
, varkw
, defaults
= inspect
.getargspec(object)
1321 argspec
= inspect
.formatargspec(
1322 args
, varargs
, varkw
, defaults
, formatvalue
=self
.formatvalue
)
1323 if realname
== '<lambda>':
1324 title
= self
.bold(name
) + ' lambda '
1325 argspec
= argspec
[1:-1] # remove parentheses
1328 decl
= title
+ argspec
+ note
1333 doc
= getdoc(object) or ''
1334 return decl
+ '\n' + (doc
and rstrip(self
.indent(doc
)) + '\n')
1336 def _docdescriptor(self
, name
, value
, mod
):
1338 push
= results
.append
1341 push(self
.bold(name
))
1343 doc
= getdoc(value
) or ''
1345 push(self
.indent(doc
))
1347 return ''.join(results
)
1349 def docproperty(self
, object, name
=None, mod
=None, cl
=None):
1350 """Produce text documentation for a property."""
1351 return self
._docdescriptor
(name
, object, mod
)
1353 def docdata(self
, object, name
=None, mod
=None, cl
=None):
1354 """Produce text documentation for a data descriptor."""
1355 return self
._docdescriptor
(name
, object, mod
)
1357 def docother(self
, object, name
=None, mod
=None, parent
=None, maxlen
=None, doc
=None):
1358 """Produce text documentation for a data object."""
1359 repr = self
.repr(object)
1361 line
= (name
and name
+ ' = ' or '') + repr
1362 chop
= maxlen
- len(line
)
1363 if chop
< 0: repr = repr[:chop
] + '...'
1364 line
= (name
and self
.bold(name
) + ' = ' or '') + repr
1366 line
+= '\n' + self
.indent(str(doc
))
1369 # --------------------------------------------------------- user interfaces
1372 """The first time this is called, determine what kind of pager to use."""
1378 """Decide what method to use for paging through text."""
1379 if type(sys
.stdout
) is not types
.FileType
:
1381 if not hasattr(sys
.stdin
, "isatty"):
1383 if not sys
.stdin
.isatty() or not sys
.stdout
.isatty():
1385 if 'PAGER' in os
.environ
:
1386 if sys
.platform
== 'win32': # pipes completely broken in Windows
1387 return lambda text
: tempfilepager(plain(text
), os
.environ
['PAGER'])
1388 elif os
.environ
.get('TERM') in ('dumb', 'emacs'):
1389 return lambda text
: pipepager(plain(text
), os
.environ
['PAGER'])
1391 return lambda text
: pipepager(text
, os
.environ
['PAGER'])
1392 if os
.environ
.get('TERM') in ('dumb', 'emacs'):
1394 if sys
.platform
== 'win32' or sys
.platform
.startswith('os2'):
1395 return lambda text
: tempfilepager(plain(text
), 'more <')
1396 if hasattr(os
, 'system') and os
.system('(less) 2>/dev/null') == 0:
1397 return lambda text
: pipepager(text
, 'less')
1400 (fd
, filename
) = tempfile
.mkstemp()
1403 if hasattr(os
, 'system') and os
.system('more "%s"' % filename
) == 0:
1404 return lambda text
: pipepager(text
, 'more')
1411 """Remove boldface formatting from text."""
1412 return re
.sub('.\b', '', text
)
1414 def pipepager(text
, cmd
):
1415 """Page through text by feeding it to another program."""
1416 pipe
= os
.popen(cmd
, 'w')
1418 pipe
.write(_encode(text
))
1421 pass # Ignore broken pipes caused by quitting the pager program.
1423 def tempfilepager(text
, cmd
):
1424 """Page through text by invoking a program on a temporary file."""
1426 filename
= tempfile
.mktemp()
1427 file = open(filename
, 'w')
1428 file.write(_encode(text
))
1431 os
.system(cmd
+ ' "' + filename
+ '"')
1436 """Page through text on a text terminal."""
1437 lines
= plain(_encode(plain(text
), getattr(sys
.stdout
, 'encoding', _encoding
))).split('\n')
1440 fd
= sys
.stdin
.fileno()
1441 old
= tty
.tcgetattr(fd
)
1443 getchar
= lambda: sys
.stdin
.read(1)
1444 except (ImportError, AttributeError):
1446 getchar
= lambda: sys
.stdin
.readline()[:-1][:1]
1450 h
= int(os
.environ
.get('LINES', 0))
1456 sys
.stdout
.write(join(lines
[:inc
], '\n') + '\n')
1458 sys
.stdout
.write('-- more --')
1463 sys
.stdout
.write('\r \r')
1465 elif c
in ('\r', '\n'):
1466 sys
.stdout
.write('\r \r' + lines
[r
] + '\n')
1469 if c
in ('b', 'B', '\x1b'):
1472 sys
.stdout
.write('\n' + join(lines
[r
:r
+inc
], '\n') + '\n')
1477 tty
.tcsetattr(fd
, tty
.TCSAFLUSH
, old
)
1479 def plainpager(text
):
1480 """Simply print unformatted text. This is the ultimate fallback."""
1481 sys
.stdout
.write(_encode(plain(text
), getattr(sys
.stdout
, 'encoding', _encoding
)))
1483 def describe(thing
):
1484 """Produce a short description of the given thing."""
1485 if inspect
.ismodule(thing
):
1486 if thing
.__name
__ in sys
.builtin_module_names
:
1487 return 'built-in module ' + thing
.__name
__
1488 if hasattr(thing
, '__path__'):
1489 return 'package ' + thing
.__name
__
1491 return 'module ' + thing
.__name
__
1492 if inspect
.isbuiltin(thing
):
1493 return 'built-in function ' + thing
.__name
__
1494 if inspect
.isgetsetdescriptor(thing
):
1495 return 'getset descriptor %s.%s.%s' % (
1496 thing
.__objclass
__.__module
__, thing
.__objclass
__.__name
__,
1498 if inspect
.ismemberdescriptor(thing
):
1499 return 'member descriptor %s.%s.%s' % (
1500 thing
.__objclass
__.__module
__, thing
.__objclass
__.__name
__,
1502 if inspect
.isclass(thing
):
1503 return 'class ' + thing
.__name
__
1504 if inspect
.isfunction(thing
):
1505 return 'function ' + thing
.__name
__
1506 if inspect
.ismethod(thing
):
1507 return 'method ' + thing
.__name
__
1508 if type(thing
) is types
.InstanceType
:
1509 return 'instance of ' + thing
.__class
__.__name
__
1510 return type(thing
).__name
__
1512 def locate(path
, forceload
=0):
1513 """Locate an object by name or dotted path, importing as necessary."""
1514 parts
= [part
for part
in split(path
, '.') if part
]
1516 while n
< len(parts
):
1517 nextmodule
= safeimport(join(parts
[:n
+1], '.'), forceload
)
1518 if nextmodule
: module
, n
= nextmodule
, n
+ 1
1523 object = __builtin__
1524 for part
in parts
[n
:]:
1526 object = getattr(object, part
)
1527 except AttributeError:
1531 # --------------------------------------- interactive interpreter interface
1536 class _OldStyleClass
: pass
1537 _OLD_INSTANCE_TYPE
= type(_OldStyleClass())
1539 def resolve(thing
, forceload
=0):
1540 """Given an object or a path to an object, get the object and its name."""
1541 if isinstance(thing
, str):
1542 object = locate(thing
, forceload
)
1544 raise ImportError, 'no Python documentation found for %r' % thing
1545 return object, thing
1547 name
= getattr(thing
, '__name__', None)
1548 return thing
, name
if isinstance(name
, str) else None
1550 def render_doc(thing
, title
='Python Library Documentation: %s', forceload
=0):
1551 """Render text documentation, given an object or a path to an object."""
1552 object, name
= resolve(thing
, forceload
)
1553 desc
= describe(object)
1554 module
= inspect
.getmodule(object)
1555 if name
and '.' in name
:
1556 desc
+= ' in ' + name
[:name
.rfind('.')]
1557 elif module
and module
is not object:
1558 desc
+= ' in module ' + module
.__name
__
1559 if type(object) is _OLD_INSTANCE_TYPE
:
1560 # If the passed object is an instance of an old-style class,
1561 # document its available methods instead of its value.
1562 object = object.__class
__
1563 elif not (inspect
.ismodule(object) or
1564 inspect
.isclass(object) or
1565 inspect
.isroutine(object) or
1566 inspect
.isgetsetdescriptor(object) or
1567 inspect
.ismemberdescriptor(object) or
1568 isinstance(object, property)):
1569 # If the passed object is a piece of data or an instance,
1570 # document its available methods instead of its value.
1571 object = type(object)
1573 return title
% desc
+ '\n\n' + text
.document(object, name
)
1575 def doc(thing
, title
='Python Library Documentation: %s', forceload
=0):
1576 """Display text documentation, given an object or a path to an object."""
1578 pager(render_doc(thing
, title
, forceload
))
1579 except (ImportError, ErrorDuringImport
), value
:
1582 def writedoc(thing
, forceload
=0):
1583 """Write HTML documentation to a file in the current directory."""
1585 object, name
= resolve(thing
, forceload
)
1586 page
= html
.page(describe(object), html
.document(object, name
))
1587 file = open(name
+ '.html', 'w')
1590 print 'wrote', name
+ '.html'
1591 except (ImportError, ErrorDuringImport
), value
:
1594 def writedocs(dir, pkgpath
='', done
=None):
1595 """Write out HTML documentation for all modules in a directory tree."""
1596 if done
is None: done
= {}
1597 for importer
, modname
, ispkg
in pkgutil
.walk_packages([dir], pkgpath
):
1603 # These dictionaries map a topic name to either an alias, or a tuple
1604 # (label, seealso-items). The "label" is the label of the corresponding
1605 # section in the .rst file under Doc/ and an index into the dictionary
1606 # in pydoc_data/topics.py.
1608 # CAUTION: if you change one of these dictionaries, be sure to adapt the
1609 # list of needed labels in Doc/tools/pyspecific.py and
1610 # regenerate the pydoc_data/topics.py file by running
1612 # in Doc/ and copying the output file into the Lib/ directory.
1617 'assert': ('assert', ''),
1618 'break': ('break', 'while for'),
1619 'class': ('class', 'CLASSES SPECIALMETHODS'),
1620 'continue': ('continue', 'while for'),
1621 'def': ('function', ''),
1622 'del': ('del', 'BASICMETHODS'),
1624 'else': ('else', 'while for'),
1626 'exec': ('exec', ''),
1628 'for': ('for', 'break continue while'),
1630 'global': ('global', 'NAMESPACES'),
1631 'if': ('if', 'TRUTHVALUE'),
1632 'import': ('import', 'MODULES'),
1633 'in': ('in', 'SEQUENCEMETHODS2'),
1635 'lambda': ('lambda', 'FUNCTIONS'),
1638 'pass': ('pass', ''),
1639 'print': ('print', ''),
1640 'raise': ('raise', 'EXCEPTIONS'),
1641 'return': ('return', 'FUNCTIONS'),
1642 'try': ('try', 'EXCEPTIONS'),
1643 'while': ('while', 'break continue if TRUTHVALUE'),
1644 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
1645 'yield': ('yield', ''),
1647 # Either add symbols to this dictionary or to the symbols dictionary
1648 # directly: Whichever is easier. They are merged later.
1649 _symbols_inverse
= {
1650 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'),
1651 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&',
1652 '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),
1653 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'),
1654 'UNARY' : ('-', '~'),
1655 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=',
1656 '^=', '<<=', '>>=', '**=', '//='),
1657 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'),
1658 'COMPLEX' : ('j', 'J')
1661 '%': 'OPERATORS FORMATTING',
1663 ',': 'TUPLES LISTS FUNCTIONS',
1664 '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',
1666 ':': 'SLICINGS DICTIONARYLITERALS',
1669 '_': 'PRIVATENAMES',
1670 '__': 'PRIVATENAMES SPECIALMETHODS',
1672 '(': 'TUPLES FUNCTIONS CALLS',
1673 ')': 'TUPLES FUNCTIONS CALLS',
1674 '[': 'LISTS SUBSCRIPTS SLICINGS',
1675 ']': 'LISTS SUBSCRIPTS SLICINGS'
1677 for topic
, symbols_
in _symbols_inverse
.iteritems():
1678 for symbol
in symbols_
:
1679 topics
= symbols
.get(symbol
, topic
)
1680 if topic
not in topics
:
1681 topics
= topics
+ ' ' + topic
1682 symbols
[symbol
] = topics
1685 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS '
1686 'FUNCTIONS CLASSES MODULES FILES inspect'),
1687 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING '
1689 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'),
1690 'FORMATTING': ('formatstrings', 'OPERATORS'),
1691 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS '
1692 'FORMATTING TYPES'),
1693 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'),
1694 'INTEGER': ('integers', 'int range'),
1695 'FLOAT': ('floating', 'float math'),
1696 'COMPLEX': ('imaginary', 'complex cmath'),
1697 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING xrange LISTS'),
1698 'MAPPINGS': 'DICTIONARIES',
1699 'FUNCTIONS': ('typesfunctions', 'def TYPES'),
1700 'METHODS': ('typesmethods', 'class def CLASSES TYPES'),
1701 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'),
1702 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'),
1703 'FRAMEOBJECTS': 'TYPES',
1704 'TRACEBACKS': 'TYPES',
1705 'NONE': ('bltin-null-object', ''),
1706 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'),
1707 'FILES': ('bltin-file-objects', ''),
1708 'SPECIALATTRIBUTES': ('specialattrs', ''),
1709 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'),
1710 'MODULES': ('typesmodules', 'import'),
1711 'PACKAGES': 'import',
1712 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN '
1713 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER '
1714 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES '
1715 'LISTS DICTIONARIES BACKQUOTES'),
1716 'OPERATORS': 'EXPRESSIONS',
1717 'PRECEDENCE': 'EXPRESSIONS',
1718 'OBJECTS': ('objects', 'TYPES'),
1719 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '
1720 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS '
1721 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
1722 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'),
1723 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
1724 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
1725 'SEQUENCEMETHODS1': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 '
1727 'SEQUENCEMETHODS2': ('sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 '
1729 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),
1730 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT '
1732 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),
1733 'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'),
1734 'DYNAMICFEATURES': ('dynamic-features', ''),
1735 'SCOPING': 'NAMESPACES',
1736 'FRAMES': 'NAMESPACES',
1737 'EXCEPTIONS': ('exceptions', 'try except finally raise'),
1738 'COERCIONS': ('coercion-rules','CONVERSIONS'),
1739 'CONVERSIONS': ('conversions', 'COERCIONS'),
1740 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'),
1741 'SPECIALIDENTIFIERS': ('id-classes', ''),
1742 'PRIVATENAMES': ('atom-identifiers', ''),
1743 'LITERALS': ('atom-literals', 'STRINGS BACKQUOTES NUMBERS '
1744 'TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'),
1745 'TUPLES': 'SEQUENCES',
1746 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'),
1747 'LISTS': ('typesseq-mutable', 'LISTLITERALS'),
1748 'LISTLITERALS': ('lists', 'LISTS LITERALS'),
1749 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),
1750 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),
1751 'BACKQUOTES': ('string-conversions', 'repr str STRINGS LITERALS'),
1752 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr '
1753 'ATTRIBUTEMETHODS'),
1754 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'),
1755 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'),
1756 'CALLS': ('calls', 'EXPRESSIONS'),
1757 'POWER': ('power', 'EXPRESSIONS'),
1758 'UNARY': ('unary', 'EXPRESSIONS'),
1759 'BINARY': ('binary', 'EXPRESSIONS'),
1760 'SHIFTING': ('shifting', 'EXPRESSIONS'),
1761 'BITWISE': ('bitwise', 'EXPRESSIONS'),
1762 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'),
1763 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'),
1764 'ASSERTION': 'assert',
1765 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'),
1766 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'),
1768 'PRINTING': 'print',
1769 'RETURNING': 'return',
1770 'IMPORTING': 'import',
1771 'CONDITIONAL': 'if',
1772 'LOOPING': ('compound', 'for while break continue'),
1773 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'),
1774 'DEBUGGING': ('debugger', 'pdb'),
1775 'CONTEXTMANAGERS': ('context-managers', 'with'),
1778 def __init__(self
, input=None, output
=None):
1780 self
._output
= output
1782 input = property(lambda self
: self
._input
or sys
.stdin
)
1783 output
= property(lambda self
: self
._output
or sys
.stdout
)
1786 if inspect
.stack()[1][3] == '?':
1789 return '<pydoc.Helper instance>'
1791 _GoInteractive
= object()
1792 def __call__(self
, request
=_GoInteractive
):
1793 if request
is not self
._GoInteractive
:
1798 self
.output
.write('''
1799 You are now leaving help and returning to the Python interpreter.
1800 If you want to ask for help on a particular object directly from the
1801 interpreter, you can type "help(object)". Executing "help('string')"
1802 has the same effect as typing a particular string at the help> prompt.
1806 self
.output
.write('\n')
1809 request
= self
.getline('help> ')
1810 if not request
: break
1811 except (KeyboardInterrupt, EOFError):
1813 request
= strip(replace(request
, '"', '', "'", ''))
1814 if lower(request
) in ('q', 'quit'): break
1817 def getline(self
, prompt
):
1818 """Read one line, using raw_input when available."""
1819 if self
.input is sys
.stdin
:
1820 return raw_input(prompt
)
1822 self
.output
.write(prompt
)
1824 return self
.input.readline()
1826 def help(self
, request
):
1827 if type(request
) is type(''):
1828 request
= request
.strip()
1829 if request
== 'help': self
.intro()
1830 elif request
== 'keywords': self
.listkeywords()
1831 elif request
== 'symbols': self
.listsymbols()
1832 elif request
== 'topics': self
.listtopics()
1833 elif request
== 'modules': self
.listmodules()
1834 elif request
[:8] == 'modules ':
1835 self
.listmodules(split(request
)[1])
1836 elif request
in self
.symbols
: self
.showsymbol(request
)
1837 elif request
in self
.keywords
: self
.showtopic(request
)
1838 elif request
in self
.topics
: self
.showtopic(request
)
1839 elif request
: doc(request
, 'Help on %s:')
1840 elif isinstance(request
, Helper
): self()
1841 else: doc(request
, 'Help on %s:')
1842 self
.output
.write('\n')
1845 self
.output
.write('''
1846 Welcome to Python %s! This is the online help utility.
1848 If this is your first time using Python, you should definitely check out
1849 the tutorial on the Internet at http://docs.python.org/%s/tutorial/.
1851 Enter the name of any module, keyword, or topic to get help on writing
1852 Python programs and using Python modules. To quit this help utility and
1853 return to the interpreter, just type "quit".
1855 To get a list of available modules, keywords, or topics, type "modules",
1856 "keywords", or "topics". Each module also comes with a one-line summary
1857 of what it does; to list the modules whose summaries contain a given word
1858 such as "spam", type "modules spam".
1859 ''' % tuple([sys
.version
[:3]]*2))
1861 def list(self
, items
, columns
=4, width
=80):
1864 colw
= width
/ columns
1865 rows
= (len(items
) + columns
- 1) / columns
1866 for row
in range(rows
):
1867 for col
in range(columns
):
1868 i
= col
* rows
+ row
1870 self
.output
.write(items
[i
])
1871 if col
< columns
- 1:
1872 self
.output
.write(' ' + ' ' * (colw
-1 - len(items
[i
])))
1873 self
.output
.write('\n')
1875 def listkeywords(self
):
1876 self
.output
.write('''
1877 Here is a list of the Python keywords. Enter any keyword to get more help.
1880 self
.list(self
.keywords
.keys())
1882 def listsymbols(self
):
1883 self
.output
.write('''
1884 Here is a list of the punctuation symbols which Python assigns special meaning
1885 to. Enter any symbol to get more help.
1888 self
.list(self
.symbols
.keys())
1890 def listtopics(self
):
1891 self
.output
.write('''
1892 Here is a list of available topics. Enter any topic name to get more help.
1895 self
.list(self
.topics
.keys())
1897 def showtopic(self
, topic
, more_xrefs
=''):
1899 import pydoc_data
.topics
1901 self
.output
.write('''
1902 Sorry, topic and keyword documentation is not available because the
1903 module "pydoc_data.topics" could not be found.
1906 target
= self
.topics
.get(topic
, self
.keywords
.get(topic
))
1908 self
.output
.write('no documentation found for %s\n' % repr(topic
))
1910 if type(target
) is type(''):
1911 return self
.showtopic(target
, more_xrefs
)
1913 label
, xrefs
= target
1915 doc
= pydoc_data
.topics
.topics
[label
]
1917 self
.output
.write('no documentation found for %s\n' % repr(topic
))
1919 pager(strip(doc
) + '\n')
1921 xrefs
= (xrefs
or '') + ' ' + more_xrefs
1923 import StringIO
, formatter
1924 buffer = StringIO
.StringIO()
1925 formatter
.DumbWriter(buffer).send_flowing_data(
1926 'Related help topics: ' + join(split(xrefs
), ', ') + '\n')
1927 self
.output
.write('\n%s\n' % buffer.getvalue())
1929 def showsymbol(self
, symbol
):
1930 target
= self
.symbols
[symbol
]
1931 topic
, _
, xrefs
= target
.partition(' ')
1932 self
.showtopic(topic
, xrefs
)
1934 def listmodules(self
, key
=''):
1936 self
.output
.write('''
1937 Here is a list of matching modules. Enter any module name to get more help.
1942 self
.output
.write('''
1943 Please wait a moment while I gather a list of all available modules...
1947 def callback(path
, modname
, desc
, modules
=modules
):
1948 if modname
and modname
[-9:] == '.__init__':
1949 modname
= modname
[:-9] + ' (package)'
1950 if find(modname
, '.') < 0:
1951 modules
[modname
] = 1
1952 def onerror(modname
):
1953 callback(None, modname
, None)
1954 ModuleScanner().run(callback
, onerror
=onerror
)
1955 self
.list(modules
.keys())
1956 self
.output
.write('''
1957 Enter any module name to get more help. Or, type "modules spam" to search
1958 for modules whose descriptions contain the word "spam".
1964 """A generic tree iterator."""
1965 def __init__(self
, roots
, children
, descendp
):
1966 self
.roots
= roots
[:]
1968 self
.children
= children
1969 self
.descendp
= descendp
1975 root
= self
.roots
.pop(0)
1976 self
.state
= [(root
, self
.children(root
))]
1977 node
, children
= self
.state
[-1]
1981 child
= children
.pop(0)
1982 if self
.descendp(child
):
1983 self
.state
.append((child
, self
.children(child
)))
1987 class ModuleScanner
:
1988 """An interruptible scanner that searches module synopses."""
1990 def run(self
, callback
, key
=None, completer
=None, onerror
=None):
1991 if key
: key
= lower(key
)
1995 for modname
in sys
.builtin_module_names
:
1996 if modname
!= '__main__':
1999 callback(None, modname
, '')
2001 desc
= split(__import__(modname
).__doc
__ or '', '\n')[0]
2002 if find(lower(modname
+ ' - ' + desc
), key
) >= 0:
2003 callback(None, modname
, desc
)
2005 for importer
, modname
, ispkg
in pkgutil
.walk_packages(onerror
=onerror
):
2009 callback(None, modname
, '')
2011 loader
= importer
.find_module(modname
)
2012 if hasattr(loader
,'get_source'):
2014 desc
= source_synopsis(
2015 StringIO
.StringIO(loader
.get_source(modname
))
2017 if hasattr(loader
,'get_filename'):
2018 path
= loader
.get_filename(modname
)
2022 module
= loader
.load_module(modname
)
2023 desc
= module
.__doc
__.splitlines()[0] if module
.__doc
__ else ''
2024 path
= getattr(module
,'__file__',None)
2025 if find(lower(modname
+ ' - ' + desc
), key
) >= 0:
2026 callback(path
, modname
, desc
)
2032 """Print all the one-line module summaries that contain a substring."""
2033 def callback(path
, modname
, desc
):
2034 if modname
[-9:] == '.__init__':
2035 modname
= modname
[:-9] + ' (package)'
2036 print modname
, desc
and '- ' + desc
2037 def onerror(modname
):
2039 with warnings
.catch_warnings():
2040 warnings
.filterwarnings('ignore') # ignore problems during import
2041 ModuleScanner().run(callback
, key
, onerror
=onerror
)
2043 # --------------------------------------------------- web browser interface
2045 def serve(port
, callback
=None, completer
=None):
2046 import BaseHTTPServer
, mimetools
, select
2048 # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
2049 class Message(mimetools
.Message
):
2050 def __init__(self
, fp
, seekable
=1):
2051 Message
= self
.__class
__
2052 Message
.__bases
__[0].__bases
__[0].__init
__(self
, fp
, seekable
)
2053 self
.encodingheader
= self
.getheader('content-transfer-encoding')
2054 self
.typeheader
= self
.getheader('content-type')
2058 class DocHandler(BaseHTTPServer
.BaseHTTPRequestHandler
):
2059 def send_document(self
, title
, contents
):
2061 self
.send_response(200)
2062 self
.send_header('Content-Type', 'text/html')
2064 self
.wfile
.write(html
.page(title
, contents
))
2065 except IOError: pass
2069 if path
[-5:] == '.html': path
= path
[:-5]
2070 if path
[:1] == '/': path
= path
[1:]
2071 if path
and path
!= '.':
2073 obj
= locate(path
, forceload
=1)
2074 except ErrorDuringImport
, value
:
2075 self
.send_document(path
, html
.escape(str(value
)))
2078 self
.send_document(describe(obj
), html
.document(obj
, path
))
2080 self
.send_document(path
,
2081 'no Python documentation found for %s' % repr(path
))
2083 heading
= html
.heading(
2084 '<big><big><strong>Python: Index of Modules</strong></big></big>',
2085 '#ffffff', '#7799ee')
2086 def bltinlink(name
):
2087 return '<a href="%s.html">%s</a>' % (name
, name
)
2088 names
= filter(lambda x
: x
!= '__main__',
2089 sys
.builtin_module_names
)
2090 contents
= html
.multicolumn(names
, bltinlink
)
2091 indices
= ['<p>' + html
.bigsection(
2092 'Built-in Modules', '#ffffff', '#ee77aa', contents
)]
2095 for dir in sys
.path
:
2096 indices
.append(html
.index(dir, seen
))
2097 contents
= heading
+ join(indices
) + '''<p align=right>
2098 <font color="#909090" face="helvetica, arial"><strong>
2099 pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''
2100 self
.send_document('Index of Modules', contents
)
2102 def log_message(self
, *args
): pass
2104 class DocServer(BaseHTTPServer
.HTTPServer
):
2105 def __init__(self
, port
, callback
):
2107 self
.address
= (host
, port
)
2108 self
.callback
= callback
2109 self
.base
.__init
__(self
, self
.address
, self
.handler
)
2111 def serve_until_quit(self
):
2114 while not self
.quit
:
2115 rd
, wr
, ex
= select
.select([self
.socket
.fileno()], [], [], 1)
2116 if rd
: self
.handle_request()
2118 def server_activate(self
):
2119 self
.base
.server_activate(self
)
2120 self
.url
= 'http://%s:%d/' % (self
.address
[0], self
.server_port
)
2121 if self
.callback
: self
.callback(self
)
2123 DocServer
.base
= BaseHTTPServer
.HTTPServer
2124 DocServer
.handler
= DocHandler
2125 DocHandler
.MessageClass
= Message
2128 DocServer(port
, callback
).serve_until_quit()
2129 except (KeyboardInterrupt, select
.error
):
2132 if completer
: completer()
2134 # ----------------------------------------------------- graphical interface
2137 """Graphical interface (starts web server and pops up a control window)."""
2139 def __init__(self
, window
, port
=7464):
2140 self
.window
= window
2145 self
.server_frm
= Tkinter
.Frame(window
)
2146 self
.title_lbl
= Tkinter
.Label(self
.server_frm
,
2147 text
='Starting server...\n ')
2148 self
.open_btn
= Tkinter
.Button(self
.server_frm
,
2149 text
='open browser', command
=self
.open, state
='disabled')
2150 self
.quit_btn
= Tkinter
.Button(self
.server_frm
,
2151 text
='quit serving', command
=self
.quit
, state
='disabled')
2153 self
.search_frm
= Tkinter
.Frame(window
)
2154 self
.search_lbl
= Tkinter
.Label(self
.search_frm
, text
='Search for')
2155 self
.search_ent
= Tkinter
.Entry(self
.search_frm
)
2156 self
.search_ent
.bind('<Return>', self
.search
)
2157 self
.stop_btn
= Tkinter
.Button(self
.search_frm
,
2158 text
='stop', pady
=0, command
=self
.stop
, state
='disabled')
2159 if sys
.platform
== 'win32':
2160 # Trying to hide and show this button crashes under Windows.
2161 self
.stop_btn
.pack(side
='right')
2163 self
.window
.title('pydoc')
2164 self
.window
.protocol('WM_DELETE_WINDOW', self
.quit
)
2165 self
.title_lbl
.pack(side
='top', fill
='x')
2166 self
.open_btn
.pack(side
='left', fill
='x', expand
=1)
2167 self
.quit_btn
.pack(side
='right', fill
='x', expand
=1)
2168 self
.server_frm
.pack(side
='top', fill
='x')
2170 self
.search_lbl
.pack(side
='left')
2171 self
.search_ent
.pack(side
='right', fill
='x', expand
=1)
2172 self
.search_frm
.pack(side
='top', fill
='x')
2173 self
.search_ent
.focus_set()
2175 font
= ('helvetica', sys
.platform
== 'win32' and 8 or 10)
2176 self
.result_lst
= Tkinter
.Listbox(window
, font
=font
, height
=6)
2177 self
.result_lst
.bind('<Button-1>', self
.select
)
2178 self
.result_lst
.bind('<Double-Button-1>', self
.goto
)
2179 self
.result_scr
= Tkinter
.Scrollbar(window
,
2180 orient
='vertical', command
=self
.result_lst
.yview
)
2181 self
.result_lst
.config(yscrollcommand
=self
.result_scr
.set)
2183 self
.result_frm
= Tkinter
.Frame(window
)
2184 self
.goto_btn
= Tkinter
.Button(self
.result_frm
,
2185 text
='go to selected', command
=self
.goto
)
2186 self
.hide_btn
= Tkinter
.Button(self
.result_frm
,
2187 text
='hide results', command
=self
.hide
)
2188 self
.goto_btn
.pack(side
='left', fill
='x', expand
=1)
2189 self
.hide_btn
.pack(side
='right', fill
='x', expand
=1)
2191 self
.window
.update()
2192 self
.minwidth
= self
.window
.winfo_width()
2193 self
.minheight
= self
.window
.winfo_height()
2194 self
.bigminheight
= (self
.server_frm
.winfo_reqheight() +
2195 self
.search_frm
.winfo_reqheight() +
2196 self
.result_lst
.winfo_reqheight() +
2197 self
.result_frm
.winfo_reqheight())
2198 self
.bigwidth
, self
.bigheight
= self
.minwidth
, self
.bigminheight
2200 self
.window
.wm_geometry('%dx%d' % (self
.minwidth
, self
.minheight
))
2201 self
.window
.wm_minsize(self
.minwidth
, self
.minheight
)
2202 self
.window
.tk
.willdispatch()
2206 target
=serve
, args
=(port
, self
.ready
, self
.quit
)).start()
2208 def ready(self
, server
):
2209 self
.server
= server
2210 self
.title_lbl
.config(
2211 text
='Python documentation server at\n' + server
.url
)
2212 self
.open_btn
.config(state
='normal')
2213 self
.quit_btn
.config(state
='normal')
2215 def open(self
, event
=None, url
=None):
2216 url
= url
or self
.server
.url
2219 webbrowser
.open(url
)
2220 except ImportError: # pre-webbrowser.py compatibility
2221 if sys
.platform
== 'win32':
2222 os
.system('start "%s"' % url
)
2224 rc
= os
.system('netscape -remote "openURL(%s)" &' % url
)
2225 if rc
: os
.system('netscape "%s" &' % url
)
2227 def quit(self
, event
=None):
2229 self
.server
.quit
= 1
2232 def search(self
, event
=None):
2233 key
= self
.search_ent
.get()
2234 self
.stop_btn
.pack(side
='right')
2235 self
.stop_btn
.config(state
='normal')
2236 self
.search_lbl
.config(text
='Searching for "%s"...' % key
)
2237 self
.search_ent
.forget()
2238 self
.search_lbl
.pack(side
='left')
2239 self
.result_lst
.delete(0, 'end')
2240 self
.goto_btn
.config(state
='disabled')
2245 self
.scanner
.quit
= 1
2246 self
.scanner
= ModuleScanner()
2247 threading
.Thread(target
=self
.scanner
.run
,
2248 args
=(self
.update
, key
, self
.done
)).start()
2250 def update(self
, path
, modname
, desc
):
2251 if modname
[-9:] == '.__init__':
2252 modname
= modname
[:-9] + ' (package)'
2253 self
.result_lst
.insert('end',
2254 modname
+ ' - ' + (desc
or '(no description)'))
2256 def stop(self
, event
=None):
2258 self
.scanner
.quit
= 1
2263 self
.search_lbl
.config(text
='Search for')
2264 self
.search_lbl
.pack(side
='left')
2265 self
.search_ent
.pack(side
='right', fill
='x', expand
=1)
2266 if sys
.platform
!= 'win32': self
.stop_btn
.forget()
2267 self
.stop_btn
.config(state
='disabled')
2269 def select(self
, event
=None):
2270 self
.goto_btn
.config(state
='normal')
2272 def goto(self
, event
=None):
2273 selection
= self
.result_lst
.curselection()
2275 modname
= split(self
.result_lst
.get(selection
[0]))[0]
2276 self
.open(url
=self
.server
.url
+ modname
+ '.html')
2279 if not self
.expanded
: return
2280 self
.result_frm
.forget()
2281 self
.result_scr
.forget()
2282 self
.result_lst
.forget()
2283 self
.bigwidth
= self
.window
.winfo_width()
2284 self
.bigheight
= self
.window
.winfo_height()
2285 self
.window
.wm_geometry('%dx%d' % (self
.minwidth
, self
.minheight
))
2286 self
.window
.wm_minsize(self
.minwidth
, self
.minheight
)
2290 if self
.expanded
: return
2291 self
.result_frm
.pack(side
='bottom', fill
='x')
2292 self
.result_scr
.pack(side
='right', fill
='y')
2293 self
.result_lst
.pack(side
='top', fill
='both', expand
=1)
2294 self
.window
.wm_geometry('%dx%d' % (self
.bigwidth
, self
.bigheight
))
2295 self
.window
.wm_minsize(self
.minwidth
, self
.bigminheight
)
2298 def hide(self
, event
=None):
2305 # Tk will crash if pythonw.exe has an XP .manifest
2306 # file and the root has is not destroyed explicitly.
2307 # If the problem is ever fixed in Tk, the explicit
2314 except KeyboardInterrupt:
2317 # -------------------------------------------------- command-line interface
2320 return isinstance(x
, str) and find(x
, os
.sep
) >= 0
2323 """Command-line interface (looks at sys.argv to decide what to do)."""
2325 class BadUsage
: pass
2327 # Scripts don't get the current directory in their path by default
2328 # unless they are run with the '-m' switch
2329 if '' not in sys
.path
:
2330 scriptdir
= os
.path
.dirname(sys
.argv
[0])
2331 if scriptdir
in sys
.path
:
2332 sys
.path
.remove(scriptdir
)
2333 sys
.path
.insert(0, '.')
2336 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'gk:p:w')
2339 for opt
, val
in opts
:
2352 print 'pydoc server ready at %s' % server
.url
2354 print 'pydoc server stopped'
2355 serve(port
, ready
, stopped
)
2360 if not args
: raise BadUsage
2362 if ispath(arg
) and not os
.path
.exists(arg
):
2363 print 'file %r does not exist' % arg
2366 if ispath(arg
) and os
.path
.isfile(arg
):
2367 arg
= importfile(arg
)
2369 if ispath(arg
) and os
.path
.isdir(arg
):
2375 except ErrorDuringImport
, value
:
2378 except (getopt
.error
, BadUsage
):
2379 cmd
= os
.path
.basename(sys
.argv
[0])
2380 print """pydoc - the Python documentation tool
2383 Show text documentation on something. <name> may be the name of a
2384 Python keyword, topic, function, module, or package, or a dotted
2385 reference to a class or function within a module or module in a
2386 package. If <name> contains a '%s', it is used as the path to a
2387 Python source file to document. If name is 'keywords', 'topics',
2388 or 'modules', a listing of these things is displayed.
2391 Search for a keyword in the synopsis lines of all available modules.
2394 Start an HTTP server on the given port on the local machine. Port
2395 number 0 can be used to get an arbitrary unused port.
2398 Pop up a graphical interface for finding and serving documentation.
2401 Write out the HTML documentation for a module to a file in the current
2402 directory. If <name> contains a '%s', it is treated as a filename; if
2403 it names a directory, documentation is written for all the contents.
2404 """ % (cmd
, os
.sep
, cmd
, cmd
, cmd
, cmd
, os
.sep
)
2406 if __name__
== '__main__': cli()