home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Mac / Tools / IDE / Wtraceback.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  5.2 KB  |  189 lines

  1. import traceback
  2. import sys
  3. import W
  4. import os
  5. import types
  6. import List
  7.  
  8.  
  9. class TraceBack:
  10.     
  11.     def __init__(self, title = "Traceback"):
  12.         app = W.getapplication()  # checks if W is properly initialized
  13.         self.title = title
  14.         self.w = None
  15.         self.closed = 1
  16.         self.start = 0
  17.         self.lastwindowtitle = ""
  18.         self.bounds = (360, 298)
  19.     
  20.     def traceback(self, start = 0, lastwindowtitle = ""):
  21.         try:
  22.             self.lastwindowtitle = lastwindowtitle
  23.             self.start = start
  24.             self.type, self.value, self.tb = sys.exc_type, sys.exc_value, sys.exc_traceback
  25.             if self.type is not SyntaxError:
  26.                 self.show()
  27.                 if type(self.type) == types.ClassType:
  28.                     errortext = self.type.__name__
  29.                 else:
  30.                     errortext = str(self.type)
  31.                 value = str(self.value)
  32.                 if self.value and value:
  33.                     errortext = errortext + ": " + value
  34.                 self.w.text.set(errortext)
  35.                 self.buildtblist()
  36.                 self.w.list.set(self.textlist)
  37.                 self.w.list.setselection([len(self.textlist) - 1])
  38.                 self.w.wid.SelectWindow()
  39.                 self.closed = 0
  40.             else:
  41.                 self.syntaxerror()
  42.         except:
  43.             traceback.print_exc()
  44.     
  45.     def syntaxerror(self):
  46.         try:
  47.             value, (filename, lineno, charno, line) = self.value
  48.         except:
  49.             filename = ""
  50.             lineno = None
  51.             value = self.value
  52.         if not filename and self.lastwindowtitle:
  53.             filename = self.lastwindowtitle
  54.         elif not filename:
  55.             filename = "<unknown>"
  56.         if filename and os.path.exists(filename):
  57.             filename = os.path.split(filename)[1]
  58.         if lineno:
  59.             charno = charno - 1
  60.             text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "•" + line[charno:-1]
  61.         else:
  62.             text = str(value) + '\rFile: "' + str(filename) + '"'
  63.         self.syntaxdialog = W.ModalDialog((360, 120), "Syntax Error")
  64.         self.syntaxdialog.text = W.TextBox((10, 10, -10, -40), text)
  65.         self.syntaxdialog.cancel = W.Button((-190, -32, 80, 16), "Cancel", self.syntaxclose)
  66.         self.syntaxdialog.edit = W.Button((-100, -32, 80, 16), "Edit", self.syntaxedit)
  67.         self.syntaxdialog.setdefaultbutton(self.syntaxdialog.edit)
  68.         self.syntaxdialog.bind("cmd.", self.syntaxdialog.cancel.push)
  69.         self.syntaxdialog.open()
  70.     
  71.     def syntaxclose(self):
  72.         self.syntaxdialog.close()
  73.         del self.syntaxdialog
  74.     
  75.     def syntaxedit(self):
  76.         try:
  77.             value, (filename, lineno, charno, line) = self.value
  78.         except:
  79.             filename = ""
  80.             lineno = None
  81.         if not filename and self.lastwindowtitle:
  82.             filename = self.lastwindowtitle
  83.         elif not filename:
  84.             filename = "<unknown>"
  85.         self.syntaxclose()
  86.         if lineno:
  87.             W.getapplication().openscript(filename, lineno, charno - 1)
  88.         else:
  89.             W.getapplication().openscript(filename)
  90.     
  91.     def show(self):
  92.         if self.closed:
  93.             self.setupwidgets()
  94.             self.w.open()
  95.         else:
  96.             self.w.wid.ShowWindow()
  97.             self.w.wid.SelectWindow()
  98.     
  99.     def hide(self):
  100.         if self.closed:
  101.             return
  102.         self.w.close()
  103.     
  104.     def close(self):
  105.         self.bounds = self.w.getbounds()
  106.         self.closed = 1
  107.         self.type, self.value, self.tb = None, None, None
  108.         self.tblist = None
  109.     
  110.     def activate(self, onoff):
  111.         if onoff:
  112.             if self.closed:
  113.                 self.traceback()
  114.             self.closed = 0
  115.             self.checkbuttons()
  116.     
  117.     def setupwidgets(self):
  118.         self.w = W.Window(self.bounds, self.title, minsize = (316, 168))
  119.         self.w.text = W.TextBox((10, 10, -10, 30))
  120.         self.w.tbtitle = W.TextBox((10, 40, -10, 10), "Traceback (innermost last):")
  121.         self.w.list = W.TwoLineList((10, 60, -10, -40), callback = self.listhit)
  122.         
  123.         self.w.editbutton = W.Button((10, -30, 60, 16), "Edit", self.edit)
  124.         self.w.editbutton.enable(0)
  125.         
  126.         self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse locals…", self.browselocals)
  127.         self.w.browselocalsbutton.enable(0)
  128.         
  129.         self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortem…", self.postmortem)
  130.         
  131.         self.w.setdefaultbutton(self.w.editbutton)
  132.         self.w.bind("cmdb", self.w.browselocalsbutton.push)
  133.         self.w.bind("<close>", self.close)
  134.         self.w.bind("<activate>", self.activate)
  135.     
  136.     def buildtblist(self):
  137.         tb = self.tb
  138.         for i in range(self.start):
  139.             if tb.tb_next is None:
  140.                 break
  141.             tb = tb.tb_next
  142.         self.tblist = traceback.extract_tb(tb)
  143.         self.textlist = []
  144.         for filename, lineno, func, line in self.tblist:
  145.             tbline = ""
  146.             if os.path.exists(filename):
  147.                 filename = os.path.split(filename)[1]
  148.                 tbline = 'File "' + filename + '", line ' + `lineno` + ', in ' + func
  149.             else:
  150.                 tbline = 'File "' + filename + '", line ' + `lineno` + ', in ' + func
  151.             if line:
  152.                 tbline = tbline + '\r      ' + line
  153.             self.textlist.append(tbline[:255])
  154.     
  155.     def edit(self):
  156.         sel = self.w.list.getselection()
  157.         for i in sel:
  158.             filename, lineno, func, line = self.tblist[i]
  159.             W.getapplication().openscript(filename, lineno)
  160.     
  161.     def browselocals(self):
  162.         sel = self.w.list.getselection()
  163.         for i in sel:
  164.             tb = self.tb
  165.             for j in range(i + self.start):
  166.                 tb = tb.tb_next
  167.             self.browse(tb.tb_frame.f_locals)
  168.     
  169.     def browse(self, object):
  170.         import PyBrowser
  171.         PyBrowser.Browser(object)
  172.     
  173.     def postmortem(self):
  174.         import PyDebugger
  175.         PyDebugger.postmortem(self.type, self.value, self.tb)
  176.     
  177.     def listhit(self, isdbl):
  178.         if isdbl:
  179.             self.w.editbutton.push()
  180.         else:
  181.             self.checkbuttons()
  182.     
  183.     def checkbuttons(self):
  184.         havefile = len(self.w.list.getselection()) > 0
  185.         self.w.editbutton.enable(havefile)
  186.         self.w.browselocalsbutton.enable(havefile)
  187.         self.w.setdefaultbutton(havefile and self.w.editbutton or self.w.postmortembutton)
  188.  
  189.