wdb.py :  » Mobile » Python-for-PalmOS » Python-1.5.2+reduced-1.0 » Lib » lib-stdwin » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Mobile » Python for PalmOS 
Python for PalmOS » Python 1.5.2 reduced 1.0 » Lib » lib stdwin » wdb.py
# wdb.py -- a window-based Python debugger

# XXX To do:
# - don't fall out of bottom frame


import stdwin
from stdwinevents import *
import sys
import basewin
import bdb
import repr

WIDTH = 40
HEIGHT = 8

WdbDone = 'wdb.WdbDone' # Exception to continue execution


class Wdb(bdb.Bdb, basewin.BaseWindow): # Window debugger
  
  def __init__(self):
    self.sourcewindows = {}
    self.framewindows = {}
    bdb.Bdb.__init__(self)
    width = WIDTH*stdwin.textwidth('0')
    height = HEIGHT*stdwin.lineheight()
    stdwin.setdefwinsize(width, height)
    basewin.BaseWindow.__init__(self, '--Stack--')
    self.closed = 0
  
  def reset(self):
    if self.closed: raise RuntimeError, 'already closed'
    bdb.Bdb.reset(self)
    self.forget()
  
  def forget(self):
    self.lineno = None
    self.stack = []
    self.curindex = 0
    self.curframe = None
    for fn in self.sourcewindows.keys():
      self.sourcewindows[fn].resetlineno()
  
  def setup(self, f, t):
    self.forget()
    self.stack, self.curindex = self.get_stack(f, t)
    self.curframe = self.stack[self.curindex][0]
    # Build a list of current frames
    cfl = []
    for f, i in self.stack: cfl.append(f)
    # Remove deactivated frame windows
    for name in self.framewindows.keys():
      fw = self.framewindows[name]
      if fw.frame not in cfl: fw.close()
      else: fw.refreshframe()
    # Refresh the stack window
    self.refreshstack()
  
  # Override Bdb methods (except user_call, for now)
  
  def user_line(self, frame):
    # This function is called when we stop or break at this line
    self.interaction(frame, None)
  
  def user_return(self, frame, return_value):
    # This function is called when a return trap is set here
    frame.f_locals['__return__'] = return_value
    self.settitle('--Return--')
    self.interaction(frame, None)
    if not self.closed:
      self.settitle('--Stack--')
  
  def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
    # This function is called if an exception occurs,
    # but only if we are to stop at or just below this level
    frame.f_locals['__exception__'] = exc_type, exc_value
    if type(exc_type) == type(''):
      exc_type_name = exc_type
    else: exc_type_name = exc_type.__name__
    self.settitle(exc_type_name + ': ' + repr.repr(exc_value))
    stdwin.fleep()
    self.interaction(frame, exc_traceback)
    if not self.closed:
      self.settitle('--Stack--')
  
  # Change the title
  
  def settitle(self, title):
    self.savetitle = self.win.gettitle()
    self.win.settitle(title)
  
  # General interaction function
  
  def interaction(self, frame, traceback):
    import mainloop
    self.popup()
    self.setup(frame, traceback)
    try:
      mainloop.mainloop()
    except WdbDone:
      pass
    self.forget()
  
  # Functions whose name is do_X for some character X
  # are callable directly from the keyboard.
  
  def do_up(self):
    if self.curindex == 0:
      stdwin.fleep()
    else:
      self.curindex = self.curindex - 1
      self.curframe = self.stack[self.curindex][0]
      self.refreshstack()
  do_u = do_up
  
  def do_down(self):
    if self.curindex + 1 == len(self.stack):
      stdwin.fleep()
    else:
      self.curindex = self.curindex + 1
      self.curframe = self.stack[self.curindex][0]
      self.refreshstack()
  do_d = do_down
  
  def do_step(self):
    self.set_step()
    raise WdbDone
  do_s = do_step
  
  def do_next(self):
    self.set_next(self.curframe)
    raise WdbDone
  do_n = do_next
  
  def do_return(self):
    self.set_return(self.curframe)
    raise WdbDone
  do_r = do_return
  
  def do_continue(self):
    self.set_continue()
    raise WdbDone
  do_c = do_cont = do_continue
  
  def do_quit(self):
    self.close()
    raise WdbDone
  do_q = do_quit
  
  def do_list(self):
    fn = self.curframe.f_code.co_filename
    if not self.sourcewindows.has_key(fn):
      import wdbsrcwin
      try:
        self.sourcewindows[fn] = wdbsrcwin. \
            DebuggerSourceWindow(self, fn)
      except IOError:
        stdwin.fleep()
        return
    w = self.sourcewindows[fn]
    lineno = self.stack[self.curindex][1]
    w.setlineno(lineno)
    w.popup()
  do_l = do_list
  
  def do_frame(self):
    name = 'locals' + `self.curframe`[16:-1]
    if self.framewindows.has_key(name):
      self.framewindows[name].popup()
    else:
      import wdbframewin
      self.framewindows[name] = \
        wdbframewin.FrameWindow(self, \
          self.curframe, \
          self.curframe.f_locals, name)
  do_f = do_frame
  
  def do_globalframe(self):
    name = 'globals' + `self.curframe`[16:-1]
    if self.framewindows.has_key(name):
      self.framewindows[name].popup()
    else:
      import wdbframewin
      self.framewindows[name] = \
        wdbframewin.FrameWindow(self, \
          self.curframe, \
          self.curframe.f_globals, name)
  do_g = do_globalframe
  
  # Link between the debugger and the window
  
  def refreshstack(self):
    height = stdwin.lineheight() * (1 + len(self.stack))
    self.win.setdocsize((0, height))
    self.refreshall() # XXX be more subtle later
    # Also pass the information on to the source windows
    filename = self.curframe.f_code.co_filename
    lineno = self.curframe.f_lineno
    for fn in self.sourcewindows.keys():
      w = self.sourcewindows[fn]
      if fn == filename:
        w.setlineno(lineno)
      else:
        w.resetlineno()
  
  # The remaining methods override BaseWindow methods
  
  def close(self):
    if not self.closed:
      basewin.BaseWindow.close(self)
    self.closed = 1
    for key in self.sourcewindows.keys():
      self.sourcewindows[key].close()
    for key in self.framewindows.keys():
      self.framewindows[key].close()
    self.set_quit()
  
  def char(self, detail):
    try:
      func = eval('self.do_' + detail)
    except (AttributeError, SyntaxError):
      stdwin.fleep()
      return
    func()
  
  def command(self, detail):
    if detail == WC_UP:
      self.do_up()
    elif detail == WC_DOWN:
      self.do_down()
  
  def mouse_down(self, detail):
    (h, v), clicks, button, mask = detail
    i = v / stdwin.lineheight()
    if 0 <= i < len(self.stack):
      if i != self.curindex:
        self.curindex = i
        self.curframe = self.stack[self.curindex][0]
        self.refreshstack()
      elif clicks == 2:
        self.do_frame()
    else:
      stdwin.fleep()
  
  def draw(self, detail):
    import linecache, string
    d = self.win.begindrawing()
    try:
      h, v = 0, 0
      for f, lineno in self.stack:
        fn = f.f_code.co_filename
        if f is self.curframe:
          s = '> '
        else:
          s = '  '
        s = s + fn + '(' + `lineno` + ')'
        s = s + f.f_code.co_name
        if f.f_locals.has_key('__args__'):
          args = f.f_locals['__args__']
          if args is not None:
            s = s + repr.repr(args)
        if f.f_locals.has_key('__return__'):
          rv = f.f_locals['__return__']
          s = s + '->'
          s = s + repr.repr(rv)
        line = linecache.getline(fn, lineno)
        if line: s = s + ': ' + string.strip(line)
        d.text((h, v), s)
        v = v + d.lineheight()
    finally:
      d.close()


# Simplified interface

def run(statement, globals=None, locals=None):
  x = Wdb()
  try: x.run(statement, globals, locals)
  finally: x.close()

def runeval(expression, globals=None, locals=None):
  x = Wdb()
  try: return x.runeval(expression, globals, locals)
  finally: x.close()

def runctx(statement, globals, locals):
  # B/W compatibility
  run(statement, globals, locals)

def runcall(*args):
  x = Wdb()
  try: return apply(x.runcall, args)
  finally: x.close()

def set_trace():
  Wdb().set_trace()

# Post-Mortem interface

def post_mortem(traceback):
  x = Wdb()
  x.reset()
  x.interaction(None, traceback)

def pm():
  import sys
  post_mortem(sys.last_traceback)


# Main program for testing

TESTCMD = 'import x; x.main()'

def test():
  run(TESTCMD)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.