import pdb; import sys; import linecache class qdebug: def __init__(self, options = None, expanded = None, typeformats = None, individualformats = None, watchers = None): self.options = options self.expandedINames = expanded self.typeformats = typeformats self.individualformats = individualformats self.watchers = watchers if self.options == "listmodules": self.handleListModules() elif self.options == "listsymbols": self.handleListSymbols(expanded) else: self.handleListVars() def put(self, value): sys.stdout.write(value) def putField(self, name, value): self.put('%s="%s",' % (name, value)) def putItemCount(self, count): self.put('value="<%s items>",' % count) def putEllipsis(self): self.put('{name="",value="",type="",numchild="0"},') def cleanType(self, type): t = str(type) if t.startswith(""): t = t[7:-2] if t.startswith(""): t = t[8:-2] return t def putType(self, type, priority = 0): self.putField("type", self.cleanType(type)) def putAddress(self, addr): self.put('addr="%s",' % cleanAddress(addr)) def putNumChild(self, numchild): self.put('numchild="%s",' % numchild) def putValue(self, value, encoding = None, priority = 0): self.putField("value", value) def putName(self, name): self.put('name="%s",' % name) def isExpanded(self, iname): #self.warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames)) if iname.startswith("None"): raise "Illegal iname '%s'" % iname #self.warn(" --> %s" % (iname in self.expandedINames)) return iname in self.expandedINames def isExpandedIName(self, iname): return iname in self.expandedINames def itemFormat(self, item): format = self.formats.get(str(cleanAddress(item.value.address))) if format is None: format = self.typeformats.get(stripClassTag(str(item.value.type))) return format def dumpFrame(self, frame): for var in frame.f_locals.keys(): if var == "__file__": continue #if var == "__name__": # continue if var == "__package__": continue if var == "qdebug": continue if var != '__builtins__': value = frame.f_locals[var] self.dumpValue(value, var, "local.%s" % var) def dumpValue(self, value, name, iname): t = type(value) tt = self.cleanType(t) if tt == "module" or tt == "function": return if str(value).startswith(" 1: v = "@" + v[p + 11:-1] self.putValue(v) if self.isExpanded(iname): self.put("children=[") for child in dir(value): if child == "__dict__": continue if child == "__doc__": continue if child == "__module__": continue attr = getattr(value, child) if callable(attr): continue try: self.dumpValue(attr, child, "%s.%s" % (iname, child)) except: pass self.put("],") self.put("},") def warn(self, msg): self.putField("warning", msg) def handleListVars(self): # Trigger error to get a backtrace. frame = None #self.warn("frame: %s" % frame) try: raise ZeroDivisionError except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame.f_back limit = 30 n = 0 isActive = False while frame is not None and n < limit: #self.warn("frame: %s" % frame.f_locals.keys()) lineno = frame.f_lineno code = frame.f_code filename = code.co_filename name = code.co_name if isActive: linecache.checkcache(filename) line = linecache.getline(filename, lineno, frame.f_globals) self.dumpFrame(frame) if name == "": isActive = False if name == "trace_dispatch": isActive = True frame = frame.f_back n = n + 1 sys.stdout.flush() def handleListModules(self): self.put("modules=["); for name in sys.modules: self.put("{") self.putName(name) self.putValue(sys.modules[name]) self.put("},") self.put("]") sys.stdout.flush() def handleListSymbols(self, module): #self.put("symbols=%s" % dir(sys.modules[module])) self.put("symbols=["); for name in sys.modules: self.put("{") self.putName(name) #self.putValue(sys.modules[name]) self.put("},") self.put("]") sys.stdout.flush()