]> granicus.if.org Git - python/commitdiff
M PyShell.py
authorKurt B. Kaiser <kbk@shore.net>
Sat, 25 Jan 2003 21:33:40 +0000 (21:33 +0000)
committerKurt B. Kaiser <kbk@shore.net>
Sat, 25 Jan 2003 21:33:40 +0000 (21:33 +0000)
M RemoteDebugger.py
M rpc.py

Fix the incorrect shell exception tracebacks generated when running
under debugger control:

1. Use rpc.SocketIO.asynccall() instead of remotecall() to handle the
   IdbProxy.run() command.
2. Add a 'shell' attribute to RemoteDebugger.IdbProxy to allow setting
   of ModifiedInterpreter's active_seq attribute from RemoteDebugger code.
3. Cleanup PyShell.ModifiedInterpreter.runcode() and remove ambiguity
   regarding use of begin/endexecuting().
4. In runcode() and cleanup_traceback() use 'console' instead of 'file' to
   denote the entity to which the exception traceback is printed.
5. Enhance cleanup_traceback() so if the traceback is pruned entirely away
   (the error is in IDLE internals) it will be displayed in its entirety
   instead.
6. ModifiedInterpreter.runcode() now prints ERROR RPC returns to both
   console and __stderr__.
7. Make a small tweak to the rpc.py debug messages.

Lib/idlelib/PyShell.py
Lib/idlelib/RemoteDebugger.py
Lib/idlelib/rpc.py

index 9c5152679b690bb1f2c293dfd6b8c843dc885d34..cbfd2036db8db8ee47f667f924772672ba1eed85 100644 (file)
@@ -399,16 +399,16 @@ class ModifiedInterpreter(InteractiveInterpreter):
             self.tkconsole.resetoutput()
             self.active_seq = None
             how, what = response
-            file = self.tkconsole.console
+            console = self.tkconsole.console
             if how == "OK":
                 if what is not None:
-                    print >>file, `what`
+                    print >>console, `what`
             elif how == "EXCEPTION":
                 mod, name, args, tb = what
-                print >>file, 'Traceback (most recent call last):'
-                exclude = ("run.py", "rpc.py")
-                self.cleanup_traceback(tb, exclude)
-                traceback.print_list(tb, file=file)
+                print >>console, 'Traceback (most recent call last):'
+                exclude = ("run.py", "rpc.py", "RemoteDebugger.py", "bdb.py")
+                self.cleanup_traceback(tb, exclude, console)
+                traceback.print_list(tb, file=console)
                 # try to reinstantiate the exception, stuff in the args:
                 try:
                     etype = eval(mod + '.' + name)
@@ -419,18 +419,20 @@ class ModifiedInterpreter(InteractiveInterpreter):
                     val = args
                 lines = traceback.format_exception_only(etype, val)
                 for line in lines[:-1]:
-                    traceback._print(file, line, '')
-                traceback._print(file, lines[-1], '')
+                    traceback._print(console, line, '')
+                traceback._print(console, lines[-1], '')
                 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
                     self.remote_stack_viewer()
             elif how == "ERROR":
                 errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
                 print >>sys.__stderr__, errmsg, what
-                print >>file, errmsg, what
+                print >>console, errmsg, what
+            # we received a response to the currently active seq number:
             self.tkconsole.endexecuting()
 
-    def cleanup_traceback(self, tb, exclude):
+    def cleanup_traceback(self, tb, exclude, console):
         "Remove excluded traces from beginning/end of tb; get cached lines"
+        orig_tb = tb[:]
         while tb:
             for rpcfile in exclude:
                 if tb[0][0].count(rpcfile):
@@ -445,6 +447,11 @@ class ModifiedInterpreter(InteractiveInterpreter):
             else:
                 break
             del tb[-1]
+        if len(tb) == 0:
+            # error was in IDLE internals, don't prune!
+            tb[:] = orig_tb[:]
+            print>>sys.__stderr__, "** IDLE Internal Error: ", tb
+            print>>console, "** IDLE Internal Error **"
         for i in range(len(tb)):
             fn, ln, nm, line = tb[i]
             if nm == '?':
@@ -617,31 +624,26 @@ class ModifiedInterpreter(InteractiveInterpreter):
             warnings.filters[:] = self.save_warnings_filters
             self.save_warnings_filters = None
         debugger = self.debugger
-        if not debugger and self.rpcclt is not None:
-            self.tkconsole.beginexecuting()
-            self.active_seq = self.rpcclt.asynccall("exec", "runcode",
-                                                    (code,), {})
-            return
+        self.tkconsole.beginexecuting()
         try:
-            self.tkconsole.beginexecuting()
-            try:
-                if debugger:
-                    debugger.run(code, self.locals)
-                else:
-                    exec code in self.locals
-            except SystemExit:
-                if tkMessageBox.askyesno(
-                    "Exit?",
-                    "Do you want to exit altogether?",
-                    default="yes",
-                    master=self.tkconsole.text):
-                    raise
-                else:
-                    self.showtraceback()
-            except:
+            if not debugger and self.rpcclt is not None:
+                self.active_seq = self.rpcclt.asynccall("exec", "runcode",
+                                                        (code,), {})
+            elif debugger:
+                debugger.run(code, self.locals)
+            else:
+                exec code in self.locals
+        except SystemExit:
+            if tkMessageBox.askyesno(
+                "Exit?",
+                "Do you want to exit altogether?",
+                default="yes",
+                master=self.tkconsole.text):
+                raise
+            else:
                 self.showtraceback()
-        finally:
-            self.tkconsole.endexecuting()
+        except:
+            self.showtraceback()
 
     def write(self, s):
         "Override base class method"
index 054b975485c3d560d90a3d623d36dd59d6d7277a..41f910f45b7134c235de0bfc6051a801b2ad8329 100644 (file)
@@ -287,19 +287,21 @@ class GUIAdapter:
 
 class IdbProxy:
 
-    def __init__(self, conn, oid):
+    def __init__(self, conn, shell, oid):
         self.oid = oid
         self.conn = conn
+        self.shell = shell
 
     def call(self, methodname, *args, **kwargs):
-        ##print "call %s %s %s" % (methodname, args, kwargs)
+        ##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs)
         value = self.conn.remotecall(self.oid, methodname, args, kwargs)
-        ##print "return %s" % `value`
+        ##print "**IdbProxy.call %s returns %s" % (methodname, `value`)
         return value
 
     def run(self, cmd, locals):
         # Ignores locals on purpose!
-        self.call("run", cmd)
+        seq = self.conn.asynccall(self.oid, "run", (cmd,), {})
+        self.shell.interp.active_seq = seq
 
     def get_stack(self, frame, tbid):
         # passing frame and traceback IDs, not the objects themselves
@@ -352,7 +354,7 @@ def start_remote_debugger(rpcclt, pyshell):
 
     idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
                                    (gui_adap_oid,), {})
-    idb_proxy = IdbProxy(rpcclt, idb_adap_oid)
+    idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid)
     gui = Debugger.Debugger(pyshell, idb_proxy)
     gui_adap = GUIAdapter(rpcclt, gui)
     rpcclt.register(gui_adap_oid, gui_adap)
index 40b16971e0c30442cd1ffd21b232518d3436dc4c..c7644e16818da3e53011ac9ba15bd4a56bfd06e9 100644 (file)
@@ -361,9 +361,10 @@ class SocketIO:
             seq, resq = message
             self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
             if resq[0] == "call":
-                self.debug("pollresponse:%d:call_localcall" % seq)
+                self.debug("pollresponse:%d:localcall:call:" % seq)
                 response = self.localcall(resq)
-                self.debug("pollresponse:%d:response:%s" % (seq, response))
+                self.debug("pollresponse:%d:localcall:response:%s"
+                           % (seq, response))
                 self.putmessage((seq, response))
                 continue
             elif seq == myseq: