[Idle-dev] CVS: idle PyShell.py,1.53,1.54 RemoteDebugger.py,1.8,1.9 rpc.py,1.13,1.14

Kurt B. Kaiser kbk@users.sourceforge.net
Sat, 25 Jan 2003 13:33:43 -0800


Update of /cvsroot/idlefork/idle
In directory sc8-pr-cvs1:/tmp/cvs-serv21799

Modified Files:
	PyShell.py RemoteDebugger.py rpc.py 
Log Message:
M PyShell.py
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.


Index: PyShell.py
===================================================================
RCS file: /cvsroot/idlefork/idle/PyShell.py,v
retrieving revision 1.53
retrieving revision 1.54
diff -C2 -r1.53 -r1.54
*** PyShell.py	22 Jan 2003 00:23:23 -0000	1.53
--- PyShell.py	25 Jan 2003 21:33:40 -0000	1.54
***************
*** 400,413 ****
              self.active_seq = None
              how, what = response
!             file = self.tkconsole.console
              if how == "OK":
                  if what is not None:
!                     print >>file, `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)
                  # try to reinstantiate the exception, stuff in the args:
                  try:
--- 400,413 ----
              self.active_seq = None
              how, what = response
!             console = self.tkconsole.console
              if how == "OK":
                  if what is not None:
!                     print >>console, `what`
              elif how == "EXCEPTION":
                  mod, name, args, tb = what
!                 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:
***************
*** 420,425 ****
                  lines = traceback.format_exception_only(etype, val)
                  for line in lines[:-1]:
!                     traceback._print(file, line, '')
!                 traceback._print(file, lines[-1], '')
                  if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
                      self.remote_stack_viewer()
--- 420,425 ----
                  lines = traceback.format_exception_only(etype, val)
                  for line in lines[:-1]:
!                     traceback._print(console, line, '')
!                 traceback._print(console, lines[-1], '')
                  if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
                      self.remote_stack_viewer()
***************
*** 427,435 ****
                  errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
                  print >>sys.__stderr__, errmsg, what
!                 print >>file, errmsg, what
              self.tkconsole.endexecuting()
  
!     def cleanup_traceback(self, tb, exclude):
          "Remove excluded traces from beginning/end of tb; get cached lines"
          while tb:
              for rpcfile in exclude:
--- 427,437 ----
                  errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
                  print >>sys.__stderr__, 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, console):
          "Remove excluded traces from beginning/end of tb; get cached lines"
+         orig_tb = tb[:]
          while tb:
              for rpcfile in exclude:
***************
*** 446,449 ****
--- 448,456 ----
                  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]
***************
*** 618,646 ****
              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
          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:
                  self.showtraceback()
!         finally:
!             self.tkconsole.endexecuting()
  
      def write(self, s):
--- 625,648 ----
              self.save_warnings_filters = None
          debugger = self.debugger
!         self.tkconsole.beginexecuting()
          try:
!             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()
!         except:
!             self.showtraceback()
  
      def write(self, s):

Index: RemoteDebugger.py
===================================================================
RCS file: /cvsroot/idlefork/idle/RemoteDebugger.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -r1.8 -r1.9
*** RemoteDebugger.py	31 Dec 2002 15:59:14 -0000	1.8
--- RemoteDebugger.py	25 Jan 2003 21:33:40 -0000	1.9
***************
*** 288,304 ****
  class IdbProxy:
  
!     def __init__(self, conn, oid):
          self.oid = oid
          self.conn = conn
  
      def call(self, methodname, *args, **kwargs):
!         ##print "call %s %s %s" % (methodname, args, kwargs)
          value = self.conn.remotecall(self.oid, methodname, args, kwargs)
!         ##print "return %s" % `value`
          return value
  
      def run(self, cmd, locals):
          # Ignores locals on purpose!
!         self.call("run", cmd)
  
      def get_stack(self, frame, tbid):
--- 288,306 ----
  class IdbProxy:
  
!     def __init__(self, conn, shell, oid):
          self.oid = oid
          self.conn = conn
+         self.shell = shell
  
      def call(self, methodname, *args, **kwargs):
!         ##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs)
          value = self.conn.remotecall(self.oid, methodname, args, kwargs)
!         ##print "**IdbProxy.call %s returns %s" % (methodname, `value`)
          return value
  
      def run(self, cmd, locals):
          # Ignores locals on purpose!
!         seq = self.conn.asynccall(self.oid, "run", (cmd,), {})
!         self.shell.interp.active_seq = seq
  
      def get_stack(self, frame, tbid):
***************
*** 353,357 ****
      idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
                                     (gui_adap_oid,), {})
!     idb_proxy = IdbProxy(rpcclt, idb_adap_oid)
      gui = Debugger.Debugger(pyshell, idb_proxy)
      gui_adap = GUIAdapter(rpcclt, gui)
--- 355,359 ----
      idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
                                     (gui_adap_oid,), {})
!     idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid)
      gui = Debugger.Debugger(pyshell, idb_proxy)
      gui_adap = GUIAdapter(rpcclt, gui)

Index: rpc.py
===================================================================
RCS file: /cvsroot/idlefork/idle/rpc.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -r1.13 -r1.14
*** rpc.py	25 Jan 2003 03:26:35 -0000	1.13
--- rpc.py	25 Jan 2003 21:33:40 -0000	1.14
***************
*** 362,368 ****
              self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
              if resq[0] == "call":
!                 self.debug("pollresponse:%d:call_localcall" % seq)
                  response = self.localcall(resq)
!                 self.debug("pollresponse:%d:response:%s" % (seq, response))
                  self.putmessage((seq, response))
                  continue
--- 362,369 ----
              self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
              if resq[0] == "call":
!                 self.debug("pollresponse:%d:localcall:call:" % seq)
                  response = self.localcall(resq)
!                 self.debug("pollresponse:%d:localcall:response:%s"
!                            % (seq, response))
                  self.putmessage((seq, response))
                  continue