PyXR

c:\python24\lib \ cgitb.py



0001 """More comprehensive traceback formatting for Python scripts.
0002 
0003 To enable this module, do:
0004 
0005     import cgitb; cgitb.enable()
0006 
0007 at the top of your script.  The optional arguments to enable() are:
0008 
0009     display     - if true, tracebacks are displayed in the web browser
0010     logdir      - if set, tracebacks are written to files in this directory
0011     context     - number of lines of source code to show for each stack frame
0012     format      - 'text' or 'html' controls the output format
0013 
0014 By default, tracebacks are displayed but not saved, the context is 5 lines
0015 and the output format is 'html' (for backwards compatibility with the
0016 original use of this module)
0017 
0018 Alternatively, if you have caught an exception and want cgitb to display it
0019 for you, call cgitb.handler().  The optional argument to handler() is a
0020 3-item tuple (etype, evalue, etb) just like the value of sys.exc_info().
0021 The default handler displays output as HTML.
0022 """
0023 
0024 __author__ = 'Ka-Ping Yee'
0025 __version__ = '$Revision: 1.15 $'
0026 
0027 import sys
0028 
0029 def reset():
0030     """Return a string that resets the CGI and browser to a known state."""
0031     return '''<!--: spam
0032 Content-Type: text/html
0033 
0034 <body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> -->
0035 <body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> -->
0036 </font> </font> </font> </script> </object> </blockquote> </pre>
0037 </table> </table> </table> </table> </table> </font> </font> </font>'''
0038 
0039 __UNDEF__ = []                          # a special sentinel object
0040 def small(text):
0041     if text:
0042         return '<small>' + text + '</small>'
0043     else:
0044         return ''
0045 
0046 def strong(text):
0047     if text:
0048         return '<strong>' + text + '</strong>'
0049     else:
0050         return ''
0051 
0052 def grey(text):
0053     if text:
0054         return '<font color="#909090">' + text + '</font>'
0055     else:
0056         return ''
0057 
0058 def lookup(name, frame, locals):
0059     """Find the value for a given name in the given environment."""
0060     if name in locals:
0061         return 'local', locals[name]
0062     if name in frame.f_globals:
0063         return 'global', frame.f_globals[name]
0064     if '__builtins__' in frame.f_globals:
0065         builtins = frame.f_globals['__builtins__']
0066         if type(builtins) is type({}):
0067             if name in builtins:
0068                 return 'builtin', builtins[name]
0069         else:
0070             if hasattr(builtins, name):
0071                 return 'builtin', getattr(builtins, name)
0072     return None, __UNDEF__
0073 
0074 def scanvars(reader, frame, locals):
0075     """Scan one logical line of Python and look up values of variables used."""
0076     import tokenize, keyword
0077     vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__
0078     for ttype, token, start, end, line in tokenize.generate_tokens(reader):
0079         if ttype == tokenize.NEWLINE: break
0080         if ttype == tokenize.NAME and token not in keyword.kwlist:
0081             if lasttoken == '.':
0082                 if parent is not __UNDEF__:
0083                     value = getattr(parent, token, __UNDEF__)
0084                     vars.append((prefix + token, prefix, value))
0085             else:
0086                 where, value = lookup(token, frame, locals)
0087                 vars.append((token, where, value))
0088         elif token == '.':
0089             prefix += lasttoken + '.'
0090             parent = value
0091         else:
0092             parent, prefix = None, ''
0093         lasttoken = token
0094     return vars
0095 
0096 def html((etype, evalue, etb), context=5):
0097     """Return a nice HTML document describing a given traceback."""
0098     import os, types, time, traceback, linecache, inspect, pydoc
0099 
0100     if type(etype) is types.ClassType:
0101         etype = etype.__name__
0102     pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
0103     date = time.ctime(time.time())
0104     head = '<body bgcolor="#f0f0f8">' + pydoc.html.heading(
0105         '<big><big>%s</big></big>' %
0106         strong(pydoc.html.escape(str(etype))),
0107         '#ffffff', '#6622aa', pyver + '<br>' + date) + '''
0108 <p>A problem occurred in a Python script.  Here is the sequence of
0109 function calls leading up to the error, in the order they occurred.</p>'''
0110 
0111     indent = '<tt>' + small('&nbsp;' * 5) + '&nbsp;</tt>'
0112     frames = []
0113     records = inspect.getinnerframes(etb, context)
0114     for frame, file, lnum, func, lines, index in records:
0115         file = file and os.path.abspath(file) or '?'
0116         link = '<a href="file://%s">%s</a>' % (file, pydoc.html.escape(file))
0117         args, varargs, varkw, locals = inspect.getargvalues(frame)
0118         call = ''
0119         if func != '?':
0120             call = 'in ' + strong(func) + \
0121                 inspect.formatargvalues(args, varargs, varkw, locals,
0122                     formatvalue=lambda value: '=' + pydoc.html.repr(value))
0123 
0124         highlight = {}
0125         def reader(lnum=[lnum]):
0126             highlight[lnum[0]] = 1
0127             try: return linecache.getline(file, lnum[0])
0128             finally: lnum[0] += 1
0129         vars = scanvars(reader, frame, locals)
0130 
0131         rows = ['<tr><td bgcolor="#d8bbff">%s%s %s</td></tr>' %
0132                 ('<big>&nbsp;</big>', link, call)]
0133         if index is not None:
0134             i = lnum - index
0135             for line in lines:
0136                 num = small('&nbsp;' * (5-len(str(i))) + str(i)) + '&nbsp;'
0137                 line = '<tt>%s%s</tt>' % (num, pydoc.html.preformat(line))
0138                 if i in highlight:
0139                     rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line)
0140                 else:
0141                     rows.append('<tr><td>%s</td></tr>' % grey(line))
0142                 i += 1
0143 
0144         done, dump = {}, []
0145         for name, where, value in vars:
0146             if name in done: continue
0147             done[name] = 1
0148             if value is not __UNDEF__:
0149                 if where in ['global', 'builtin']:
0150                     name = ('<em>%s</em> ' % where) + strong(name)
0151                 elif where == 'local':
0152                     name = strong(name)
0153                 else:
0154                     name = where + strong(name.split('.')[-1])
0155                 dump.append('%s&nbsp;= %s' % (name, pydoc.html.repr(value)))
0156             else:
0157                 dump.append(name + ' <em>undefined</em>')
0158 
0159         rows.append('<tr><td>%s</td></tr>' % small(grey(', '.join(dump))))
0160         frames.append('''
0161 <table width="100%%" cellspacing=0 cellpadding=0 border=0>
0162 %s</table>''' % '\n'.join(rows))
0163 
0164     exception = ['<p>%s: %s' % (strong(pydoc.html.escape(str(etype))),
0165                                 pydoc.html.escape(str(evalue)))]
0166     if type(evalue) is types.InstanceType:
0167         for name in dir(evalue):
0168             if name[:1] == '_': continue
0169             value = pydoc.html.repr(getattr(evalue, name))
0170             exception.append('\n<br>%s%s&nbsp;=\n%s' % (indent, name, value))
0171 
0172     import traceback
0173     return head + ''.join(frames) + ''.join(exception) + '''
0174 
0175 
0176 <!-- The above is a description of an error in a Python program, formatted
0177      for a Web browser because the 'cgitb' module was enabled.  In case you
0178      are not reading this in a Web browser, here is the original traceback:
0179 
0180 %s
0181 -->
0182 ''' % ''.join(traceback.format_exception(etype, evalue, etb))
0183 
0184 def text((etype, evalue, etb), context=5):
0185     """Return a plain text document describing a given traceback."""
0186     import os, types, time, traceback, linecache, inspect, pydoc
0187 
0188     if type(etype) is types.ClassType:
0189         etype = etype.__name__
0190     pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
0191     date = time.ctime(time.time())
0192     head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + '''
0193 A problem occurred in a Python script.  Here is the sequence of
0194 function calls leading up to the error, in the order they occurred.
0195 '''
0196 
0197     frames = []
0198     records = inspect.getinnerframes(etb, context)
0199     for frame, file, lnum, func, lines, index in records:
0200         file = file and os.path.abspath(file) or '?'
0201         args, varargs, varkw, locals = inspect.getargvalues(frame)
0202         call = ''
0203         if func != '?':
0204             call = 'in ' + func + \
0205                 inspect.formatargvalues(args, varargs, varkw, locals,
0206                     formatvalue=lambda value: '=' + pydoc.text.repr(value))
0207 
0208         highlight = {}
0209         def reader(lnum=[lnum]):
0210             highlight[lnum[0]] = 1
0211             try: return linecache.getline(file, lnum[0])
0212             finally: lnum[0] += 1
0213         vars = scanvars(reader, frame, locals)
0214 
0215         rows = [' %s %s' % (file, call)]
0216         if index is not None:
0217             i = lnum - index
0218             for line in lines:
0219                 num = '%5d ' % i
0220                 rows.append(num+line.rstrip())
0221                 i += 1
0222 
0223         done, dump = {}, []
0224         for name, where, value in vars:
0225             if name in done: continue
0226             done[name] = 1
0227             if value is not __UNDEF__:
0228                 if where == 'global': name = 'global ' + name
0229                 elif where != 'local': name = where + name.split('.')[-1]
0230                 dump.append('%s = %s' % (name, pydoc.text.repr(value)))
0231             else:
0232                 dump.append(name + ' undefined')
0233 
0234         rows.append('\n'.join(dump))
0235         frames.append('\n%s\n' % '\n'.join(rows))
0236 
0237     exception = ['%s: %s' % (str(etype), str(evalue))]
0238     if type(evalue) is types.InstanceType:
0239         for name in dir(evalue):
0240             value = pydoc.text.repr(getattr(evalue, name))
0241             exception.append('\n%s%s = %s' % (" "*4, name, value))
0242 
0243     import traceback
0244     return head + ''.join(frames) + ''.join(exception) + '''
0245 
0246 The above is a description of an error in a Python program.  Here is
0247 the original traceback:
0248 
0249 %s
0250 ''' % ''.join(traceback.format_exception(etype, evalue, etb))
0251 
0252 class Hook:
0253     """A hook to replace sys.excepthook that shows tracebacks in HTML."""
0254 
0255     def __init__(self, display=1, logdir=None, context=5, file=None,
0256                  format="html"):
0257         self.display = display          # send tracebacks to browser if true
0258         self.logdir = logdir            # log tracebacks to files if not None
0259         self.context = context          # number of source code lines per frame
0260         self.file = file or sys.stdout  # place to send the output
0261         self.format = format
0262 
0263     def __call__(self, etype, evalue, etb):
0264         self.handle((etype, evalue, etb))
0265 
0266     def handle(self, info=None):
0267         info = info or sys.exc_info()
0268         if self.format == "html":
0269             self.file.write(reset())
0270 
0271         formatter = (self.format=="html") and html or text
0272         plain = False
0273         try:
0274             doc = formatter(info, self.context)
0275         except:                         # just in case something goes wrong
0276             import traceback
0277             doc = ''.join(traceback.format_exception(*info))
0278             plain = True
0279 
0280         if self.display:
0281             if plain:
0282                 doc = doc.replace('&', '&amp;').replace('<', '&lt;')
0283                 self.file.write('<pre>' + doc + '</pre>\n')
0284             else:
0285                 self.file.write(doc + '\n')
0286         else:
0287             self.file.write('<p>A problem occurred in a Python script.\n')
0288 
0289         if self.logdir is not None:
0290             import os, tempfile
0291             suffix = ['.txt', '.html'][self.format=="html"]
0292             (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir)
0293             try:
0294                 file = os.fdopen(fd, 'w')
0295                 file.write(doc)
0296                 file.close()
0297                 msg = '<p> %s contains the description of this error.' % path
0298             except:
0299                 msg = '<p> Tried to save traceback to %s, but failed.' % path
0300             self.file.write(msg + '\n')
0301         try:
0302             self.file.flush()
0303         except: pass
0304 
0305 handler = Hook().handle
0306 def enable(display=1, logdir=None, context=5, format="html"):
0307     """Install an exception handler that formats tracebacks as HTML.
0308 
0309     The optional argument 'display' can be set to 0 to suppress sending the
0310     traceback to the browser, and 'logdir' can be set to a directory to cause
0311     tracebacks to be written to files there."""
0312     sys.excepthook = Hook(display=display, logdir=logdir,
0313                           context=context, format=format)
0314 

Generated by PyXR 0.9.4
SourceForge.net Logo