|
| 1 | +# $Id: cgitb.py,v 1.1 2001-07-22 11:58:35 richard Exp $ |
| 2 | + |
| 3 | +import sys, os, types, string, keyword, linecache, tokenize, inspect, pydoc |
| 4 | + |
| 5 | +def breaker(): |
| 6 | + return ('<body bgcolor="#f0f0ff">' + |
| 7 | + '<font color="#f0f0ff" size="-5"> > </font> ' + |
| 8 | + '</table>' * 5) |
| 9 | + |
| 10 | +def html(context=5): |
| 11 | + etype, evalue = sys.exc_type, sys.exc_value |
| 12 | + if type(etype) is types.ClassType: |
| 13 | + etype = etype.__name__ |
| 14 | + pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable |
| 15 | + head = pydoc.html.heading( |
| 16 | + '<font size=+1><strong>%s</strong>: %s</font>'%(str(etype), str(evalue)), |
| 17 | + '#ffffff', '#aa55cc', pyver) |
| 18 | + |
| 19 | + head = head + ('<p>A problem occurred while running a Python script. ' |
| 20 | + 'Here is the sequence of function calls leading up to ' |
| 21 | + 'the error, with the most recent (innermost) call first. ' |
| 22 | + 'The exception attributes are:') |
| 23 | + |
| 24 | + indent = '<tt><small>%s</small> </tt>' % (' ' * 5) |
| 25 | + traceback = [] |
| 26 | + for frame, file, lnum, func, lines, index in inspect.trace(context): |
| 27 | + if file is None: |
| 28 | + link = '<file is None - probably inside <tt>eval</tt> or <tt>exec</tt>>' |
| 29 | + else: |
| 30 | + file = os.path.abspath(file) |
| 31 | + link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file)) |
| 32 | + args, varargs, varkw, locals = inspect.getargvalues(frame) |
| 33 | + if func == '?': |
| 34 | + call = '' |
| 35 | + else: |
| 36 | + call = 'in <strong>%s</strong>' % func + inspect.formatargvalues( |
| 37 | + args, varargs, varkw, locals, |
| 38 | + formatvalue=lambda value: '=' + pydoc.html.repr(value)) |
| 39 | + |
| 40 | + level = ''' |
| 41 | +<table width="100%%" bgcolor="#d8bbff" cellspacing=0 cellpadding=2 border=0> |
| 42 | +<tr><td>%s %s</td></tr></table>''' % (link, call) |
| 43 | + |
| 44 | + if file is None: |
| 45 | + traceback.append('<p>' + level) |
| 46 | + continue |
| 47 | + |
| 48 | + # do a fil inspection |
| 49 | + names = [] |
| 50 | + def tokeneater(type, token, start, end, line, names=names): |
| 51 | + if type == tokenize.NAME and token not in keyword.kwlist: |
| 52 | + if token not in names: |
| 53 | + names.append(token) |
| 54 | + if type == tokenize.NEWLINE: raise IndexError |
| 55 | + def linereader(file=file, lnum=[lnum]): |
| 56 | + line = linecache.getline(file, lnum[0]) |
| 57 | + lnum[0] = lnum[0] + 1 |
| 58 | + return line |
| 59 | + |
| 60 | + try: |
| 61 | + tokenize.tokenize(linereader, tokeneater) |
| 62 | + except IndexError: pass |
| 63 | + lvals = [] |
| 64 | + for name in names: |
| 65 | + if name in frame.f_code.co_varnames: |
| 66 | + if locals.has_key(name): |
| 67 | + value = pydoc.html.repr(locals[name]) |
| 68 | + else: |
| 69 | + value = '<em>undefined</em>' |
| 70 | + name = '<strong>%s</strong>' % name |
| 71 | + else: |
| 72 | + if frame.f_globals.has_key(name): |
| 73 | + value = pydoc.html.repr(frame.f_globals[name]) |
| 74 | + else: |
| 75 | + value = '<em>undefined</em>' |
| 76 | + name = '<em>global</em> <strong>%s</strong>' % name |
| 77 | + lvals.append('%s = %s' % (name, value)) |
| 78 | + if lvals: |
| 79 | + lvals = string.join(lvals, ', ') |
| 80 | + lvals = indent + ''' |
| 81 | +<small><font color="#909090">%s</font></small><br>''' % lvals |
| 82 | + else: |
| 83 | + lvals = '' |
| 84 | + |
| 85 | + excerpt = [] |
| 86 | + i = lnum - index |
| 87 | + for line in lines: |
| 88 | + number = ' ' * (5-len(str(i))) + str(i) |
| 89 | + number = '<small><font color="#909090">%s</font></small>' % number |
| 90 | + line = '<tt>%s %s</tt>' % (number, pydoc.html.preformat(line)) |
| 91 | + if i == lnum: |
| 92 | + line = ''' |
| 93 | +<table width="100%%" bgcolor="#ffccee" cellspacing=0 cellpadding=0 border=0> |
| 94 | +<tr><td>%s</td></tr></table>''' % line |
| 95 | + excerpt.append('\n' + line) |
| 96 | + if i == lnum: |
| 97 | + excerpt.append(lvals) |
| 98 | + i = i + 1 |
| 99 | + traceback.append('<p>' + level + string.join(excerpt, '\n')) |
| 100 | + |
| 101 | + traceback.reverse() |
| 102 | + |
| 103 | + exception = '<p><strong>%s</strong>: %s' % (str(etype), str(evalue)) |
| 104 | + attribs = [] |
| 105 | + if type(evalue) is types.InstanceType: |
| 106 | + for name in dir(evalue): |
| 107 | + value = pydoc.html.repr(getattr(evalue, name)) |
| 108 | + attribs.append('<br>%s%s = %s' % (indent, name, value)) |
| 109 | + |
| 110 | + return head + string.join(attribs) + string.join(traceback) + '<p> </p>' |
| 111 | + |
| 112 | +def handler(): |
| 113 | + print breaker() |
| 114 | + print html() |
| 115 | + |
| 116 | +# |
| 117 | +# $Log: not supported by cvs2svn $ |
| 118 | +# Revision 1.3 2001/07/19 06:27:07 anthonybaxter |
| 119 | +# fixing (manually) the (dollarsign)Log(dollarsign) entries caused by |
| 120 | +# my using the magic (dollarsign)Id(dollarsign) and (dollarsign)Log(dollarsign) |
| 121 | +# strings in a commit message. I'm a twonk. |
| 122 | +# |
| 123 | +# Also broke the help string in two. |
| 124 | +# |
| 125 | +# Revision 1.2 2001/07/19 05:52:22 anthonybaxter |
| 126 | +# Added CVS keywords Id and Log to all python files. |
| 127 | +# |
| 128 | +# |
0 commit comments