Viewing file: failure.py (6.51 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Copyright (c) 2004 Divmod. # See LICENSE for details.
# failure.py
import types import linecache import re
from nevow import tags as t from twisted.python import failure
stylesheet = """ p.error { color: black; font-family: Verdana, Arial, helvetica, sans-serif; font-weight: bold; font-size: large; margin: 0.25em; }
div { font-family: Verdana, Arial, helvetica, sans-serif; }
strong.variableClass { font-size: small; }
div.stackTrace { }
div.frame { padding: 0.25em; background: white; border-bottom: thin black dotted; }
div.firstFrame { padding: 0.25em; background: white; border-top: thin black dotted; border-bottom: thin black dotted; }
div.location { font-size: small; }
div.snippet { background: #FFFFDD; padding: 0.25em; }
div.snippetHighlightLine { color: red; }
span.lineno { font-size: small; }
pre.code { margin: 0px; padding: 0px; display: inline; font-size: small; font-family: "Courier New", courier, monotype; }
span.function { font-weight: bold; font-family: "Courier New", courier, monotype; }
table.variables { border-collapse: collapse; width: 100%; }
td.varName { width: 1in; vertical-align: top; font-style: italic; font-size: small; padding-right: 0.25em; }
td.varValue { padding-left: 0.25em; padding-right: 0.25em; font-size: small; }
div.variables { margin-top: 0.5em; }
div.dict { background: #cccc99; padding: 2px; float: left; }
td.dictKey { background: #ffff99; font-weight: bold; }
td.dictValue { background: #ffff99; }
div.list { background: #7777cc; padding: 2px; float: left; }
div.listItem { background: #9999ff; }
div.instance { width: 100%; background: #efefef; padding: 2px; float: left; }
span.instanceName { font-size: small; display: block; }
span.instanceRepr { font-family: "Courier New", courier, monotype; }
div.function { background: orange; font-weight: bold; float: left; } """
def saferepr(x): try: rx = repr(x) except: rx = "repr failed! %s instance at 0x%x" % (x.__class__, id(x)) return rx
def htmlDict(d): return t.div(_class="dict")[ t.span(_class="heading")[ "Dictionary instance @ 0x%x" % id(d) ], t.table(_class="dict")[[ t.tr[ t.td(_class="dictKey")[ k == '__builtins__' and 'builtin dictionary' or htmlrepr(k) ], t.td(_class="dictValue")[ htmlrepr(v) ] ] for k, v in d.items() ]] ]
def htmlList(l): return t.div(_class="list")[ t.span(_class="heading")[ "List instance @ 0x%x" % id(l) ], [t.div(_class="listItem")[ htmlrepr(i) ] for i in l] ]
def htmlInst(i): return t.div(_class="instance")[ t.span(_class="instanceName")[ "%s instance at 0x%x" % (i.__class__, id(i)) ], t.span(_class="instanceRepr")[ saferepr(i) ] ]
def htmlString(s): return s
def htmlFunc(f): return t.div(_class="function")[ "Function %s in file %s at line %s" % (f.__name__, f.func_code.co_filename, f.func_code.co_firstlineno) ]
def htmlMeth(m): return t.div(_class="method")[ "Method %s in file %s at line %s" % (m.im_func.__name__, m.im_func.func_code.co_filename, m.im_func.func_code.co_firstlineno) ]
def htmlUnknown(u): return t.pre[ saferepr(u) ]
htmlReprTypes = { types.DictType: htmlDict, types.ListType: htmlList, types.InstanceType: htmlInst, types.StringType: htmlString, types.FunctionType: htmlFunc, types.MethodType: htmlMeth, }
def htmlrepr(x): return htmlReprTypes.get(type(x), htmlUnknown)(x)
def varTable(usedVars): return t.table(_class="variables")[[ t.tr(_class="varRow")[ t.td(_class="varName")[ key ], t.td(_class="varValue")[ htmlrepr(value) ] ] for (key, value) in usedVars ]]
def formatFailure(myFailure): if not isinstance(myFailure, failure.Failure): return t.pre[ str(myFailure) ]
stackTrace = t.div(_class="stackTrace") failureOverview = t.p(_class="error")[ str(myFailure.type), ": ", str(myFailure.value) ]
result = [ t.style(type="text/css")[ stylesheet, ], t.a(href="#tracebackEnd")[ failureOverview ], stackTrace, t.a(name="tracebackEnd")[ failureOverview ] ]
first = 1 for method, filename, lineno, localVars, globalVars in myFailure.frames: # It's better to have a line number than nothing at all. #if filename == '<string>': # continue if first: frame = t.div(_class="firstFrame") first = 0 else: frame = t.div(_class="frame") stackTrace[ frame ]
snippet = t.div(_class="snippet") frame[ t.div(_class="location")[ filename, ", line ", lineno, " in ", t.span(_class="function")[ method ] ], snippet, ]
textSnippet = '' for snipLineNo in range(lineno-2, lineno+2): snipLine = linecache.getline(filename, snipLineNo) textSnippet += snipLine if snipLineNo == lineno: snippetClass = "snippetHighlightLine" else: snippetClass = "snippetLine" snippet[ t.div(_class=snippetClass)[ t.span(_class="lineno")[ snipLineNo ], t.pre(_class="code")[ snipLine ] ] ]
# Instance variables for name, var in localVars: if name == 'self' and hasattr(var, '__dict__'): usedVars = [ (key, value) for (key, value) in var.__dict__.items() if re.search(r'\Wself.%s\W' % (re.escape(key),), textSnippet) ] if usedVars: frame[ t.div(_class="variables")[ t.strong(_class="variableClass")[ "Self" ], varTable(usedVars) ] ] break
# Local and global vars for nm, varList in ('Locals', localVars), ('Globals', globalVars): usedVars = [ (name, var) for (name, var) in varList if re.search(r'\W%s\W' % (re.escape(name),), textSnippet) ] if usedVars: frame[ t.div(_class="variables")[ t.strong(_class="variableClass")[ nm ] ], varTable(usedVars) ]
return result
|