Index: Lib/cgitb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cgitb.py,v retrieving revision 1.4 diff -c -r1.4 cgitb.py *** Lib/cgitb.py 19 Dec 2001 14:27:41 -0000 1.4 --- Lib/cgitb.py 16 Jun 2002 05:06:11 -0000 *************** *** 148,177 **** --> ''' % ''.join(traceback.format_exception(etype, evalue, etb)) class Hook: """A hook to replace sys.excepthook that shows tracebacks in HTML.""" ! def __init__(self, display=1, logdir=None, context=5, file=None): self.display = display # send tracebacks to browser if true self.logdir = logdir # log tracebacks to files if not None self.context = context # number of source code lines per frame self.file = file or sys.stdout # place to send the output def __call__(self, etype, evalue, etb): self.handle((etype, evalue, etb)) def handle(self, info=None): info = info or sys.exc_info() ! self.file.write(reset()) try: ! text, doc = 0, html(info, self.context) except: # just in case something goes wrong import traceback ! text, doc = 1, ''.join(traceback.format_exception(*info)) if self.display: ! if text: doc = doc.replace('&', '&').replace('<', '<') self.file.write('
' + doc + '
\n') else: --- 148,253 ---- --> ''' % ''.join(traceback.format_exception(etype, evalue, etb)) + def text((etype, evalue, etb), context=5): + """Return a plain text document describing a given traceback.""" + import os, types, time, traceback, linecache, inspect, pydoc + + if type(etype) is types.ClassType: + etype = etype.__name__ + pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable + date = time.ctime(time.time()) + head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + ''' + A problem occurred in a Python script. Here is the sequence of + function calls leading up to the error, in the order they occurred. + ''' + + indent = ' ' * 5 + ' ' + frames = [] + records = inspect.getinnerframes(etb, context) + for frame, file, lnum, func, lines, index in records: + file = file and os.path.abspath(file) or '?' + args, varargs, varkw, locals = inspect.getargvalues(frame) + call = '' + if func != '?': + call = 'in ' + func + \ + inspect.formatargvalues(args, varargs, varkw, locals, + formatvalue=lambda value: '=' + pydoc.text.repr(value)) + + highlight = {} + def reader(lnum=[lnum]): + highlight[lnum[0]] = 1 + try: return linecache.getline(file, lnum[0]) + finally: lnum[0] += 1 + vars = scanvars(reader, frame, locals) + + rows = [' %s %s' % (file, call)] + if index is not None: + i = lnum - index + for line in lines: + num = '%5d ' % i + rows.append(num+line.rstrip()) + i += 1 + + done, dump = {}, [] + for name, where, value in vars: + if name in done: continue + done[name] = 1 + if value is not __UNDEF__: + if where == 'global': name = 'global ' + name + elif where == 'local': name = name + else: name = where + name.split('.')[-1] + dump.append('%s = %s' % (name, pydoc.text.repr(value))) + else: + dump.append(name + ' undefined') + + rows.append('\n'.join(dump)) + frames.append('\n%s\n' % '\n'.join(rows)) + + exception = ['%s: %s' % (str(etype), str(evalue))] + if type(evalue) is types.InstanceType: + for name in dir(evalue): + value = pydoc.text.repr(getattr(evalue, name)) + exception.append('\n%s%s =\n%s' % (indent, name, value)) + + import traceback + return head + ''.join(frames) + ''.join(exception) + ''' + + The above is a description of an error in a Python program. Here is + the original traceback: + + %s + ''' % ''.join(traceback.format_exception(etype, evalue, etb)) + class Hook: """A hook to replace sys.excepthook that shows tracebacks in HTML.""" ! def __init__(self, display=1, logdir=None, context=5, file=None, ! format="html"): self.display = display # send tracebacks to browser if true self.logdir = logdir # log tracebacks to files if not None self.context = context # number of source code lines per frame self.file = file or sys.stdout # place to send the output + self.format = format def __call__(self, etype, evalue, etb): self.handle((etype, evalue, etb)) def handle(self, info=None): info = info or sys.exc_info() ! if self.format == "html": ! self.file.write(reset()) + formatter = (self.format=="html") and html or text + plain = 0 try: ! doc = formatter(info, self.context) except: # just in case something goes wrong import traceback ! doc = ''.join(traceback.format_exception(*info)) ! plain = 1 if self.display: ! if plain: doc = doc.replace('&', '&').replace('<', '<') self.file.write('
' + doc + '
\n') else: *************** *** 181,187 **** if self.logdir is not None: import os, tempfile ! name = tempfile.mktemp(['.html', '.txt'][text]) path = os.path.join(self.logdir, os.path.basename(name)) try: file = open(path, 'w') --- 257,263 ---- if self.logdir is not None: import os, tempfile ! name = tempfile.mktemp(['.txt', '.html'][self.format=="html"]) path = os.path.join(self.logdir, os.path.basename(name)) try: file = open(path, 'w') *************** *** 196,205 **** except: pass handler = Hook().handle ! def enable(display=1, logdir=None, context=5): """Install an exception handler that formats tracebacks as HTML. The optional argument 'display' can be set to 0 to suppress sending the traceback to the browser, and 'logdir' can be set to a directory to cause tracebacks to be written to files there.""" ! sys.excepthook = Hook(display, logdir, context) --- 272,282 ---- except: pass handler = Hook().handle ! def enable(display=1, logdir=None, context=5, format="html"): """Install an exception handler that formats tracebacks as HTML. The optional argument 'display' can be set to 0 to suppress sending the traceback to the browser, and 'logdir' can be set to a directory to cause tracebacks to be written to files there.""" ! sys.excepthook = Hook(display=display, logdir=logdir, ! context=context, format=format) Index: Doc/lib/libcgitb.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcgitb.tex,v retrieving revision 1.3 diff -c -r1.3 libcgitb.tex *** Doc/lib/libcgitb.tex 20 Dec 2001 17:13:09 -0000 1.3 --- Doc/lib/libcgitb.tex 16 Jun 2002 05:06:11 -0000 *************** *** 12,20 **** \index{exceptions!in CGI scripts} \index{tracebacks!in CGI scripts} ! The \module{cgitb} module provides a special exception handler for CGI ! scripts. After this module is activated, if an uncaught exception occurs, ! a detailed, formatted report will be sent to the Web browser. The report includes a traceback showing excerpts of the source code for each level, as well as the values of the arguments and local variables to currently running functions, to help you debug the problem. Optionally, you can --- 12,23 ---- \index{exceptions!in CGI scripts} \index{tracebacks!in CGI scripts} ! The \module{cgitb} module provides a special exception handler for Python ! scripts. (It's name is a bit misleading. It was originally designed to ! display extensive traceback information in HTML for CGI scripts. It was ! later generalized to also display this information in plain text.) After ! this module is activated, if an uncaught exception occurs, a detailed, ! formatted report will be displayed. The report includes a traceback showing excerpts of the source code for each level, as well as the values of the arguments and local variables to currently running functions, to help you debug the problem. Optionally, you can *************** *** 32,38 **** \begin{funcdesc}{enable}{\optional{display\optional{, logdir\optional{, ! context}}}} This function causes the \module{cgitb} module to take over the interpreter's default handling for exceptions by setting the value of \code{\refmodule{sys}.excepthook}. --- 35,41 ---- \begin{funcdesc}{enable}{\optional{display\optional{, logdir\optional{, ! context\optional{, format}}}}} This function causes the \module{cgitb} module to take over the interpreter's default handling for exceptions by setting the value of \code{\refmodule{sys}.excepthook}. *************** *** 46,51 **** --- 49,57 ---- The optional argument \var{context} is the number of lines of context to display around the current line of source code in the traceback; this defaults to \code{5}. + If the optional argument \var{format} is \code{"html"}, the output is + formatted as HTML. Any other value forces plain text output. The default + value is \code{"html"} \end{funcdesc} \begin{funcdesc}{handler}{\optional{info}}