From 669f4c3850eaaf4e00a79032ef960a79e6ca6ad7 Mon Sep 17 00:00:00 2001 From: "Kurt B. Kaiser" Date: Thu, 20 Jun 2002 04:01:47 +0000 Subject: [PATCH] 1. Debugger Breakpoints, finish implementation 2. Debugger Clear Breakpoints, implement 3. Nice yellow breakpoints for Chui :) --- Lib/idlelib/Debugger.py | 30 ++++++++--------- Lib/idlelib/PyShell.py | 11 +++++- Lib/idlelib/RemoteDebugger.py | 57 ++++++++++++++++++++++++++++---- Lib/idlelib/config-highlight.def | 8 ++--- 4 files changed, 79 insertions(+), 27 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py index f5646e04904..46531469e87 100644 --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -52,7 +52,6 @@ class Idb(bdb.Bdb): class Debugger: - # interacting = 0 # XXX KBK 14Jun02 move to __init__ vstack = vsource = vlocals = vglobals = None def __init__(self, pyshell, idb=None): @@ -157,7 +156,6 @@ class Debugger: if self.vglobals.get(): self.show_globals() - # frame = None # XXX KBK 14Jun02 Move to __init__ def interaction(self, message, frame, info=None): self.frame = frame @@ -321,16 +319,18 @@ class Debugger: return text.tag_add("BREAK", "insert linestart", "insert lineend +1char") - # A literal copy of Bdb.set_break() without the print statement at the end - #def set_break(self, filename, lineno, temporary=0, cond = None): - # import linecache # Import as late as possible - # filename = self.canonic(filename) - # line = linecache.getline(filename, lineno) - # if not line: - # return 'That line does not exist!' - # if not self.breaks.has_key(filename): - # self.breaks[filename] = [] - # list = self.breaks[filename] - # if not lineno in list: - # list.append(lineno) - # bp = bdb.Breakpoint(filename, lineno, temporary, cond) + def clear_breakpoint_here(self, edit): + text = edit.text + filename = edit.io.filename + if not filename: + text.bell() + return + lineno = int(float(text.index("insert"))) + msg = self.idb.clear_break(filename, lineno) + if msg: + text.bell() + return + text.tag_remove("BREAK", "insert linestart",\ + "insert lineend +1char") + + diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index d84e2e1bd65..f418a5757e3 100644 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -96,10 +96,13 @@ class PyShellEditorWindow(EditorWindow): def __init__(self, *args): apply(EditorWindow.__init__, (self,) + args) self.text.bind("<>", self.set_breakpoint_here) + self.text.bind("<>", + self.clear_breakpoint_here) self.text.bind("<>", self.flist.open_shell) rmenu_specs = [ - ("Set breakpoint here", "<>"), + ("Set Breakpoint", "<>"), + ("Clear Breakpoint", "<>") ] def set_breakpoint_here(self, event=None): @@ -108,6 +111,12 @@ class PyShellEditorWindow(EditorWindow): return self.flist.pyshell.interp.debugger.set_breakpoint_here(self) + def clear_breakpoint_here(self, event=None): + if not self.flist.pyshell or not self.flist.pyshell.interp.debugger: + self.text.bell() + return + self.flist.pyshell.interp.debugger.clear_breakpoint_here(self) + class PyShellFileList(FileList): diff --git a/Lib/idlelib/RemoteDebugger.py b/Lib/idlelib/RemoteDebugger.py index 5131065151a..a5b4e7e363d 100644 --- a/Lib/idlelib/RemoteDebugger.py +++ b/Lib/idlelib/RemoteDebugger.py @@ -26,7 +26,9 @@ import Debugger debugging = 0 -# In the PYTHON subprocess +#======================================= +# +# In the PYTHON subprocess: frametable = {} dicttable = {} @@ -59,6 +61,8 @@ class IdbAdapter: def __init__(self, idb): self.idb = idb + #----------called by an IdbProxy---------- + def set_step(self): self.idb.set_step() @@ -90,6 +94,15 @@ class IdbAdapter: import __main__ self.idb.run(cmd, __main__.__dict__) + def set_break(self, filename, lineno): + msg = self.idb.set_break(filename, lineno) + return msg + + def clear_break(self, filename, lineno): + msg = self.idb.clear_break(filename, lineno) + + #----------called by a FrameProxy---------- + def frame_attr(self, fid, name): frame = frametable[fid] return getattr(frame, name) @@ -115,6 +128,8 @@ class IdbAdapter: codetable[cid] = code return cid + #----------called by a CodeProxy---------- + def code_name(self, cid): code = codetable[cid] return code.co_name @@ -123,6 +138,8 @@ class IdbAdapter: code = codetable[cid] return code.co_filename + #----------called by a DictProxy---------- + def dict_keys(self, did): dict = dicttable[did] return dict.keys() @@ -141,8 +158,18 @@ class IdbAdapter: # #value = None return value +#----------end class IdbAdapter---------- + + def start_debugger(conn, gui_adap_oid): - "Launch debugger in the remote python subprocess" + """Start the debugger and its RPC link in the Python subprocess + + Start the subprocess side of the split debugger and set up that side of the + RPC link by instantiating the GUIProxy, Idle debugger, and IdbAdapter + objects and linking them together. Register the IdbAdapter to handle RPC + requests from the split Debugger GUI via the IdbProxy. + + """ gui_proxy = GUIProxy(conn, gui_adap_oid) idb = Debugger.Idb(gui_proxy) idb_adap = IdbAdapter(idb) @@ -150,7 +177,11 @@ def start_debugger(conn, gui_adap_oid): conn.register(idb_adap_oid, idb_adap) return idb_adap_oid -# In the IDLE process + +#======================================= +# +# In the IDLE process: + class FrameProxy: @@ -193,6 +224,7 @@ class FrameProxy: self._dictcache[did] = dp return dp + class CodeProxy: def __init__(self, conn, oid, cid): @@ -208,6 +240,7 @@ class CodeProxy: return self._conn.remotecall(self._oid, "code_filename", (self._cid,), {}) + class DictProxy: def __init__(self, conn, oid, did): @@ -226,6 +259,7 @@ class DictProxy: ##print >>sys.__stderr__, "failed DictProxy.__getattr__:", name raise AttributeError, name + class GUIAdapter: def __init__(self, conn, gui): @@ -238,6 +272,7 @@ class GUIAdapter: info = None # XXX for now self.gui.interaction(message, frame, info) + class IdbProxy: def __init__(self, conn, oid): @@ -274,14 +309,22 @@ class IdbProxy: def set_quit(self): self.call("set_quit") + def set_break(self, filename, lineno): + msg = self.call("set_break", filename, lineno) + return msg + + def clear_break(self, filename, lineno): + msg = self.call("clear_break", filename, lineno) + def start_remote_debugger(conn, pyshell): """Start the subprocess debugger, initialize the debugger GUI and RPC link - Start the debugger in the remote Python process. Instantiate IdbProxy, - Debugger GUI, and Debugger GUIAdapter objects, and link them together. + Request the RPCServer start the Python subprocess debugger and link. Set + up the Idle side of the split debugger by instantiating the IdbProxy, + Debugger GUI, and Debugger GUIAdapter objects and linking them together. - The GUIAdapter will handle debugger GUI interaction requests coming from - the subprocess debugger via the GUIProxy. + Register the GUIAdapter to handle debugger GUI interaction requests coming + from the subprocess debugger via the GUIProxy. The IdbAdapter will pass execution and environment requests coming from the Idle debugger GUI to the subprocess debugger via the IdbProxy. diff --git a/Lib/idlelib/config-highlight.def b/Lib/idlelib/config-highlight.def index 81c4ba5183e..2b7deab3825 100644 --- a/Lib/idlelib/config-highlight.def +++ b/Lib/idlelib/config-highlight.def @@ -14,8 +14,8 @@ definition-foreground= #0000ff definition-background= #ffffff hilite-foreground= #000000 hilite-background= gray -break-foreground= #ff7777 -break-background= #ffffff +break-foreground= black +break-background= #ffff55 hit-foreground= #ffffff hit-background= #000000 error-foreground= #000000 @@ -43,8 +43,8 @@ definition-foreground= #0000ff definition-background= #ffffff hilite-foreground= #000000 hilite-background= gray -break-foreground= #ff7777 -break-background= #ffffff +break-foreground= black +break-background= #ffff55 hit-foreground= #ffffff hit-background= #000000 error-foreground= #000000