]>
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 -*-
4 # Module 'pydoc' -- Generate Python documentation in HTML or text for interactive use.
6 # Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
7 # Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
8 # This program and the accompanying materials are licensed and made available under
9 # the terms and conditions of the BSD License that accompanies this distribution.
10 # The full text of the license may be found at
11 # http://opensource.org/licenses/bsd-license.
13 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 """Generate Python documentation in HTML or text for interactive use.
18 In the Python interpreter, do "from pydoc import help" to provide online
19 help. Calling help(thing) on a Python object documents the object.
21 Or, at the shell command line outside of Python:
23 Run "pydoc <name>" to show documentation on something. <name> may be
24 the name of a function, module, package, or a dotted reference to a
25 class or function within a module or module in a package. If the
26 argument contains a path segment delimiter (e.g. slash on Unix,
27 backslash on Windows) it is treated as the path to a Python source file.
29 Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines
30 of all available modules.
32 Run "pydoc -p <port>" to start an HTTP server on a given port on the
33 local machine to generate documentation web pages. Port number 0 can be
34 used to get an arbitrary unused port.
36 For platforms without a command line, "pydoc -g" starts the HTTP server
37 and also pops up a little window for controlling it.
39 Run "pydoc -w <name>" to write out the HTML documentation for a module
40 to a file named "<name>.html".
42 Module docs for core modules are assumed to be in
44 http://docs.python.org/library/
46 This can be overridden by setting the PYTHONDOCS environment variable
47 to a different URL or to a local directory containing the Library
48 Reference Manual pages.
51 __author__
= "Ka-Ping Yee <ping@lfw.org>"
52 __date__
= "26 February 2001"
54 __version__
= "$Revision: 88564 $"
55 __credits__
= """Guido van Rossum, for an excellent programming language.
56 Tommy Burnette, the original creator of manpy.
57 Paul Prescod, for all his work on onlinehelp.
58 Richard Chamberlain, for the first implementation of textdoc.
61 # Known bugs that can't be fixed here:
62 # - imp.load_module() cannot be prevented from clobbering existing
63 # loaded modules, so calling synopsis() on a binary module file
64 # changes the contents of any existing module with the same name.
65 # - If the __file__ attribute on a module is a relative path and
66 # the current directory is changed with os.chdir(), an incorrect
67 # path will be displayed.
69 import sys
, imp
, os
, re
, types
, inspect
, __builtin__
, pkgutil
, warnings
71 from string
import expandtabs
, find
, join
, lower
, split
, strip
, rfind
, rstrip
72 from traceback
import extract_tb
74 from collections
import deque
76 # Python 2.3 compatibility
81 # --------------------------------------------------------- common routines
84 """Convert sys.path into a list of absolute, existing, unique paths."""
88 dir = os
.path
.abspath(dir or '.')
89 normdir
= os
.path
.normcase(dir)
90 if normdir
not in normdirs
and os
.path
.isdir(dir):
92 normdirs
.append(normdir
)
96 """Get the doc string or comments for an object."""
97 result
= inspect
.getdoc(object) or inspect
.getcomments(object)
98 result
= _encode(result
)
99 return result
and re
.sub('^ *\n', '', rstrip(result
)) or ''
102 """Split a doc string into a synopsis line (if any) and the rest."""
103 lines
= split(strip(doc
), '\n')
106 elif len(lines
) >= 2 and not rstrip(lines
[1]):
107 return lines
[0], join(lines
[2:], '\n')
108 return '', join(lines
, '\n')
110 def classname(object, modname
):
111 """Get a class name and qualify it with a module name if necessary."""
112 name
= object.__name
__
113 if object.__module
__ != modname
:
114 name
= object.__module
__ + '.' + name
118 """Check if an object is of a type that probably means it's data."""
119 return not (inspect
.ismodule(object) or inspect
.isclass(object) or
120 inspect
.isroutine(object) or inspect
.isframe(object) or
121 inspect
.istraceback(object) or inspect
.iscode(object))
123 def replace(text
, *pairs
):
124 """Do a series of global replacements on a string."""
126 text
= join(split(text
, pairs
[0]), pairs
[1])
130 def cram(text
, maxlen
):
131 """Omit part of a string if needed to make it fit in a maximum length."""
132 if len(text
) > maxlen
:
133 pre
= max(0, (maxlen
-3)//2)
134 post
= max(0, maxlen
-3-pre
)
135 return text
[:pre
] + '...' + text
[len(text
)-post
:]
138 _re_stripid
= re
.compile(r
' at 0x[0-9a-f]{6,16}(>+)$', re
.IGNORECASE
)
140 """Remove the hexadecimal id from a Python object representation."""
141 # The behaviour of %p is implementation-dependent in terms of case.
142 return _re_stripid
.sub(r
'\1', text
)
144 def _is_some_method(obj
):
145 return inspect
.ismethod(obj
) or inspect
.ismethoddescriptor(obj
)
149 for key
, value
in inspect
.getmembers(cl
, _is_some_method
):
151 for base
in cl
.__bases
__:
152 methods
.update(allmethods(base
)) # all your base are belong to us
153 for key
in methods
.keys():
154 methods
[key
] = getattr(cl
, key
)
157 def _split_list(s
, predicate
):
158 """Split sequence s via predicate, and return pair ([true], [false]).
160 The return value is a 2-tuple of lists,
161 ([x for x in s if predicate(x)],
162 [x for x in s if not predicate(x)])
174 def visiblename(name
, all
=None, obj
=None):
175 """Decide whether to show documentation on a variable."""
176 # Certain special names are redundant.
177 _hidden_names
= ('__builtins__', '__doc__', '__file__', '__path__',
178 '__module__', '__name__', '__slots__', '__package__')
179 if name
in _hidden_names
: return 0
180 # Private names are hidden, but special names are displayed.
181 if name
.startswith('__') and name
.endswith('__'): return 1
182 # Namedtuples have public fields and methods with a single leading underscore
183 if name
.startswith('_') and hasattr(obj
, '_fields'):
186 # only document that which the programmer exported in __all__
189 return not name
.startswith('_')
191 def classify_class_attrs(object):
192 """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
194 name
, kind
, cls
, value
= data
195 if inspect
.isdatadescriptor(value
):
196 kind
= 'data descriptor'
197 return name
, kind
, cls
, value
198 return map(fixup
, inspect
.classify_class_attrs(object))
200 # ----------------------------------------------------- Unicode support helpers
205 # If Python is built without Unicode support, the unicode type
206 # will not exist. Fake one that nothing will match, and make
207 # the _encode function that do nothing.
208 class _unicode(object):
211 def _encode(text
, encoding
='ascii'):
215 _encoding
= locale
.getpreferredencoding()
217 def _encode(text
, encoding
=None):
218 if isinstance(text
, unicode):
219 return text
.encode(encoding
or _encoding
, 'xmlcharrefreplace')
224 # Ensure that we have an encoded (binary) string representation of obj,
225 # even if it is a unicode string.
226 if isinstance(obj
, _unicode
):
227 return obj
.encode(_encoding
, 'xmlcharrefreplace')
230 # ----------------------------------------------------- module manipulation
233 """Guess whether a path refers to a package directory."""
234 if os
.path
.isdir(path
):
235 for ext
in ('.py', '.pyc', '.pyo'):
236 if os
.path
.isfile(os
.path
.join(path
, '__init__' + ext
)):
240 def source_synopsis(file):
241 line
= file.readline()
242 while line
[:1] == '#' or not strip(line
):
243 line
= file.readline()
246 if line
[:4] == 'r"""': line
= line
[1:]
247 if line
[:3] == '"""':
249 if line
[-1:] == '\\': line
= line
[:-1]
250 while not strip(line
):
251 line
= file.readline()
253 result
= strip(split(line
, '"""')[0])
257 def synopsis(filename
, cache
={}):
258 """Get the one-line summary out of a module file."""
259 mtime
= os
.stat(filename
).st_mtime
260 lastupdate
, result
= cache
.get(filename
, (None, None))
261 if lastupdate
is None or lastupdate
< mtime
:
262 info
= inspect
.getmoduleinfo(filename
)
264 file = open(filename
)
266 # module can't be opened, so skip it
268 if info
and 'b' in info
[2]: # binary modules have to be imported
269 try: module
= imp
.load_module('__temp__', file, filename
, info
[1:])
271 result
= module
.__doc
__.splitlines()[0] if module
.__doc
__ else None
272 del sys
.modules
['__temp__']
273 else: # text modules can be directly examined
274 result
= source_synopsis(file)
276 cache
[filename
] = (mtime
, result
)
279 class ErrorDuringImport(Exception):
280 """Errors that occurred while trying to import something to document it."""
281 def __init__(self
, filename
, exc_info
):
282 exc
, value
, tb
= exc_info
283 self
.filename
= filename
290 if type(exc
) is types
.ClassType
:
292 return 'problem in %s - %s: %s' % (self
.filename
, exc
, self
.value
)
294 def importfile(path
):
295 """Import a Python source file or compiled file given its path."""
296 magic
= imp
.get_magic()
297 file = open(path
, 'r')
298 if file.read(len(magic
)) == magic
:
299 kind
= imp
.PY_COMPILED
303 filename
= os
.path
.basename(path
)
304 name
, ext
= os
.path
.splitext(filename
)
305 file = open(path
, 'r')
307 module
= imp
.load_module(name
, file, path
, (ext
, 'r', kind
))
309 raise ErrorDuringImport(path
, sys
.exc_info())
313 def safeimport(path
, forceload
=0, cache
={}):
314 """Import a module; handle errors; return None if the module isn't found.
316 If the module *is* found but an exception occurs, it's wrapped in an
317 ErrorDuringImport exception and reraised. Unlike __import__, if a
318 package path is specified, the module at the end of the path is returned,
319 not the package at the beginning. If the optional 'forceload' argument
320 is 1, we reload the module from disk (unless it's a dynamic extension)."""
322 # If forceload is 1 and the module has been previously loaded from
323 # disk, we always have to reload the module. Checking the file's
324 # mtime isn't good enough (e.g. the module could contain a class
325 # that inherits from another module that has changed).
326 if forceload
and path
in sys
.modules
:
327 if path
not in sys
.builtin_module_names
:
328 # Avoid simply calling reload() because it leaves names in
329 # the currently loaded module lying around if they're not
330 # defined in the new source file. Instead, remove the
331 # module from sys.modules and re-import. Also remove any
332 # submodules because they won't appear in the newly loaded
333 # module's namespace if they're already in sys.modules.
334 subs
= [m
for m
in sys
.modules
if m
.startswith(path
+ '.')]
335 for key
in [path
] + subs
:
336 # Prevent garbage collection.
337 cache
[key
] = sys
.modules
[key
]
339 module
= __import__(path
)
341 # Did the error occur before or after the module was found?
342 (exc
, value
, tb
) = info
= sys
.exc_info()
343 if path
in sys
.modules
:
344 # An error occurred while executing the imported module.
345 raise ErrorDuringImport(sys
.modules
[path
].__file
__, info
)
346 elif exc
is SyntaxError:
347 # A SyntaxError occurred before we could execute the module.
348 raise ErrorDuringImport(value
.filename
, info
)
349 elif exc
is ImportError and extract_tb(tb
)[-1][2]=='safeimport':
350 # The import error occurred directly in this function,
351 # which means there is no such module in the path.
354 # Some other error occurred during the importing process.
355 raise ErrorDuringImport(path
, sys
.exc_info())
356 for part
in split(path
, '.')[1:]:
357 try: module
= getattr(module
, part
)
358 except AttributeError: return None
361 # ---------------------------------------------------- formatter base class
364 def document(self
, object, name
=None, *args
):
365 """Generate documentation for an object."""
366 args
= (object, name
) + args
367 # 'try' clause is to attempt to handle the possibility that inspect
368 # identifies something in a way that pydoc itself has issues handling;
369 # think 'super' and how it is a descriptor (which raises the exception
370 # by lacking a __name__ attribute) and an instance.
371 if inspect
.isgetsetdescriptor(object): return self
.docdata(*args
)
372 if inspect
.ismemberdescriptor(object): return self
.docdata(*args
)
374 if inspect
.ismodule(object): return self
.docmodule(*args
)
375 if inspect
.isclass(object): return self
.docclass(*args
)
376 if inspect
.isroutine(object): return self
.docroutine(*args
)
377 except AttributeError:
379 if isinstance(object, property): return self
.docproperty(*args
)
380 return self
.docother(*args
)
382 def fail(self
, object, name
=None, *args
):
383 """Raise an exception for unimplemented types."""
384 message
= "don't know how to document object%s of type %s" % (
385 name
and ' ' + repr(name
), type(object).__name
__)
386 raise TypeError, message
388 docmodule
= docclass
= docroutine
= docother
= docproperty
= docdata
= fail
390 def getdocloc(self
, object):
391 """Return the location of module docs or None"""
394 file = inspect
.getabsfile(object)
398 docloc
= os
.environ
.get("PYTHONDOCS",
399 "http://docs.python.org/library")
400 basedir
= os
.path
.join(sys
.exec_prefix
, "lib",
401 "python"+sys
.version
[0:3])
402 if (isinstance(object, type(os
)) and
403 (object.__name
__ in ('errno', 'exceptions', 'gc', 'imp',
404 'marshal', 'posix', 'signal', 'sys',
405 'thread', 'zipimport') or
406 (file.startswith(basedir
) and
407 not file.startswith(os
.path
.join(basedir
, 'site-packages')))) and
408 object.__name
__ not in ('xml.etree', 'test.pydoc_mod')):
409 if docloc
.startswith("http://"):
410 docloc
= "%s/%s" % (docloc
.rstrip("/"), object.__name
__)
412 docloc
= os
.path
.join(docloc
, object.__name
__ + ".html")
417 # -------------------------------------------- HTML documentation generator
419 class HTMLRepr(Repr
):
420 """Class for safely making an HTML representation of a Python object."""
423 self
.maxlist
= self
.maxtuple
= 20
425 self
.maxstring
= self
.maxother
= 100
427 def escape(self
, text
):
428 return replace(text
, '&', '&', '<', '<', '>', '>')
430 def repr(self
, object):
431 return Repr
.repr(self
, object)
433 def repr1(self
, x
, level
):
434 if hasattr(type(x
), '__name__'):
435 methodname
= 'repr_' + join(split(type(x
).__name
__), '_')
436 if hasattr(self
, methodname
):
437 return getattr(self
, methodname
)(x
, level
)
438 return self
.escape(cram(stripid(repr(x
)), self
.maxother
))
440 def repr_string(self
, x
, level
):
441 test
= cram(x
, self
.maxstring
)
442 testrepr
= repr(test
)
443 if '\\' in test
and '\\' not in replace(testrepr
, r
'\\', ''):
444 # Backslashes are only literal in the string and are never
445 # needed to make any special characters, so show a raw string.
446 return 'r' + testrepr
[0] + self
.escape(test
) + testrepr
[0]
447 return re
.sub(r
'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
448 r'<font color="#c040c0">\1</font>',
449 self
.escape(testrepr
))
451 repr_str
= repr_string
453 def repr_instance(self
, x
, level
):
455 return self
.escape(cram(stripid(repr(x
)), self
.maxstring
))
457 return self
.escape('<%s instance>' % x
.__class
__.__name
__)
459 repr_unicode
= repr_string
462 """Formatter class for HTML documentation."""
464 # ------------------------------------------- HTML formatting utilities
466 _repr_instance
= HTMLRepr()
467 repr = _repr_instance
.repr
468 escape
= _repr_instance
.escape
470 def page(self
, title
, contents
):
471 """Format an HTML page."""
473 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
474 <html><head><title>Python: %s</title>
475 <meta charset="utf-8">
476 </head><body bgcolor="#f0f0f8">
478 </body></html>''' % (title
, contents
), 'ascii')
480 def heading(self
, title
, fgcol
, bgcol
, extras
=''):
481 """Format a page heading."""
483 <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
485 <td valign=bottom> <br>
486 <font color="%s" face="helvetica, arial"> <br>%s</font></td
487 ><td align=right valign=bottom
488 ><font color="%s" face="helvetica, arial">%s</font></td></tr></table>
489 ''' % (bgcol
, fgcol
, title
, fgcol
, extras
or ' ')
491 def section(self
, title
, fgcol
, bgcol
, contents
, width
=6,
492 prelude
='', marginalia
=None, gap
=' '):
493 """Format a section with a heading."""
494 if marginalia
is None:
495 marginalia
= '<tt>' + ' ' * width
+ '</tt>'
497 <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
499 <td colspan=3 valign=bottom> <br>
500 <font color="%s" face="helvetica, arial">%s</font></td></tr>
501 ''' % (bgcol
, fgcol
, title
)
503 result
= result
+ '''
504 <tr bgcolor="%s"><td rowspan=2>%s</td>
505 <td colspan=2>%s</td></tr>
506 <tr><td>%s</td>''' % (bgcol
, marginalia
, prelude
, gap
)
508 result
= result
+ '''
509 <tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol
, marginalia
, gap
)
511 return result
+ '\n<td width="100%%">%s</td></tr></table>' % contents
513 def bigsection(self
, title
, *args
):
514 """Format a section with a big heading."""
515 title
= '<big><strong>%s</strong></big>' % title
516 return self
.section(title
, *args
)
518 def preformat(self
, text
):
519 """Format literal preformatted text."""
520 text
= self
.escape(expandtabs(text
))
521 return replace(text
, '\n\n', '\n \n', '\n\n', '\n \n',
522 ' ', ' ', '\n', '<br>\n')
524 def multicolumn(self
, list, format
, cols
=4):
525 """Format a list of items into a multi-column list."""
527 rows
= (len(list)+cols
-1)//cols
528 for col
in range(cols
):
529 result
= result
+ '<td width="%d%%" valign=top>' % (100//cols
)
530 for i
in range(rows
*col
, rows
*col
+rows
):
532 result
= result
+ format(list[i
]) + '<br>\n'
533 result
= result
+ '</td>'
534 return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
536 def grey(self
, text
): return '<font color="#909090">%s</font>' % text
538 def namelink(self
, name
, *dicts
):
539 """Make a link for an identifier, given name-to-URL mappings."""
542 return '<a href="%s">%s</a>' % (dict[name
], name
)
545 def classlink(self
, object, modname
):
546 """Make a link for a class."""
547 name
, module
= object.__name
__, sys
.modules
.get(object.__module
__)
548 if hasattr(module
, name
) and getattr(module
, name
) is object:
549 return '<a href="%s.html#%s">%s</a>' % (
550 module
.__name
__, name
, classname(object, modname
))
551 return classname(object, modname
)
553 def modulelink(self
, object):
554 """Make a link for a module."""
555 return '<a href="%s.html">%s</a>' % (object.__name
__, object.__name
__)
557 def modpkglink(self
, data
):
558 """Make a link for a module or package to display in an index."""
559 name
, path
, ispackage
, shadowed
= data
561 return self
.grey(name
)
563 url
= '%s.%s.html' % (path
, name
)
565 url
= '%s.html' % name
567 text
= '<strong>%s</strong> (package)' % name
570 return '<a href="%s">%s</a>' % (url
, text
)
572 def markup(self
, text
, escape
=None, funcs
={}, classes
={}, methods
={}):
573 """Mark up some plain text, given a context of symbols to look for.
574 Each context dictionary maps object names to anchor names."""
575 escape
= escape
or self
.escape
578 pattern
= re
.compile(r
'\b((http|ftp)://\S+[\w/]|'
583 match
= pattern
.search(text
, here
)
585 start
, end
= match
.span()
586 results
.append(escape(text
[here
:start
]))
588 all
, scheme
, rfc
, pep
, selfdot
, name
= match
.groups()
590 url
= escape(all
).replace('"', '"')
591 results
.append('<a href="%s">%s</a>' % (url
, url
))
593 url
= 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc
)
594 results
.append('<a href="%s">%s</a>' % (url
, escape(all
)))
596 url
= 'http://www.python.org/dev/peps/pep-%04d/' % int(pep
)
597 results
.append('<a href="%s">%s</a>' % (url
, escape(all
)))
599 # Create a link for methods like 'self.method(...)'
600 # and use <strong> for attributes like 'self.attr'
601 if text
[end
:end
+1] == '(':
602 results
.append('self.' + self
.namelink(name
, methods
))
604 results
.append('self.<strong>%s</strong>' % name
)
605 elif text
[end
:end
+1] == '(':
606 results
.append(self
.namelink(name
, methods
, funcs
, classes
))
608 results
.append(self
.namelink(name
, classes
))
610 results
.append(escape(text
[here
:]))
611 return join(results
, '')
613 # ---------------------------------------------- type-specific routines
615 def formattree(self
, tree
, modname
, parent
=None):
616 """Produce HTML for a class tree as given by inspect.getclasstree()."""
619 if type(entry
) is type(()):
621 result
= result
+ '<dt><font face="helvetica, arial">'
622 result
= result
+ self
.classlink(c
, modname
)
623 if bases
and bases
!= (parent
,):
626 parents
.append(self
.classlink(base
, modname
))
627 result
= result
+ '(' + join(parents
, ', ') + ')'
628 result
= result
+ '\n</font></dt>'
629 elif type(entry
) is type([]):
630 result
= result
+ '<dd>\n%s</dd>\n' % self
.formattree(
632 return '<dl>\n%s</dl>\n' % result
634 def docmodule(self
, object, name
=None, mod
=None, *ignored
):
635 """Produce HTML documentation for a module object."""
636 name
= object.__name
__ # ignore the passed-in name
639 except AttributeError:
641 parts
= split(name
, '.')
643 for i
in range(len(parts
)-1):
645 '<a href="%s.html"><font color="#ffffff">%s</font></a>' %
646 (join(parts
[:i
+1], '.'), parts
[i
]))
647 linkedname
= join(links
+ parts
[-1:], '.')
648 head
= '<big><big><strong>%s</strong></big></big>' % linkedname
650 path
= inspect
.getabsfile(object)
652 if sys
.platform
== 'win32':
654 url
= nturl2path
.pathname2url(path
)
655 filelink
= '<a href="file:%s">%s</a>' % (url
, path
)
657 filelink
= '(built-in)'
659 if hasattr(object, '__version__'):
660 version
= _binstr(object.__version
__)
661 if version
[:11] == '$' + 'Revision: ' and version
[-1:] == '$':
662 version
= strip(version
[11:-1])
663 info
.append('version %s' % self
.escape(version
))
664 if hasattr(object, '__date__'):
665 info
.append(self
.escape(_binstr(object.__date
__)))
667 head
= head
+ ' (%s)' % join(info
, ', ')
668 docloc
= self
.getdocloc(object)
669 if docloc
is not None:
670 docloc
= '<br><a href="%(docloc)s">Module Docs</a>' % locals()
673 result
= self
.heading(
674 head
, '#ffffff', '#7799ee',
675 '<a href=".">index</a><br>' + filelink
+ docloc
)
677 modules
= inspect
.getmembers(object, inspect
.ismodule
)
679 classes
, cdict
= [], {}
680 for key
, value
in inspect
.getmembers(object, inspect
.isclass
):
681 # if __all__ exists, believe it. Otherwise use old heuristic.
682 if (all
is not None or
683 (inspect
.getmodule(value
) or object) is object):
684 if visiblename(key
, all
, object):
685 classes
.append((key
, value
))
686 cdict
[key
] = cdict
[value
] = '#' + key
687 for key
, value
in classes
:
688 for base
in value
.__bases
__:
689 key
, modname
= base
.__name
__, base
.__module
__
690 module
= sys
.modules
.get(modname
)
691 if modname
!= name
and module
and hasattr(module
, key
):
692 if getattr(module
, key
) is base
:
694 cdict
[key
] = cdict
[base
] = modname
+ '.html#' + key
695 funcs
, fdict
= [], {}
696 for key
, value
in inspect
.getmembers(object, inspect
.isroutine
):
697 # if __all__ exists, believe it. Otherwise use old heuristic.
698 if (all
is not None or
699 inspect
.isbuiltin(value
) or inspect
.getmodule(value
) is object):
700 if visiblename(key
, all
, object):
701 funcs
.append((key
, value
))
702 fdict
[key
] = '#-' + key
703 if inspect
.isfunction(value
): fdict
[value
] = fdict
[key
]
705 for key
, value
in inspect
.getmembers(object, isdata
):
706 if visiblename(key
, all
, object):
707 data
.append((key
, value
))
709 doc
= self
.markup(getdoc(object), self
.preformat
, fdict
, cdict
)
710 doc
= doc
and '<tt>%s</tt>' % doc
711 result
= result
+ '<p>%s</p>\n' % doc
713 if hasattr(object, '__path__'):
715 for importer
, modname
, ispkg
in pkgutil
.iter_modules(object.__path
__):
716 modpkgs
.append((modname
, name
, ispkg
, 0))
718 contents
= self
.multicolumn(modpkgs
, self
.modpkglink
)
719 result
= result
+ self
.bigsection(
720 'Package Contents', '#ffffff', '#aa55cc', contents
)
722 contents
= self
.multicolumn(
723 modules
, lambda key_value
, s
=self
: s
.modulelink(key_value
[1]))
724 result
= result
+ self
.bigsection(
725 'Modules', '#ffffff', '#aa55cc', contents
)
728 classlist
= map(lambda key_value
: key_value
[1], classes
)
730 self
.formattree(inspect
.getclasstree(classlist
, 1), name
)]
731 for key
, value
in classes
:
732 contents
.append(self
.document(value
, key
, name
, fdict
, cdict
))
733 result
= result
+ self
.bigsection(
734 'Classes', '#ffffff', '#ee77aa', join(contents
))
737 for key
, value
in funcs
:
738 contents
.append(self
.document(value
, key
, name
, fdict
, cdict
))
739 result
= result
+ self
.bigsection(
740 'Functions', '#ffffff', '#eeaa77', join(contents
))
743 for key
, value
in data
:
744 contents
.append(self
.document(value
, key
))
745 result
= result
+ self
.bigsection(
746 'Data', '#ffffff', '#55aa55', join(contents
, '<br>\n'))
747 if hasattr(object, '__author__'):
748 contents
= self
.markup(_binstr(object.__author
__), self
.preformat
)
749 result
= result
+ self
.bigsection(
750 'Author', '#ffffff', '#7799ee', contents
)
751 if hasattr(object, '__credits__'):
752 contents
= self
.markup(_binstr(object.__credits
__), self
.preformat
)
753 result
= result
+ self
.bigsection(
754 'Credits', '#ffffff', '#7799ee', contents
)
758 def docclass(self
, object, name
=None, mod
=None, funcs
={}, classes
={},
760 """Produce HTML documentation for a class object."""
761 realname
= object.__name
__
762 name
= name
or realname
763 bases
= object.__bases
__
766 push
= contents
.append
768 # Cute little class to pump out a horizontal rule between sections.
769 class HorizontalRule
:
776 hr
= HorizontalRule()
778 # List the mro, if non-trivial.
779 mro
= deque(inspect
.getmro(object))
782 push('<dl><dt>Method resolution order:</dt>\n')
784 push('<dd>%s</dd>\n' % self
.classlink(base
,
788 def spill(msg
, attrs
, predicate
):
789 ok
, attrs
= _split_list(attrs
, predicate
)
793 for name
, kind
, homecls
, value
in ok
:
795 value
= getattr(object, name
)
797 # Some descriptors may meet a failure in their __get__.
799 push(self
._docdescriptor
(name
, value
, mod
))
801 push(self
.document(value
, name
, mod
,
802 funcs
, classes
, mdict
, object))
806 def spilldescriptors(msg
, attrs
, predicate
):
807 ok
, attrs
= _split_list(attrs
, predicate
)
811 for name
, kind
, homecls
, value
in ok
:
812 push(self
._docdescriptor
(name
, value
, mod
))
815 def spilldata(msg
, attrs
, predicate
):
816 ok
, attrs
= _split_list(attrs
, predicate
)
820 for name
, kind
, homecls
, value
in ok
:
821 base
= self
.docother(getattr(object, name
), name
, mod
)
822 if (hasattr(value
, '__call__') or
823 inspect
.isdatadescriptor(value
)):
824 doc
= getattr(value
, "__doc__", None)
828 push('<dl><dt>%s</dl>\n' % base
)
830 doc
= self
.markup(getdoc(value
), self
.preformat
,
831 funcs
, classes
, mdict
)
832 doc
= '<dd><tt>%s</tt>' % doc
833 push('<dl><dt>%s%s</dl>\n' % (base
, doc
))
837 attrs
= filter(lambda data
: visiblename(data
[0], obj
=object),
838 classify_class_attrs(object))
840 for key
, kind
, homecls
, value
in attrs
:
841 mdict
[key
] = anchor
= '#' + name
+ '-' + key
843 value
= getattr(object, name
)
845 # Some descriptors may meet a failure in their __get__.
849 # The value may not be hashable (e.g., a data attr with
850 # a dict or list value).
851 mdict
[value
] = anchor
857 thisclass
= mro
.popleft()
859 thisclass
= attrs
[0][2]
860 attrs
, inherited
= _split_list(attrs
, lambda t
: t
[2] is thisclass
)
862 if thisclass
is __builtin__
.object:
865 elif thisclass
is object:
868 tag
= 'inherited from %s' % self
.classlink(thisclass
,
872 # Sort attrs by name.
874 attrs
.sort(key
=lambda t
: t
[0])
876 attrs
.sort(lambda t1
, t2
: cmp(t1
[0], t2
[0])) # 2.3 compat
878 # Pump out the attrs, segregated by kind.
879 attrs
= spill('Methods %s' % tag
, attrs
,
880 lambda t
: t
[1] == 'method')
881 attrs
= spill('Class methods %s' % tag
, attrs
,
882 lambda t
: t
[1] == 'class method')
883 attrs
= spill('Static methods %s' % tag
, attrs
,
884 lambda t
: t
[1] == 'static method')
885 attrs
= spilldescriptors('Data descriptors %s' % tag
, attrs
,
886 lambda t
: t
[1] == 'data descriptor')
887 attrs
= spilldata('Data and other attributes %s' % tag
, attrs
,
888 lambda t
: t
[1] == 'data')
892 contents
= ''.join(contents
)
895 title
= '<a name="%s">class <strong>%s</strong></a>' % (
898 title
= '<strong>%s</strong> = <a name="%s">class %s</a>' % (
899 name
, name
, realname
)
903 parents
.append(self
.classlink(base
, object.__module
__))
904 title
= title
+ '(%s)' % join(parents
, ', ')
905 doc
= self
.markup(getdoc(object), self
.preformat
, funcs
, classes
, mdict
)
906 doc
= doc
and '<tt>%s<br> </tt>' % doc
908 return self
.section(title
, '#000000', '#ffc8d8', contents
, 3, doc
)
910 def formatvalue(self
, object):
911 """Format an argument default value as text."""
912 return self
.grey('=' + self
.repr(object))
914 def docroutine(self
, object, name
=None, mod
=None,
915 funcs
={}, classes
={}, methods
={}, cl
=None):
916 """Produce HTML documentation for a function or method object."""
917 realname
= object.__name
__
918 name
= name
or realname
919 anchor
= (cl
and cl
.__name
__ or '') + '-' + name
922 if inspect
.ismethod(object):
923 imclass
= object.im_class
925 if imclass
is not cl
:
926 note
= ' from ' + self
.classlink(imclass
, mod
)
928 if object.im_self
is not None:
929 note
= ' method of %s instance' % self
.classlink(
930 object.im_self
.__class
__, mod
)
932 note
= ' unbound %s method' % self
.classlink(imclass
,mod
)
933 object = object.im_func
936 title
= '<a name="%s"><strong>%s</strong></a>' % (anchor
, realname
)
938 if (cl
and realname
in cl
.__dict
__ and
939 cl
.__dict
__[realname
] is object):
940 reallink
= '<a href="#%s">%s</a>' % (
941 cl
.__name
__ + '-' + realname
, realname
)
945 title
= '<a name="%s"><strong>%s</strong></a> = %s' % (
946 anchor
, name
, reallink
)
947 if inspect
.isfunction(object):
948 args
, varargs
, varkw
, defaults
= inspect
.getargspec(object)
949 argspec
= inspect
.formatargspec(
950 args
, varargs
, varkw
, defaults
, formatvalue
=self
.formatvalue
)
951 if realname
== '<lambda>':
952 title
= '<strong>%s</strong> <em>lambda</em> ' % name
953 argspec
= argspec
[1:-1] # remove parentheses
957 decl
= title
+ argspec
+ (note
and self
.grey(
958 '<font face="helvetica, arial">%s</font>' % note
))
961 return '<dl><dt>%s</dt></dl>\n' % decl
964 getdoc(object), self
.preformat
, funcs
, classes
, methods
)
965 doc
= doc
and '<dd><tt>%s</tt></dd>' % doc
966 return '<dl><dt>%s</dt>%s</dl>\n' % (decl
, doc
)
968 def _docdescriptor(self
, name
, value
, mod
):
970 push
= results
.append
973 push('<dl><dt><strong>%s</strong></dt>\n' % name
)
974 if value
.__doc
__ is not None:
975 doc
= self
.markup(getdoc(value
), self
.preformat
)
976 push('<dd><tt>%s</tt></dd>\n' % doc
)
979 return ''.join(results
)
981 def docproperty(self
, object, name
=None, mod
=None, cl
=None):
982 """Produce html documentation for a property."""
983 return self
._docdescriptor
(name
, object, mod
)
985 def docother(self
, object, name
=None, mod
=None, *ignored
):
986 """Produce HTML documentation for a data object."""
987 lhs
= name
and '<strong>%s</strong> = ' % name
or ''
988 return lhs
+ self
.repr(object)
990 def docdata(self
, object, name
=None, mod
=None, cl
=None):
991 """Produce html documentation for a data descriptor."""
992 return self
._docdescriptor
(name
, object, mod
)
994 def index(self
, dir, shadowed
=None):
995 """Generate an HTML index for a directory of modules."""
997 if shadowed
is None: shadowed
= {}
998 for importer
, name
, ispkg
in pkgutil
.iter_modules([dir]):
999 modpkgs
.append((name
, '', ispkg
, name
in shadowed
))
1003 contents
= self
.multicolumn(modpkgs
, self
.modpkglink
)
1004 return self
.bigsection(dir, '#ffffff', '#ee77aa', contents
)
1006 # -------------------------------------------- text documentation generator
1008 class TextRepr(Repr
):
1009 """Class for safely making a text representation of a Python object."""
1012 self
.maxlist
= self
.maxtuple
= 20
1014 self
.maxstring
= self
.maxother
= 100
1016 def repr1(self
, x
, level
):
1017 if hasattr(type(x
), '__name__'):
1018 methodname
= 'repr_' + join(split(type(x
).__name
__), '_')
1019 if hasattr(self
, methodname
):
1020 return getattr(self
, methodname
)(x
, level
)
1021 return cram(stripid(repr(x
)), self
.maxother
)
1023 def repr_string(self
, x
, level
):
1024 test
= cram(x
, self
.maxstring
)
1025 testrepr
= repr(test
)
1026 if '\\' in test
and '\\' not in replace(testrepr
, r
'\\', ''):
1027 # Backslashes are only literal in the string and are never
1028 # needed to make any special characters, so show a raw string.
1029 return 'r' + testrepr
[0] + test
+ testrepr
[0]
1032 repr_str
= repr_string
1034 def repr_instance(self
, x
, level
):
1036 return cram(stripid(repr(x
)), self
.maxstring
)
1038 return '<%s instance>' % x
.__class
__.__name
__
1041 """Formatter class for text documentation."""
1043 # ------------------------------------------- text formatting utilities
1045 _repr_instance
= TextRepr()
1046 repr = _repr_instance
.repr
1048 def bold(self
, text
):
1049 """Format a string in bold by overstriking."""
1050 return join(map(lambda ch
: ch
+ '\b' + ch
, text
), '')
1052 def indent(self
, text
, prefix
=' '):
1053 """Indent text by prepending a given prefix to each line."""
1054 if not text
: return ''
1055 lines
= split(text
, '\n')
1056 lines
= map(lambda line
, prefix
=prefix
: prefix
+ line
, lines
)
1057 if lines
: lines
[-1] = rstrip(lines
[-1])
1058 return join(lines
, '\n')
1060 def section(self
, title
, contents
):
1061 """Format a section with a given heading."""
1062 return self
.bold(title
) + '\n' + rstrip(self
.indent(contents
)) + '\n\n'
1064 # ---------------------------------------------- type-specific routines
1066 def formattree(self
, tree
, modname
, parent
=None, prefix
=''):
1067 """Render in text a class tree as returned by inspect.getclasstree()."""
1070 if type(entry
) is type(()):
1072 result
= result
+ prefix
+ classname(c
, modname
)
1073 if bases
and bases
!= (parent
,):
1074 parents
= map(lambda c
, m
=modname
: classname(c
, m
), bases
)
1075 result
= result
+ '(%s)' % join(parents
, ', ')
1076 result
= result
+ '\n'
1077 elif type(entry
) is type([]):
1078 result
= result
+ self
.formattree(
1079 entry
, modname
, c
, prefix
+ ' ')
1082 def docmodule(self
, object, name
=None, mod
=None):
1083 """Produce text documentation for a given module object."""
1084 name
= object.__name
__ # ignore the passed-in name
1085 synop
, desc
= splitdoc(getdoc(object))
1086 result
= self
.section('NAME', name
+ (synop
and ' - ' + synop
))
1089 all
= object.__all
__
1090 except AttributeError:
1094 file = inspect
.getabsfile(object)
1097 result
= result
+ self
.section('FILE', file)
1099 docloc
= self
.getdocloc(object)
1100 if docloc
is not None:
1101 result
= result
+ self
.section('MODULE DOCS', docloc
)
1104 result
= result
+ self
.section('DESCRIPTION', desc
)
1107 for key
, value
in inspect
.getmembers(object, inspect
.isclass
):
1108 # if __all__ exists, believe it. Otherwise use old heuristic.
1110 or (inspect
.getmodule(value
) or object) is object):
1111 if visiblename(key
, all
, object):
1112 classes
.append((key
, value
))
1114 for key
, value
in inspect
.getmembers(object, inspect
.isroutine
):
1115 # if __all__ exists, believe it. Otherwise use old heuristic.
1116 if (all
is not None or
1117 inspect
.isbuiltin(value
) or inspect
.getmodule(value
) is object):
1118 if visiblename(key
, all
, object):
1119 funcs
.append((key
, value
))
1121 for key
, value
in inspect
.getmembers(object, isdata
):
1122 if visiblename(key
, all
, object):
1123 data
.append((key
, value
))
1126 modpkgs_names
= set()
1127 if hasattr(object, '__path__'):
1128 for importer
, modname
, ispkg
in pkgutil
.iter_modules(object.__path
__):
1129 modpkgs_names
.add(modname
)
1131 modpkgs
.append(modname
+ ' (package)')
1133 modpkgs
.append(modname
)
1136 result
= result
+ self
.section(
1137 'PACKAGE CONTENTS', join(modpkgs
, '\n'))
1139 # Detect submodules as sometimes created by C extensions
1141 for key
, value
in inspect
.getmembers(object, inspect
.ismodule
):
1142 if value
.__name
__.startswith(name
+ '.') and key
not in modpkgs_names
:
1143 submodules
.append(key
)
1146 result
= result
+ self
.section(
1147 'SUBMODULES', join(submodules
, '\n'))
1150 classlist
= map(lambda key_value
: key_value
[1], classes
)
1151 contents
= [self
.formattree(
1152 inspect
.getclasstree(classlist
, 1), name
)]
1153 for key
, value
in classes
:
1154 contents
.append(self
.document(value
, key
, name
))
1155 result
= result
+ self
.section('CLASSES', join(contents
, '\n'))
1159 for key
, value
in funcs
:
1160 contents
.append(self
.document(value
, key
, name
))
1161 result
= result
+ self
.section('FUNCTIONS', join(contents
, '\n'))
1165 for key
, value
in data
:
1166 contents
.append(self
.docother(value
, key
, name
, maxlen
=70))
1167 result
= result
+ self
.section('DATA', join(contents
, '\n'))
1169 if hasattr(object, '__version__'):
1170 version
= _binstr(object.__version
__)
1171 if version
[:11] == '$' + 'Revision: ' and version
[-1:] == '$':
1172 version
= strip(version
[11:-1])
1173 result
= result
+ self
.section('VERSION', version
)
1174 if hasattr(object, '__date__'):
1175 result
= result
+ self
.section('DATE', _binstr(object.__date
__))
1176 if hasattr(object, '__author__'):
1177 result
= result
+ self
.section('AUTHOR', _binstr(object.__author
__))
1178 if hasattr(object, '__credits__'):
1179 result
= result
+ self
.section('CREDITS', _binstr(object.__credits
__))
1182 def docclass(self
, object, name
=None, mod
=None, *ignored
):
1183 """Produce text documentation for a given class object."""
1184 realname
= object.__name
__
1185 name
= name
or realname
1186 bases
= object.__bases
__
1188 def makename(c
, m
=object.__module
__):
1189 return classname(c
, m
)
1191 if name
== realname
:
1192 title
= 'class ' + self
.bold(realname
)
1194 title
= self
.bold(name
) + ' = class ' + realname
1196 parents
= map(makename
, bases
)
1197 title
= title
+ '(%s)' % join(parents
, ', ')
1199 doc
= getdoc(object)
1200 contents
= doc
and [doc
+ '\n'] or []
1201 push
= contents
.append
1203 # List the mro, if non-trivial.
1204 mro
= deque(inspect
.getmro(object))
1206 push("Method resolution order:")
1208 push(' ' + makename(base
))
1211 # Cute little class to pump out a horizontal rule between sections.
1212 class HorizontalRule
:
1219 hr
= HorizontalRule()
1221 def spill(msg
, attrs
, predicate
):
1222 ok
, attrs
= _split_list(attrs
, predicate
)
1226 for name
, kind
, homecls
, value
in ok
:
1228 value
= getattr(object, name
)
1230 # Some descriptors may meet a failure in their __get__.
1232 push(self
._docdescriptor
(name
, value
, mod
))
1234 push(self
.document(value
,
1238 def spilldescriptors(msg
, attrs
, predicate
):
1239 ok
, attrs
= _split_list(attrs
, predicate
)
1243 for name
, kind
, homecls
, value
in ok
:
1244 push(self
._docdescriptor
(name
, value
, mod
))
1247 def spilldata(msg
, attrs
, predicate
):
1248 ok
, attrs
= _split_list(attrs
, predicate
)
1252 for name
, kind
, homecls
, value
in ok
:
1253 if (hasattr(value
, '__call__') or
1254 inspect
.isdatadescriptor(value
)):
1258 push(self
.docother(getattr(object, name
),
1259 name
, mod
, maxlen
=70, doc
=doc
) + '\n')
1262 attrs
= filter(lambda data
: visiblename(data
[0], obj
=object),
1263 classify_class_attrs(object))
1266 thisclass
= mro
.popleft()
1268 thisclass
= attrs
[0][2]
1269 attrs
, inherited
= _split_list(attrs
, lambda t
: t
[2] is thisclass
)
1271 if thisclass
is __builtin__
.object:
1274 elif thisclass
is object:
1275 tag
= "defined here"
1277 tag
= "inherited from %s" % classname(thisclass
,
1280 # Sort attrs by name.
1283 # Pump out the attrs, segregated by kind.
1284 attrs
= spill("Methods %s:\n" % tag
, attrs
,
1285 lambda t
: t
[1] == 'method')
1286 attrs
= spill("Class methods %s:\n" % tag
, attrs
,
1287 lambda t
: t
[1] == 'class method')
1288 attrs
= spill("Static methods %s:\n" % tag
, attrs
,
1289 lambda t
: t
[1] == 'static method')
1290 attrs
= spilldescriptors("Data descriptors %s:\n" % tag
, attrs
,
1291 lambda t
: t
[1] == 'data descriptor')
1292 attrs
= spilldata("Data and other attributes %s:\n" % tag
, attrs
,
1293 lambda t
: t
[1] == 'data')
1297 contents
= '\n'.join(contents
)
1300 return title
+ '\n' + self
.indent(rstrip(contents
), ' | ') + '\n'
1302 def formatvalue(self
, object):
1303 """Format an argument default value as text."""
1304 return '=' + self
.repr(object)
1306 def docroutine(self
, object, name
=None, mod
=None, cl
=None):
1307 """Produce text documentation for a function or method object."""
1308 realname
= object.__name
__
1309 name
= name
or realname
1312 if inspect
.ismethod(object):
1313 imclass
= object.im_class
1315 if imclass
is not cl
:
1316 note
= ' from ' + classname(imclass
, mod
)
1318 if object.im_self
is not None:
1319 note
= ' method of %s instance' % classname(
1320 object.im_self
.__class
__, mod
)
1322 note
= ' unbound %s method' % classname(imclass
,mod
)
1323 object = object.im_func
1325 if name
== realname
:
1326 title
= self
.bold(realname
)
1328 if (cl
and realname
in cl
.__dict
__ and
1329 cl
.__dict
__[realname
] is object):
1331 title
= self
.bold(name
) + ' = ' + realname
1332 if inspect
.isfunction(object):
1333 args
, varargs
, varkw
, defaults
= inspect
.getargspec(object)
1334 argspec
= inspect
.formatargspec(
1335 args
, varargs
, varkw
, defaults
, formatvalue
=self
.formatvalue
)
1336 if realname
== '<lambda>':
1337 title
= self
.bold(name
) + ' lambda '
1338 argspec
= argspec
[1:-1] # remove parentheses
1341 decl
= title
+ argspec
+ note
1346 doc
= getdoc(object) or ''
1347 return decl
+ '\n' + (doc
and rstrip(self
.indent(doc
)) + '\n')
1349 def _docdescriptor(self
, name
, value
, mod
):
1351 push
= results
.append
1354 push(self
.bold(name
))
1356 doc
= getdoc(value
) or ''
1358 push(self
.indent(doc
))
1360 return ''.join(results
)
1362 def docproperty(self
, object, name
=None, mod
=None, cl
=None):
1363 """Produce text documentation for a property."""
1364 return self
._docdescriptor
(name
, object, mod
)
1366 def docdata(self
, object, name
=None, mod
=None, cl
=None):
1367 """Produce text documentation for a data descriptor."""
1368 return self
._docdescriptor
(name
, object, mod
)
1370 def docother(self
, object, name
=None, mod
=None, parent
=None, maxlen
=None, doc
=None):
1371 """Produce text documentation for a data object."""
1372 repr = self
.repr(object)
1374 line
= (name
and name
+ ' = ' or '') + repr
1375 chop
= maxlen
- len(line
)
1376 if chop
< 0: repr = repr[:chop
] + '...'
1377 line
= (name
and self
.bold(name
) + ' = ' or '') + repr
1379 line
+= '\n' + self
.indent(str(doc
))
1382 # --------------------------------------------------------- user interfaces
1385 """The first time this is called, determine what kind of pager to use."""
1391 """Decide what method to use for paging through text."""
1392 if type(sys
.stdout
) is not types
.FileType
:
1394 if not hasattr(sys
.stdin
, "isatty"):
1396 if not sys
.stdin
.isatty() or not sys
.stdout
.isatty():
1398 if 'PAGER' in os
.environ
:
1399 if sys
.platform
== 'win32': # pipes completely broken in Windows
1400 return lambda text
: tempfilepager(plain(text
), os
.environ
['PAGER'])
1401 elif sys
.platform
== 'uefi':
1402 return lambda text
: tempfilepager(plain(text
), os
.environ
['PAGER'])
1403 elif os
.environ
.get('TERM') in ('dumb', 'emacs'):
1404 return lambda text
: pipepager(plain(text
), os
.environ
['PAGER'])
1406 return lambda text
: pipepager(text
, os
.environ
['PAGER'])
1407 if os
.environ
.get('TERM') in ('dumb', 'emacs'):
1409 if sys
.platform
== 'uefi':
1411 if sys
.platform
== 'win32' or sys
.platform
.startswith('os2'):
1412 return lambda text
: tempfilepager(plain(text
), 'more <')
1413 if hasattr(os
, 'system') and os
.system('(less) 2>/dev/null') == 0:
1414 return lambda text
: pipepager(text
, 'less')
1417 (fd
, filename
) = tempfile
.mkstemp()
1420 if hasattr(os
, 'system') and os
.system('more "%s"' % filename
) == 0:
1421 return lambda text
: pipepager(text
, 'more')
1428 """Remove boldface formatting from text."""
1429 return re
.sub('.\b', '', text
)
1431 def pipepager(text
, cmd
):
1432 """Page through text by feeding it to another program."""
1433 pipe
= os
.popen(cmd
, 'w')
1435 pipe
.write(_encode(text
))
1438 pass # Ignore broken pipes caused by quitting the pager program.
1440 def tempfilepager(text
, cmd
):
1441 """Page through text by invoking a program on a temporary file."""
1443 filename
= tempfile
.mktemp()
1444 file = open(filename
, 'w')
1445 file.write(_encode(text
))
1448 os
.system(cmd
+ ' "' + filename
+ '"')
1453 """Page through text on a text terminal."""
1454 lines
= plain(_encode(plain(text
), getattr(sys
.stdout
, 'encoding', _encoding
))).split('\n')
1457 fd
= sys
.stdin
.fileno()
1458 old
= tty
.tcgetattr(fd
)
1460 getchar
= lambda: sys
.stdin
.read(1)
1461 except (ImportError, AttributeError):
1463 getchar
= lambda: sys
.stdin
.readline()[:-1][:1]
1467 h
= int(os
.environ
.get('LINES', 0))
1473 sys
.stdout
.write(join(lines
[:inc
], '\n') + '\n')
1475 sys
.stdout
.write('-- more --')
1480 sys
.stdout
.write('\r \r')
1482 elif c
in ('\r', '\n'):
1483 sys
.stdout
.write('\r \r' + lines
[r
] + '\n')
1486 if c
in ('b', 'B', '\x1b'):
1489 sys
.stdout
.write('\n' + join(lines
[r
:r
+inc
], '\n') + '\n')
1494 tty
.tcsetattr(fd
, tty
.TCSAFLUSH
, old
)
1496 def plainpager(text
):
1497 """Simply print unformatted text. This is the ultimate fallback."""
1498 sys
.stdout
.write(_encode(plain(text
), getattr(sys
.stdout
, 'encoding', _encoding
)))
1500 def describe(thing
):
1501 """Produce a short description of the given thing."""
1502 if inspect
.ismodule(thing
):
1503 if thing
.__name
__ in sys
.builtin_module_names
:
1504 return 'built-in module ' + thing
.__name
__
1505 if hasattr(thing
, '__path__'):
1506 return 'package ' + thing
.__name
__
1508 return 'module ' + thing
.__name
__
1509 if inspect
.isbuiltin(thing
):
1510 return 'built-in function ' + thing
.__name
__
1511 if inspect
.isgetsetdescriptor(thing
):
1512 return 'getset descriptor %s.%s.%s' % (
1513 thing
.__objclass
__.__module
__, thing
.__objclass
__.__name
__,
1515 if inspect
.ismemberdescriptor(thing
):
1516 return 'member descriptor %s.%s.%s' % (
1517 thing
.__objclass
__.__module
__, thing
.__objclass
__.__name
__,
1519 if inspect
.isclass(thing
):
1520 return 'class ' + thing
.__name
__
1521 if inspect
.isfunction(thing
):
1522 return 'function ' + thing
.__name
__
1523 if inspect
.ismethod(thing
):
1524 return 'method ' + thing
.__name
__
1525 if type(thing
) is types
.InstanceType
:
1526 return 'instance of ' + thing
.__class
__.__name
__
1527 return type(thing
).__name
__
1529 def locate(path
, forceload
=0):
1530 """Locate an object by name or dotted path, importing as necessary."""
1531 parts
= [part
for part
in split(path
, '.') if part
]
1533 while n
< len(parts
):
1534 nextmodule
= safeimport(join(parts
[:n
+1], '.'), forceload
)
1535 if nextmodule
: module
, n
= nextmodule
, n
+ 1
1540 object = __builtin__
1541 for part
in parts
[n
:]:
1543 object = getattr(object, part
)
1544 except AttributeError:
1548 # --------------------------------------- interactive interpreter interface
1553 class _OldStyleClass
: pass
1554 _OLD_INSTANCE_TYPE
= type(_OldStyleClass())
1556 def resolve(thing
, forceload
=0):
1557 """Given an object or a path to an object, get the object and its name."""
1558 if isinstance(thing
, str):
1559 object = locate(thing
, forceload
)
1561 raise ImportError, 'no Python documentation found for %r' % thing
1562 return object, thing
1564 name
= getattr(thing
, '__name__', None)
1565 return thing
, name
if isinstance(name
, str) else None
1567 def render_doc(thing
, title
='Python Library Documentation: %s', forceload
=0):
1568 """Render text documentation, given an object or a path to an object."""
1569 object, name
= resolve(thing
, forceload
)
1570 desc
= describe(object)
1571 module
= inspect
.getmodule(object)
1572 if name
and '.' in name
:
1573 desc
+= ' in ' + name
[:name
.rfind('.')]
1574 elif module
and module
is not object:
1575 desc
+= ' in module ' + module
.__name
__
1576 if type(object) is _OLD_INSTANCE_TYPE
:
1577 # If the passed object is an instance of an old-style class,
1578 # document its available methods instead of its value.
1579 object = object.__class
__
1580 elif not (inspect
.ismodule(object) or
1581 inspect
.isclass(object) or
1582 inspect
.isroutine(object) or
1583 inspect
.isgetsetdescriptor(object) or
1584 inspect
.ismemberdescriptor(object) or
1585 isinstance(object, property)):
1586 # If the passed object is a piece of data or an instance,
1587 # document its available methods instead of its value.
1588 object = type(object)
1590 return title
% desc
+ '\n\n' + text
.document(object, name
)
1592 def doc(thing
, title
='Python Library Documentation: %s', forceload
=0):
1593 """Display text documentation, given an object or a path to an object."""
1595 pager(render_doc(thing
, title
, forceload
))
1596 except (ImportError, ErrorDuringImport
), value
:
1599 def writedoc(thing
, forceload
=0):
1600 """Write HTML documentation to a file in the current directory."""
1602 object, name
= resolve(thing
, forceload
)
1603 page
= html
.page(describe(object), html
.document(object, name
))
1604 file = open(name
+ '.html', 'w')
1607 print 'wrote', name
+ '.html'
1608 except (ImportError, ErrorDuringImport
), value
:
1611 def writedocs(dir, pkgpath
='', done
=None):
1612 """Write out HTML documentation for all modules in a directory tree."""
1613 if done
is None: done
= {}
1614 for importer
, modname
, ispkg
in pkgutil
.walk_packages([dir], pkgpath
):
1620 # These dictionaries map a topic name to either an alias, or a tuple
1621 # (label, seealso-items). The "label" is the label of the corresponding
1622 # section in the .rst file under Doc/ and an index into the dictionary
1623 # in pydoc_data/topics.py.
1625 # CAUTION: if you change one of these dictionaries, be sure to adapt the
1626 # list of needed labels in Doc/tools/pyspecific.py and
1627 # regenerate the pydoc_data/topics.py file by running
1629 # in Doc/ and copying the output file into the Lib/ directory.
1634 'assert': ('assert', ''),
1635 'break': ('break', 'while for'),
1636 'class': ('class', 'CLASSES SPECIALMETHODS'),
1637 'continue': ('continue', 'while for'),
1638 'def': ('function', ''),
1639 'del': ('del', 'BASICMETHODS'),
1641 'else': ('else', 'while for'),
1643 'exec': ('exec', ''),
1645 'for': ('for', 'break continue while'),
1647 'global': ('global', 'NAMESPACES'),
1648 'if': ('if', 'TRUTHVALUE'),
1649 'import': ('import', 'MODULES'),
1650 'in': ('in', 'SEQUENCEMETHODS2'),
1652 'lambda': ('lambda', 'FUNCTIONS'),
1655 'pass': ('pass', ''),
1656 'print': ('print', ''),
1657 'raise': ('raise', 'EXCEPTIONS'),
1658 'return': ('return', 'FUNCTIONS'),
1659 'try': ('try', 'EXCEPTIONS'),
1660 'while': ('while', 'break continue if TRUTHVALUE'),
1661 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
1662 'yield': ('yield', ''),
1664 # Either add symbols to this dictionary or to the symbols dictionary
1665 # directly: Whichever is easier. They are merged later.
1666 _symbols_inverse
= {
1667 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'),
1668 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&',
1669 '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),
1670 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'),
1671 'UNARY' : ('-', '~'),
1672 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=',
1673 '^=', '<<=', '>>=', '**=', '//='),
1674 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'),
1675 'COMPLEX' : ('j', 'J')
1678 '%': 'OPERATORS FORMATTING',
1680 ',': 'TUPLES LISTS FUNCTIONS',
1681 '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',
1683 ':': 'SLICINGS DICTIONARYLITERALS',
1686 '_': 'PRIVATENAMES',
1687 '__': 'PRIVATENAMES SPECIALMETHODS',
1689 '(': 'TUPLES FUNCTIONS CALLS',
1690 ')': 'TUPLES FUNCTIONS CALLS',
1691 '[': 'LISTS SUBSCRIPTS SLICINGS',
1692 ']': 'LISTS SUBSCRIPTS SLICINGS'
1694 for topic
, symbols_
in _symbols_inverse
.iteritems():
1695 for symbol
in symbols_
:
1696 topics
= symbols
.get(symbol
, topic
)
1697 if topic
not in topics
:
1698 topics
= topics
+ ' ' + topic
1699 symbols
[symbol
] = topics
1702 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS '
1703 'FUNCTIONS CLASSES MODULES FILES inspect'),
1704 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING '
1706 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'),
1707 'FORMATTING': ('formatstrings', 'OPERATORS'),
1708 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS '
1709 'FORMATTING TYPES'),
1710 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'),
1711 'INTEGER': ('integers', 'int range'),
1712 'FLOAT': ('floating', 'float math'),
1713 'COMPLEX': ('imaginary', 'complex cmath'),
1714 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING xrange LISTS'),
1715 'MAPPINGS': 'DICTIONARIES',
1716 'FUNCTIONS': ('typesfunctions', 'def TYPES'),
1717 'METHODS': ('typesmethods', 'class def CLASSES TYPES'),
1718 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'),
1719 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'),
1720 'FRAMEOBJECTS': 'TYPES',
1721 'TRACEBACKS': 'TYPES',
1722 'NONE': ('bltin-null-object', ''),
1723 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'),
1724 'FILES': ('bltin-file-objects', ''),
1725 'SPECIALATTRIBUTES': ('specialattrs', ''),
1726 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'),
1727 'MODULES': ('typesmodules', 'import'),
1728 'PACKAGES': 'import',
1729 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN '
1730 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER '
1731 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES '
1732 'LISTS DICTIONARIES BACKQUOTES'),
1733 'OPERATORS': 'EXPRESSIONS',
1734 'PRECEDENCE': 'EXPRESSIONS',
1735 'OBJECTS': ('objects', 'TYPES'),
1736 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '
1737 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS '
1738 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
1739 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'),
1740 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
1741 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
1742 'SEQUENCEMETHODS1': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 '
1744 'SEQUENCEMETHODS2': ('sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 '
1746 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),
1747 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT '
1749 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),
1750 'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'),
1751 'DYNAMICFEATURES': ('dynamic-features', ''),
1752 'SCOPING': 'NAMESPACES',
1753 'FRAMES': 'NAMESPACES',
1754 'EXCEPTIONS': ('exceptions', 'try except finally raise'),
1755 'COERCIONS': ('coercion-rules','CONVERSIONS'),
1756 'CONVERSIONS': ('conversions', 'COERCIONS'),
1757 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'),
1758 'SPECIALIDENTIFIERS': ('id-classes', ''),
1759 'PRIVATENAMES': ('atom-identifiers', ''),
1760 'LITERALS': ('atom-literals', 'STRINGS BACKQUOTES NUMBERS '
1761 'TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'),
1762 'TUPLES': 'SEQUENCES',
1763 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'),
1764 'LISTS': ('typesseq-mutable', 'LISTLITERALS'),
1765 'LISTLITERALS': ('lists', 'LISTS LITERALS'),
1766 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),
1767 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),
1768 'BACKQUOTES': ('string-conversions', 'repr str STRINGS LITERALS'),
1769 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr '
1770 'ATTRIBUTEMETHODS'),
1771 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'),
1772 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'),
1773 'CALLS': ('calls', 'EXPRESSIONS'),
1774 'POWER': ('power', 'EXPRESSIONS'),
1775 'UNARY': ('unary', 'EXPRESSIONS'),
1776 'BINARY': ('binary', 'EXPRESSIONS'),
1777 'SHIFTING': ('shifting', 'EXPRESSIONS'),
1778 'BITWISE': ('bitwise', 'EXPRESSIONS'),
1779 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'),
1780 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'),
1781 'ASSERTION': 'assert',
1782 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'),
1783 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'),
1785 'PRINTING': 'print',
1786 'RETURNING': 'return',
1787 'IMPORTING': 'import',
1788 'CONDITIONAL': 'if',
1789 'LOOPING': ('compound', 'for while break continue'),
1790 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'),
1791 'DEBUGGING': ('debugger', 'pdb'),
1792 'CONTEXTMANAGERS': ('context-managers', 'with'),
1795 def __init__(self
, input=None, output
=None):
1797 self
._output
= output
1799 input = property(lambda self
: self
._input
or sys
.stdin
)
1800 output
= property(lambda self
: self
._output
or sys
.stdout
)
1803 if inspect
.stack()[1][3] == '?':
1806 return '<pydoc.Helper instance>'
1808 _GoInteractive
= object()
1809 def __call__(self
, request
=_GoInteractive
):
1810 if request
is not self
._GoInteractive
:
1815 self
.output
.write('''
1816 You are now leaving help and returning to the Python interpreter.
1817 If you want to ask for help on a particular object directly from the
1818 interpreter, you can type "help(object)". Executing "help('string')"
1819 has the same effect as typing a particular string at the help> prompt.
1823 self
.output
.write('\n')
1826 request
= self
.getline('help> ')
1827 if not request
: break
1828 except (KeyboardInterrupt, EOFError):
1830 request
= strip(replace(request
, '"', '', "'", ''))
1831 if lower(request
) in ('q', 'quit'): break
1834 def getline(self
, prompt
):
1835 """Read one line, using raw_input when available."""
1836 if self
.input is sys
.stdin
:
1837 return raw_input(prompt
)
1839 self
.output
.write(prompt
)
1841 return self
.input.readline()
1843 def help(self
, request
):
1844 if type(request
) is type(''):
1845 request
= request
.strip()
1846 if request
== 'help': self
.intro()
1847 elif request
== 'keywords': self
.listkeywords()
1848 elif request
== 'symbols': self
.listsymbols()
1849 elif request
== 'topics': self
.listtopics()
1850 elif request
== 'modules': self
.listmodules()
1851 elif request
[:8] == 'modules ':
1852 self
.listmodules(split(request
)[1])
1853 elif request
in self
.symbols
: self
.showsymbol(request
)
1854 elif request
in self
.keywords
: self
.showtopic(request
)
1855 elif request
in self
.topics
: self
.showtopic(request
)
1856 elif request
: doc(request
, 'Help on %s:')
1857 elif isinstance(request
, Helper
): self()
1858 else: doc(request
, 'Help on %s:')
1859 self
.output
.write('\n')
1862 self
.output
.write('''
1863 Welcome to Python %s! This is the online help utility.
1865 If this is your first time using Python, you should definitely check out
1866 the tutorial on the Internet at http://docs.python.org/%s/tutorial/.
1868 Enter the name of any module, keyword, or topic to get help on writing
1869 Python programs and using Python modules. To quit this help utility and
1870 return to the interpreter, just type "quit".
1872 To get a list of available modules, keywords, or topics, type "modules",
1873 "keywords", or "topics". Each module also comes with a one-line summary
1874 of what it does; to list the modules whose summaries contain a given word
1875 such as "spam", type "modules spam".
1876 ''' % tuple([sys
.version
[:3]]*2))
1878 def list(self
, items
, columns
=4, width
=80):
1881 colw
= width
/ columns
1882 rows
= (len(items
) + columns
- 1) / columns
1883 for row
in range(rows
):
1884 for col
in range(columns
):
1885 i
= col
* rows
+ row
1887 self
.output
.write(items
[i
])
1888 if col
< columns
- 1:
1889 self
.output
.write(' ' + ' ' * (colw
-1 - len(items
[i
])))
1890 self
.output
.write('\n')
1892 def listkeywords(self
):
1893 self
.output
.write('''
1894 Here is a list of the Python keywords. Enter any keyword to get more help.
1897 self
.list(self
.keywords
.keys())
1899 def listsymbols(self
):
1900 self
.output
.write('''
1901 Here is a list of the punctuation symbols which Python assigns special meaning
1902 to. Enter any symbol to get more help.
1905 self
.list(self
.symbols
.keys())
1907 def listtopics(self
):
1908 self
.output
.write('''
1909 Here is a list of available topics. Enter any topic name to get more help.
1912 self
.list(self
.topics
.keys())
1914 def showtopic(self
, topic
, more_xrefs
=''):
1916 import pydoc_data
.topics
1918 self
.output
.write('''
1919 Sorry, topic and keyword documentation is not available because the
1920 module "pydoc_data.topics" could not be found.
1923 target
= self
.topics
.get(topic
, self
.keywords
.get(topic
))
1925 self
.output
.write('no documentation found for %s\n' % repr(topic
))
1927 if type(target
) is type(''):
1928 return self
.showtopic(target
, more_xrefs
)
1930 label
, xrefs
= target
1932 doc
= pydoc_data
.topics
.topics
[label
]
1934 self
.output
.write('no documentation found for %s\n' % repr(topic
))
1936 pager(strip(doc
) + '\n')
1938 xrefs
= (xrefs
or '') + ' ' + more_xrefs
1940 import StringIO
, formatter
1941 buffer = StringIO
.StringIO()
1942 formatter
.DumbWriter(buffer).send_flowing_data(
1943 'Related help topics: ' + join(split(xrefs
), ', ') + '\n')
1944 self
.output
.write('\n%s\n' % buffer.getvalue())
1946 def showsymbol(self
, symbol
):
1947 target
= self
.symbols
[symbol
]
1948 topic
, _
, xrefs
= target
.partition(' ')
1949 self
.showtopic(topic
, xrefs
)
1951 def listmodules(self
, key
=''):
1953 self
.output
.write('''
1954 Here is a list of matching modules. Enter any module name to get more help.
1959 self
.output
.write('''
1960 Please wait a moment while I gather a list of all available modules...
1964 def callback(path
, modname
, desc
, modules
=modules
):
1965 if modname
and modname
[-9:] == '.__init__':
1966 modname
= modname
[:-9] + ' (package)'
1967 if find(modname
, '.') < 0:
1968 modules
[modname
] = 1
1969 def onerror(modname
):
1970 callback(None, modname
, None)
1971 ModuleScanner().run(callback
, onerror
=onerror
)
1972 self
.list(modules
.keys())
1973 self
.output
.write('''
1974 Enter any module name to get more help. Or, type "modules spam" to search
1975 for modules whose descriptions contain the word "spam".
1981 """A generic tree iterator."""
1982 def __init__(self
, roots
, children
, descendp
):
1983 self
.roots
= roots
[:]
1985 self
.children
= children
1986 self
.descendp
= descendp
1992 root
= self
.roots
.pop(0)
1993 self
.state
= [(root
, self
.children(root
))]
1994 node
, children
= self
.state
[-1]
1998 child
= children
.pop(0)
1999 if self
.descendp(child
):
2000 self
.state
.append((child
, self
.children(child
)))
2004 class ModuleScanner
:
2005 """An interruptible scanner that searches module synopses."""
2007 def run(self
, callback
, key
=None, completer
=None, onerror
=None):
2008 if key
: key
= lower(key
)
2012 for modname
in sys
.builtin_module_names
:
2013 if modname
!= '__main__':
2016 callback(None, modname
, '')
2018 desc
= split(__import__(modname
).__doc
__ or '', '\n')[0]
2019 if find(lower(modname
+ ' - ' + desc
), key
) >= 0:
2020 callback(None, modname
, desc
)
2022 for importer
, modname
, ispkg
in pkgutil
.walk_packages(onerror
=onerror
):
2026 callback(None, modname
, '')
2028 loader
= importer
.find_module(modname
)
2029 if hasattr(loader
,'get_source'):
2031 desc
= source_synopsis(
2032 StringIO
.StringIO(loader
.get_source(modname
))
2034 if hasattr(loader
,'get_filename'):
2035 path
= loader
.get_filename(modname
)
2039 module
= loader
.load_module(modname
)
2040 desc
= module
.__doc
__.splitlines()[0] if module
.__doc
__ else ''
2041 path
= getattr(module
,'__file__',None)
2042 if find(lower(modname
+ ' - ' + desc
), key
) >= 0:
2043 callback(path
, modname
, desc
)
2049 """Print all the one-line module summaries that contain a substring."""
2050 def callback(path
, modname
, desc
):
2051 if modname
[-9:] == '.__init__':
2052 modname
= modname
[:-9] + ' (package)'
2053 print modname
, desc
and '- ' + desc
2054 def onerror(modname
):
2056 with warnings
.catch_warnings():
2057 warnings
.filterwarnings('ignore') # ignore problems during import
2058 ModuleScanner().run(callback
, key
, onerror
=onerror
)
2060 # --------------------------------------------------- web browser interface
2062 def serve(port
, callback
=None, completer
=None):
2063 import BaseHTTPServer
, mimetools
, select
2065 # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
2066 class Message(mimetools
.Message
):
2067 def __init__(self
, fp
, seekable
=1):
2068 Message
= self
.__class
__
2069 Message
.__bases
__[0].__bases
__[0].__init
__(self
, fp
, seekable
)
2070 self
.encodingheader
= self
.getheader('content-transfer-encoding')
2071 self
.typeheader
= self
.getheader('content-type')
2075 class DocHandler(BaseHTTPServer
.BaseHTTPRequestHandler
):
2076 def send_document(self
, title
, contents
):
2078 self
.send_response(200)
2079 self
.send_header('Content-Type', 'text/html')
2081 self
.wfile
.write(html
.page(title
, contents
))
2082 except IOError: pass
2086 if path
[-5:] == '.html': path
= path
[:-5]
2087 if path
[:1] == '/': path
= path
[1:]
2088 if path
and path
!= '.':
2090 obj
= locate(path
, forceload
=1)
2091 except ErrorDuringImport
, value
:
2092 self
.send_document(path
, html
.escape(str(value
)))
2095 self
.send_document(describe(obj
), html
.document(obj
, path
))
2097 self
.send_document(path
,
2098 'no Python documentation found for %s' % repr(path
))
2100 heading
= html
.heading(
2101 '<big><big><strong>Python: Index of Modules</strong></big></big>',
2102 '#ffffff', '#7799ee')
2103 def bltinlink(name
):
2104 return '<a href="%s.html">%s</a>' % (name
, name
)
2105 names
= filter(lambda x
: x
!= '__main__',
2106 sys
.builtin_module_names
)
2107 contents
= html
.multicolumn(names
, bltinlink
)
2108 indices
= ['<p>' + html
.bigsection(
2109 'Built-in Modules', '#ffffff', '#ee77aa', contents
)]
2112 for dir in sys
.path
:
2113 indices
.append(html
.index(dir, seen
))
2114 contents
= heading
+ join(indices
) + '''<p align=right>
2115 <font color="#909090" face="helvetica, arial"><strong>
2116 pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''
2117 self
.send_document('Index of Modules', contents
)
2119 def log_message(self
, *args
): pass
2121 class DocServer(BaseHTTPServer
.HTTPServer
):
2122 def __init__(self
, port
, callback
):
2124 self
.address
= (host
, port
)
2125 self
.callback
= callback
2126 self
.base
.__init
__(self
, self
.address
, self
.handler
)
2128 def serve_until_quit(self
):
2131 while not self
.quit
:
2132 rd
, wr
, ex
= select
.select([self
.socket
.fileno()], [], [], 1)
2133 if rd
: self
.handle_request()
2135 def server_activate(self
):
2136 self
.base
.server_activate(self
)
2137 self
.url
= 'http://%s:%d/' % (self
.address
[0], self
.server_port
)
2138 if self
.callback
: self
.callback(self
)
2140 DocServer
.base
= BaseHTTPServer
.HTTPServer
2141 DocServer
.handler
= DocHandler
2142 DocHandler
.MessageClass
= Message
2145 DocServer(port
, callback
).serve_until_quit()
2146 except (KeyboardInterrupt, select
.error
):
2149 if completer
: completer()
2151 # ----------------------------------------------------- graphical interface
2154 """Graphical interface (starts web server and pops up a control window)."""
2156 def __init__(self
, window
, port
=7464):
2157 self
.window
= window
2162 self
.server_frm
= Tkinter
.Frame(window
)
2163 self
.title_lbl
= Tkinter
.Label(self
.server_frm
,
2164 text
='Starting server...\n ')
2165 self
.open_btn
= Tkinter
.Button(self
.server_frm
,
2166 text
='open browser', command
=self
.open, state
='disabled')
2167 self
.quit_btn
= Tkinter
.Button(self
.server_frm
,
2168 text
='quit serving', command
=self
.quit
, state
='disabled')
2170 self
.search_frm
= Tkinter
.Frame(window
)
2171 self
.search_lbl
= Tkinter
.Label(self
.search_frm
, text
='Search for')
2172 self
.search_ent
= Tkinter
.Entry(self
.search_frm
)
2173 self
.search_ent
.bind('<Return>', self
.search
)
2174 self
.stop_btn
= Tkinter
.Button(self
.search_frm
,
2175 text
='stop', pady
=0, command
=self
.stop
, state
='disabled')
2176 if sys
.platform
== 'win32':
2177 # Trying to hide and show this button crashes under Windows.
2178 self
.stop_btn
.pack(side
='right')
2180 self
.window
.title('pydoc')
2181 self
.window
.protocol('WM_DELETE_WINDOW', self
.quit
)
2182 self
.title_lbl
.pack(side
='top', fill
='x')
2183 self
.open_btn
.pack(side
='left', fill
='x', expand
=1)
2184 self
.quit_btn
.pack(side
='right', fill
='x', expand
=1)
2185 self
.server_frm
.pack(side
='top', fill
='x')
2187 self
.search_lbl
.pack(side
='left')
2188 self
.search_ent
.pack(side
='right', fill
='x', expand
=1)
2189 self
.search_frm
.pack(side
='top', fill
='x')
2190 self
.search_ent
.focus_set()
2192 font
= ('helvetica', sys
.platform
== 'win32' and 8 or 10)
2193 self
.result_lst
= Tkinter
.Listbox(window
, font
=font
, height
=6)
2194 self
.result_lst
.bind('<Button-1>', self
.select
)
2195 self
.result_lst
.bind('<Double-Button-1>', self
.goto
)
2196 self
.result_scr
= Tkinter
.Scrollbar(window
,
2197 orient
='vertical', command
=self
.result_lst
.yview
)
2198 self
.result_lst
.config(yscrollcommand
=self
.result_scr
.set)
2200 self
.result_frm
= Tkinter
.Frame(window
)
2201 self
.goto_btn
= Tkinter
.Button(self
.result_frm
,
2202 text
='go to selected', command
=self
.goto
)
2203 self
.hide_btn
= Tkinter
.Button(self
.result_frm
,
2204 text
='hide results', command
=self
.hide
)
2205 self
.goto_btn
.pack(side
='left', fill
='x', expand
=1)
2206 self
.hide_btn
.pack(side
='right', fill
='x', expand
=1)
2208 self
.window
.update()
2209 self
.minwidth
= self
.window
.winfo_width()
2210 self
.minheight
= self
.window
.winfo_height()
2211 self
.bigminheight
= (self
.server_frm
.winfo_reqheight() +
2212 self
.search_frm
.winfo_reqheight() +
2213 self
.result_lst
.winfo_reqheight() +
2214 self
.result_frm
.winfo_reqheight())
2215 self
.bigwidth
, self
.bigheight
= self
.minwidth
, self
.bigminheight
2217 self
.window
.wm_geometry('%dx%d' % (self
.minwidth
, self
.minheight
))
2218 self
.window
.wm_minsize(self
.minwidth
, self
.minheight
)
2219 self
.window
.tk
.willdispatch()
2223 target
=serve
, args
=(port
, self
.ready
, self
.quit
)).start()
2225 def ready(self
, server
):
2226 self
.server
= server
2227 self
.title_lbl
.config(
2228 text
='Python documentation server at\n' + server
.url
)
2229 self
.open_btn
.config(state
='normal')
2230 self
.quit_btn
.config(state
='normal')
2232 def open(self
, event
=None, url
=None):
2233 url
= url
or self
.server
.url
2236 webbrowser
.open(url
)
2237 except ImportError: # pre-webbrowser.py compatibility
2238 if sys
.platform
== 'win32':
2239 os
.system('start "%s"' % url
)
2241 rc
= os
.system('netscape -remote "openURL(%s)" &' % url
)
2242 if rc
: os
.system('netscape "%s" &' % url
)
2244 def quit(self
, event
=None):
2246 self
.server
.quit
= 1
2249 def search(self
, event
=None):
2250 key
= self
.search_ent
.get()
2251 self
.stop_btn
.pack(side
='right')
2252 self
.stop_btn
.config(state
='normal')
2253 self
.search_lbl
.config(text
='Searching for "%s"...' % key
)
2254 self
.search_ent
.forget()
2255 self
.search_lbl
.pack(side
='left')
2256 self
.result_lst
.delete(0, 'end')
2257 self
.goto_btn
.config(state
='disabled')
2262 self
.scanner
.quit
= 1
2263 self
.scanner
= ModuleScanner()
2264 threading
.Thread(target
=self
.scanner
.run
,
2265 args
=(self
.update
, key
, self
.done
)).start()
2267 def update(self
, path
, modname
, desc
):
2268 if modname
[-9:] == '.__init__':
2269 modname
= modname
[:-9] + ' (package)'
2270 self
.result_lst
.insert('end',
2271 modname
+ ' - ' + (desc
or '(no description)'))
2273 def stop(self
, event
=None):
2275 self
.scanner
.quit
= 1
2280 self
.search_lbl
.config(text
='Search for')
2281 self
.search_lbl
.pack(side
='left')
2282 self
.search_ent
.pack(side
='right', fill
='x', expand
=1)
2283 if sys
.platform
!= 'win32': self
.stop_btn
.forget()
2284 self
.stop_btn
.config(state
='disabled')
2286 def select(self
, event
=None):
2287 self
.goto_btn
.config(state
='normal')
2289 def goto(self
, event
=None):
2290 selection
= self
.result_lst
.curselection()
2292 modname
= split(self
.result_lst
.get(selection
[0]))[0]
2293 self
.open(url
=self
.server
.url
+ modname
+ '.html')
2296 if not self
.expanded
: return
2297 self
.result_frm
.forget()
2298 self
.result_scr
.forget()
2299 self
.result_lst
.forget()
2300 self
.bigwidth
= self
.window
.winfo_width()
2301 self
.bigheight
= self
.window
.winfo_height()
2302 self
.window
.wm_geometry('%dx%d' % (self
.minwidth
, self
.minheight
))
2303 self
.window
.wm_minsize(self
.minwidth
, self
.minheight
)
2307 if self
.expanded
: return
2308 self
.result_frm
.pack(side
='bottom', fill
='x')
2309 self
.result_scr
.pack(side
='right', fill
='y')
2310 self
.result_lst
.pack(side
='top', fill
='both', expand
=1)
2311 self
.window
.wm_geometry('%dx%d' % (self
.bigwidth
, self
.bigheight
))
2312 self
.window
.wm_minsize(self
.minwidth
, self
.bigminheight
)
2315 def hide(self
, event
=None):
2322 # Tk will crash if pythonw.exe has an XP .manifest
2323 # file and the root has is not destroyed explicitly.
2324 # If the problem is ever fixed in Tk, the explicit
2331 except KeyboardInterrupt:
2334 # -------------------------------------------------- command-line interface
2337 return isinstance(x
, str) and find(x
, os
.sep
) >= 0
2340 """Command-line interface (looks at sys.argv to decide what to do)."""
2342 class BadUsage
: pass
2344 # Scripts don't get the current directory in their path by default
2345 # unless they are run with the '-m' switch
2346 if '' not in sys
.path
:
2347 scriptdir
= os
.path
.dirname(sys
.argv
[0])
2348 if scriptdir
in sys
.path
:
2349 sys
.path
.remove(scriptdir
)
2350 sys
.path
.insert(0, '.')
2353 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'gk:p:w')
2356 for opt
, val
in opts
:
2369 print 'pydoc server ready at %s' % server
.url
2371 print 'pydoc server stopped'
2372 serve(port
, ready
, stopped
)
2377 if not args
: raise BadUsage
2379 if ispath(arg
) and not os
.path
.exists(arg
):
2380 print 'file %r does not exist' % arg
2383 if ispath(arg
) and os
.path
.isfile(arg
):
2384 arg
= importfile(arg
)
2386 if ispath(arg
) and os
.path
.isdir(arg
):
2392 except ErrorDuringImport
, value
:
2395 except (getopt
.error
, BadUsage
):
2396 cmd
= os
.path
.basename(sys
.argv
[0])
2397 print """pydoc - the Python documentation tool
2400 Show text documentation on something. <name> may be the name of a
2401 Python keyword, topic, function, module, or package, or a dotted
2402 reference to a class or function within a module or module in a
2403 package. If <name> contains a '%s', it is used as the path to a
2404 Python source file to document. If name is 'keywords', 'topics',
2405 or 'modules', a listing of these things is displayed.
2408 Search for a keyword in the synopsis lines of all available modules.
2411 Start an HTTP server on the given port on the local machine. Port
2412 number 0 can be used to get an arbitrary unused port.
2415 Pop up a graphical interface for finding and serving documentation.
2418 Write out the HTML documentation for a module to a file in the current
2419 directory. If <name> contains a '%s', it is treated as a filename; if
2420 it names a directory, documentation is written for all the contents.
2421 """ % (cmd
, os
.sep
, cmd
, cmd
, cmd
, cmd
, os
.sep
)
2423 if __name__
== '__main__': cli()