[Idle-dev] CVS: idle PyShell.py,1.68,1.69 ScriptBinding.py,1.20,1.21 rpc.py,1.24,1.25 run.py,1.18,1.19

Kurt B. Kaiser kbk@users.sourceforge.net
Sat, 24 May 2003 13:59:17 -0700


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

Modified Files:
	PyShell.py ScriptBinding.py rpc.py run.py 
Log Message:
1. Stake Freddy.
   e.g. further improve subprocess interrupt, exceptions, and termination.
2. Remove the workarounds in PyShell.py and ScriptBinding.py involving
   interrupting the subprocess prior to killing it, not necessary anymore.
3. Fix a bug introduced at PyShell Rev 1.66: was getting extra shell menu
   every time the shell window was recreated.

M PyShell.py
M ScriptBinding.py
M rpc.py
M run.py


Index: PyShell.py
===================================================================
RCS file: /cvsroot/idlefork/idle/PyShell.py,v
retrieving revision 1.68
retrieving revision 1.69
diff -C2 -r1.68 -r1.69
*** PyShell.py	19 May 2003 23:11:51 -0000	1.68
--- PyShell.py	24 May 2003 20:59:12 -0000	1.69
***************
*** 297,300 ****
--- 297,308 ----
          UndoDelegator.delete(self, index1, index2)
  
+ 
+ class MyRPCClient(rpc.RPCClient):
+ 
+     def handle_EOF(self):
+         "Override the base class - just re-raise EOFError"
+         raise EOFError
+ 
+     
  class ModifiedInterpreter(InteractiveInterpreter):
  
***************
*** 330,334 ****
              time.sleep(i)
              try:
!                 self.rpcclt = rpc.RPCClient(addr)
                  break
              except socket.error, err:
--- 338,342 ----
              time.sleep(i)
              try:
!                 self.rpcclt = MyRPCClient(addr)
                  break
              except socket.error, err:
***************
*** 427,433 ****
              # lost connection or subprocess terminated itself, restart
              # [the KBI is from rpc.SocketIO.handle_EOF()]
              response = None
              self.restart_subprocess()
-             self.tkconsole.endexecuting()
          if response:
              self.tkconsole.resetoutput()
--- 435,442 ----
              # lost connection or subprocess terminated itself, restart
              # [the KBI is from rpc.SocketIO.handle_EOF()]
+             if self.tkconsole.closing:
+                 return
              response = None
              self.restart_subprocess()
          if response:
              self.tkconsole.resetoutput()
***************
*** 674,678 ****
      def __init__(self, flist=None):
          if use_subprocess:
!             self.menu_specs.insert(2, ("shell", "_Shell"))
          self.interp = ModifiedInterpreter(self)
          if flist is None:
--- 683,689 ----
      def __init__(self, flist=None):
          if use_subprocess:
!             ms = self.menu_specs
!             if ms[2][0] != "shell":
!                 ms.insert(2, ("shell", "_Shell"))
          self.interp = ModifiedInterpreter(self)
          if flist is None:
***************
*** 794,806 ****
              if response == False:
                  return "cancel"
!             # interrupt the subprocess
!             self.canceled = True
!             if use_subprocess:
!                 self.interp.interrupt_subprocess()
!             return "cancel"
!         else:
!             self.closing = True
!             # Wait for poll_subprocess() rescheduling to stop
!             self.text.after(2 * self.pollinterval, self.close2)
  
      def close2(self):
--- 805,811 ----
              if response == False:
                  return "cancel"
!         self.closing = True
!         # Wait for poll_subprocess() rescheduling to stop
!         self.text.after(2 * self.pollinterval, self.close2)
  
      def close2(self):
***************
*** 886,890 ****
              self.top.quit()
          elif (self.executing and self.interp.rpcclt):
!             self.interp.interrupt_subprocess()
          return "break"
  
--- 891,898 ----
              self.top.quit()
          elif (self.executing and self.interp.rpcclt):
!             if self.interp.getdebugger():
!                 self.interp.restart_subprocess()
!             else:
!                 self.interp.interrupt_subprocess()
          return "break"
  
***************
*** 1022,1035 ****
  
      def restart_shell(self, event=None):
!         if self.executing:
!             self.cancel_callback()
!             # Wait for subprocess to interrupt and restart
!             # This can be a long time if shell is scrolling on a slow system
!             # XXX 14 May 03 KBK This delay (and one in ScriptBinding) could be
!             #     shorter if we didn't print the KeyboardInterrupt on
!             #     restarting while user code is running....
!             self.text.after(2000, self.interp.restart_subprocess)
!         else:
!             self.interp.restart_subprocess()
  
      def showprompt(self):
--- 1030,1034 ----
  
      def restart_shell(self, event=None):
!         self.interp.restart_subprocess()
  
      def showprompt(self):

Index: ScriptBinding.py
===================================================================
RCS file: /cvsroot/idlefork/idle/ScriptBinding.py,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -r1.20 -r1.21
*** ScriptBinding.py	15 May 2003 23:23:21 -0000	1.20
--- ScriptBinding.py	24 May 2003 20:59:15 -0000	1.21
***************
*** 126,140 ****
          if PyShell.use_subprocess:
              shell.restart_shell()
-             if shell.executing:
-                 delay = 2700
-             else:
-                 delay = 500
-             # Wait for the interrupt and reset to finish
-             shell.text.after(delay, self.run_module_event2, interp,
-                              filename, code)
-         else:
-             self.run_module_event2(interp, filename, code)
- 
-     def run_module_event2(self, interp, filename, code):
          # XXX Too often this discards arguments the user just set...
          interp.runcommand("""if 1:
--- 126,129 ----

Index: rpc.py
===================================================================
RCS file: /cvsroot/idlefork/idle/rpc.py,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -r1.24 -r1.25
*** rpc.py	10 May 2003 00:09:52 -0000	1.24
--- rpc.py	24 May 2003 20:59:15 -0000	1.25
***************
*** 42,46 ****
  import marshal
  
- import interrupt
  
  def unpickle_code(ms):
--- 42,45 ----
***************
*** 328,337 ****
              try:
                  n = self.sock.send(s)
!             except AttributeError:
                  # socket was closed
                  raise IOError
-             except socket.error:
-                 self.debug("putmessage:socketerror:pid:%s" % os.getpid())
-                 os._exit(0)
              else:
                  s = s[n:]
--- 327,333 ----
              try:
                  n = self.sock.send(s)
!             except (AttributeError, socket.error):
                  # socket was closed
                  raise IOError
              else:
                  s = s[n:]
***************
*** 472,476 ****
              cv.notify()
              cv.release()
-         interrupt.interrupt_main()
          # call our (possibly overridden) exit function
          self.exithook()
--- 468,471 ----

Index: run.py
===================================================================
RCS file: /cvsroot/idlefork/idle/run.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -r1.18 -r1.19
*** run.py	17 May 2003 21:04:10 -0000	1.18
--- run.py	24 May 2003 20:59:15 -0000	1.19
***************
*** 22,26 ****
  # completion and exit flags:
  
! exit_requested = False
  
  def main():
--- 22,27 ----
  # completion and exit flags:
  
! exit_now = False
! quitting = False
  
  def main():
***************
*** 42,45 ****
--- 43,48 ----
  
      """
+     global exit_now
+     global quitting
      port = 8833
      if sys.argv[1:]:
***************
*** 53,58 ****
      while 1:
          try:
!             if exit_requested:
!                 sys.exit(0)
              try:
                  seq, request = rpc.request_queue.get(0)
--- 56,65 ----
      while 1:
          try:
!             if exit_now:
!                 try:
!                     sys.exit(0)
!                 except KeyboardInterrupt:
!                     # exiting but got an extra KBI? Try again!
!                     continue
              try:
                  seq, request = rpc.request_queue.get(0)
***************
*** 64,78 ****
              rpc.response_queue.put((seq, ret))
          except KeyboardInterrupt:
              continue
          except SystemExit:
              raise
          except:
              try:
                  print_exception()
                  rpc.response_queue.put((seq, None))
              except:
!                 traceback.print_exc(file=sys.__stderr__)
!                 sys.exit(1.1)
!             continue
  
  def manage_socket(address):
--- 71,90 ----
              rpc.response_queue.put((seq, ret))
          except KeyboardInterrupt:
+             if quitting:
+                 exit_now = True
              continue
          except SystemExit:
              raise
          except:
+             type, value, tb = sys.exc_info()
              try:
                  print_exception()
                  rpc.response_queue.put((seq, None))
              except:
!                 # Link didn't work, print same exception to __stderr__
!                 traceback.print_exception(type, value, tb, file=sys.__stderr__)
!                 sys.exit(0)
!             else:
!                 continue
  
  def manage_socket(address):
***************
*** 90,95 ****
      else:
          print>>sys.__stderr__, "\nConnection to Idle failed, exiting."
!         global exit_requested
!         exit_requested = True
          return
      server.handle_request() # A single request only
--- 102,107 ----
      else:
          print>>sys.__stderr__, "\nConnection to Idle failed, exiting."
!         global exit_now
!         exit_now = True
          return
      server.handle_request() # A single request only
***************
*** 98,104 ****
      flush_stdout()
      efile = sys.stderr
!     typ, val, tb = info = sys.exc_info()
      tbe = traceback.extract_tb(tb)
!     print >>efile, 'Traceback (most recent call last):'
      exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
                 "RemoteDebugger.py", "bdb.py")
--- 110,116 ----
      flush_stdout()
      efile = sys.stderr
!     typ, val, tb = sys.exc_info()
      tbe = traceback.extract_tb(tb)
!     print >>efile, '\nTraceback (most recent call last):'
      exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
                 "RemoteDebugger.py", "bdb.py")
***************
*** 162,167 ****
              raise
          except EOFError:
!             global exit_requested
!             exit_requested = True
              interrupt.interrupt_main()
          except:
--- 174,179 ----
              raise
          except EOFError:
!             global exit_now
!             exit_now = True
              interrupt.interrupt_main()
          except:
***************
*** 175,179 ****
              print>>erf, '\n*** Unrecoverable, server exiting!'
              print>>erf, '-'*40
!             os._exit(0)
  
  
--- 187,191 ----
              print>>erf, '\n*** Unrecoverable, server exiting!'
              print>>erf, '-'*40
!             sys.exit(0)
  
  
***************
*** 191,203 ****
      def exithook(self):
          "override SocketIO method - wait for MainThread to shut us down"
!         while 1: pass
  
      def EOFhook(self):
          "Override SocketIO method - terminate wait on callback and exit thread"
!         global exit_requested
!         exit_requested = True
  
      def decode_interrupthook(self):
          "interrupt awakened thread"
          interrupt.interrupt_main()
  
--- 203,218 ----
      def exithook(self):
          "override SocketIO method - wait for MainThread to shut us down"
!         time.sleep(10)
  
      def EOFhook(self):
          "Override SocketIO method - terminate wait on callback and exit thread"
!         global quitting
!         quitting = True
!         interrupt.interrupt_main()
  
      def decode_interrupthook(self):
          "interrupt awakened thread"
+         global quitting
+         quitting = True
          interrupt.interrupt_main()
  
***************
*** 214,226 ****
              exec code in self.locals
          except:
!             if exit_requested:
                  sys.exit(0)
!             try:
!                 # even print a user code SystemExit exception, continue
!                 print_exception()
!             except:
!                 # link not working? 
!                 traceback.print_exc(file=sys.__stderr__)
!                 sys.exit(1.2)
          else:
              flush_stdout()
--- 229,236 ----
              exec code in self.locals
          except:
!             if quitting:
                  sys.exit(0)
!             # even print a user code SystemExit exception, continue
!             print_exception()
          else:
              flush_stdout()