import sys
from Tasks import ThreadedTaskHandler
import wx
'''wxPython debugging client code. This runs in the IDE.
A debug client connects to a debug server, generally in a different
process. The debug server does the dirty work of stepping and
stopping at breakpoints.
'''
wxEVT_DEBUGGER_OK = wx.NewId()
wxEVT_DEBUGGER_EXC = wx.NewId()
wxEVT_DEBUGGER_START = wx.NewId()
wxEVT_DEBUGGER_STOPPED = wx.NewId()
EVT_DEBUGGER_OK = wx.PyEventBinder(wxEVT_DEBUGGER_OK)
EVT_DEBUGGER_EXC = wx.PyEventBinder(wxEVT_DEBUGGER_EXC)
EVT_DEBUGGER_START = wx.PyEventBinder(wxEVT_DEBUGGER_START)
EVT_DEBUGGER_STOPPED = wx.PyEventBinder(wxEVT_DEBUGGER_STOPPED)
class EmptyResponseError (Exception):
"""Empty debugger response"""
class DebuggerCommEvent(wx.PyCommandEvent):
receiver_name = None
receiver_args = ()
result = None
task = None
t = None
v = None
tb = ('', 0)
def __init__(self, evtType, id):
wx.PyCommandEvent.__init__(self, evtType, id)
def SetResult(self, result):
self.result = result
def GetResult(self):
return self.result
def SetTask(self, task):
self.task = task
def GetTask(self):
return self.task
def SetReceiverName(self, name):
self.receiver_name = name
def GetReceiverName(self):
return self.receiver_name
def SetReceiverArgs(self, args):
self.receiver_args = args
def GetReceiverArgs(self):
return self.receiver_args
def SetExc(self, t, v):
self.t, self.v = t, v
def GetExc(self):
return self.t, self.v
class DebugClient:
"""The base class expected to be used by all DebugClients.
"""
def __init__(self, win):
self.win_id = win.GetId()
self.event_handler = win.GetEventHandler()
def invokeOnServer(self, m_name, m_args=(), r_name=None, r_args=()):
"""Invokes an event on the debug server."""
raise NotImplementedError
def kill(self):
"""Terminates the debugger."""
raise NotImplementedError
def getProcessId(self):
"""Returns the process ID if this client is connected to another
process."""
return 0
def createEvent(self, typ):
"""Creates an event."""
return DebuggerCommEvent(typ, self.win_id)
def postEvent(self, evt):
"""Adds an event to the event queue."""
if self.event_handler:
self.event_handler.AddPendingEvent(evt)
def pollStreams(self):
"""Returns the data sent to stdout and stderr."""
return ('', '')
class DebuggerTask:
"""Calls invoke() on a debug client then posts an event on return.
"""
def __init__(self, client, m_name, m_args=(), r_name='', r_args=()):
self.client = client
self.m_name = m_name
self.m_args = m_args
self.r_name = r_name
self.r_args = r_args
def __repr__(self):
return '<DebuggerTask: %s:%s:%s:%s>'%(self.m_name, self.m_args,
self.r_name, self.r_args)
def __call__(self):
evt = None
try:
result = self.client.invoke(self.m_name, self.m_args)
except:
t, v = sys.exc_info()[:2]
evt = self.client.createEvent(wxEVT_DEBUGGER_EXC)
evt.SetExc(t, v)
else:
if self.r_name:
evt = self.client.createEvent(wxEVT_DEBUGGER_OK)
evt.SetReceiverName(self.r_name)
evt.SetReceiverArgs(self.r_args)
evt.SetResult(result)
if evt:
self.client.postEvent(evt)
class MultiThreadedDebugClient (DebugClient):
taskHandler = ThreadedTaskHandler()
def invoke(self, m_name, m_args):
raise NotImplementedError
def invokeOnServer(self, m_name, m_args=(), r_name=None, r_args=()):
task = DebuggerTask(self, m_name, m_args, r_name, r_args)
self.taskHandler.addTask(task)
|