[Idle-dev] CVS: idle NEWS.txt, 1.27, 1.28 PyShell.py, 1.79, 1.80 ScriptBinding.py, 1.25, 1.26 run.py, 1.25, 1.26

Kurt B. Kaiser kbk at users.sourceforge.net
Sun Jan 4 23:58:53 EST 2004


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

Modified Files:
	NEWS.txt PyShell.py ScriptBinding.py run.py 
Log Message:
Added a Tk error dialog to run.py inform the user if the subprocess can't
connect to the user GUI process.  Added Tk error dialogs to PyShell.py to
announce a failure to bind the port or connect to the subprocess.  Clean up
error handling during connection initiation phase.  This is an update of
Python Patch 778323, without the listening socket timeout in Python 2.4 IDLE
(since Python 2.2.1 doesn't support that.)

M NEWS.txt
M PyShell.py
M ScriptBinding.py
M run.py


Index: NEWS.txt
===================================================================
RCS file: /cvsroot/idlefork/idle/NEWS.txt,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -r1.27 -r1.28
*** NEWS.txt	2 Jan 2004 02:35:36 -0000	1.27
--- NEWS.txt	5 Jan 2004 04:58:51 -0000	1.28
***************
*** 6,10 ****
  ===================================
  
! *Release date: XX-XXX-2003*
  
  - Print correct exception even if source file changed since shell was 
--- 6,17 ----
  ===================================
  
! *Release date: XX-XXX-2004*
! 
! - Added a Tk error dialog to run.py inform the user if the subprocess can't
!   connect to the user GUI process.  Added Tk error dialogs to PyShell.py to
!   announce a failure to bind the port or connect to the subprocess.  Clean up
!   error handling during connection initiation phase.  This is an update of
!   Python Patch 778323, without the listening socket timeout in Python 2.4 IDLE
!   (since Python 2.2.1 doesn't support that.)
  
  - Print correct exception even if source file changed since shell was 

Index: PyShell.py
===================================================================
RCS file: /cvsroot/idlefork/idle/PyShell.py,v
retrieving revision 1.79
retrieving revision 1.80
diff -C2 -r1.79 -r1.80
*** PyShell.py	25 Nov 2003 03:42:32 -0000	1.79
--- PyShell.py	5 Jan 2004 04:58:51 -0000	1.80
***************
*** 255,259 ****
          else:
              self.pyshell = PyShell(self)
!             self.pyshell.begin()
          return self.pyshell
  
--- 255,261 ----
          else:
              self.pyshell = PyShell(self)
!             if self.pyshell:
!                 if not self.pyshell.begin():
!                     return None
          return self.pyshell
  
***************
*** 348,351 ****
--- 350,356 ----
  
      def start_subprocess(self):
+         # spawning first avoids passing a listening socket to the subprocess
+         self.spawn_subprocess()
+         #time.sleep(20) # test to simulate GUI not accepting connection
          addr = (LOCALHOST, self.port)
          # Idle starts listening for connection on localhost
***************
*** 356,367 ****
                  break
              except socket.error, err:
!                 print>>sys.__stderr__,"IDLE socket error: " + err[1]\
!                                                     + ", retrying..."
          else:
!             display_port_binding_error()
!             sys.exit()
!         self.spawn_subprocess()
          # Accept the connection from the Python execution server
!         self.rpcclt.accept()
          self.rpcclt.register("stdin", self.tkconsole)
          self.rpcclt.register("stdout", self.tkconsole.stdout)
--- 361,375 ----
                  break
              except socket.error, err:
!                 pass
          else:
!             self.display_port_binding_error()
!             return None
          # Accept the connection from the Python execution server
!         #self.rpcclt.listening_sock.settimeout(10)  # no settimeout() in Python 2.2.1
!         try:
!             self.rpcclt.accept()
!         except:  #  socket.timeout, err:            # no settimeout() in Python 2.2.1
!             self.display_no_subprocess_error()
!             return None
          self.rpcclt.register("stdin", self.tkconsole)
          self.rpcclt.register("stdout", self.tkconsole.stdout)
***************
*** 372,379 ****
          self.transfer_path()
          self.poll_subprocess()
  
      def restart_subprocess(self):
          if self.restarting:
!             return
          self.restarting = True
          # close only the subprocess debugger
--- 380,388 ----
          self.transfer_path()
          self.poll_subprocess()
+         return self.rpcclt
  
      def restart_subprocess(self):
          if self.restarting:
!             return self.rpcclt
          self.restarting = True
          # close only the subprocess debugger
***************
*** 392,396 ****
          console.executing = False
          self.spawn_subprocess()
!         self.rpcclt.accept()
          self.transfer_path()
          # annotate restart in shell window and mark it
--- 401,409 ----
          console.executing = False
          self.spawn_subprocess()
!         try:
!             self.rpcclt.accept()
!         except socket.timeout, err:
!             self.display_no_subprocess_error()
!             return None
          self.transfer_path()
          # annotate restart in shell window and mark it
***************
*** 411,414 ****
--- 424,428 ----
              debug.load_breakpoints()
          self.restarting = False
+         return self.rpcclt
  
      def __request_interrupt(self):
***************
*** 419,423 ****
  
      def kill_subprocess(self):
!         self.rpcclt.close()
          self.unix_terminate()
          self.tkconsole.executing = False
--- 433,440 ----
  
      def kill_subprocess(self):
!         try:
!             self.rpcclt.close()
!         except AttributeError:  # no socket
!             pass
          self.unix_terminate()
          self.tkconsole.executing = False
***************
*** 642,652 ****
                  del c[key]
  
-     def display_executing_dialog(self):
-         tkMessageBox.showerror(
-             "Already executing",
-             "The Python Shell window is already executing a command; "
-             "please wait until it is finished.",
-             master=self.tkconsole.text)
- 
      def runcommand(self, code):
          "Run the code without invoking the debugger"
--- 659,662 ----
***************
*** 699,702 ****
--- 709,740 ----
          self.tkconsole.stderr.write(s)
  
+     def display_port_binding_error(self):
+         tkMessageBox.showerror(
+             "Port Binding Error",
+             "IDLE can't bind TCP/IP port 8833, which is necessary to "
+             "communicate with its Python execution server.  Either "
+             "no networking is installed on this computer or another "
+             "process (another IDLE?) is using the port.  Run IDLE with the -n "
+             "command line switch to start without a subprocess and refer to "
+             "Help/IDLE Help 'Running without a subprocess' for further "
+             "details.",
+             master=self.tkconsole.text)
+ 
+     def display_no_subprocess_error(self):
+         tkMessageBox.showerror(
+             "Subprocess Startup Error",
+             "IDLE's subprocess didn't make connection.  Either IDLE can't "
+             "start a subprocess or personal firewall software is blocking "
+             "the connection.",
+             master=self.tkconsole.text)
+ 
+     def display_executing_dialog(self):
+         tkMessageBox.showerror(
+             "Already executing",
+             "The Python Shell window is already executing a command; "
+             "please wait until it is finished.",
+             master=self.tkconsole.text)
+ 
+ 
  class PyShell(OutputWindow):
  
***************
*** 769,774 ****
          #
          self.pollinterval = 50  # millisec
-         if use_subprocess:
-             self.interp.start_subprocess()
  
      reading = False
--- 807,810 ----
***************
*** 882,885 ****
--- 918,925 ----
          if use_subprocess:
              nosub = ''
+             client = self.interp.start_subprocess()
+             if not client:
+                 self.close()
+                 return None
          else:
              nosub = "==== No Subprocess ===="
***************
*** 889,897 ****
          self.showprompt()
          import Tkinter
!         Tkinter._default_root = None
! 
!     def interact(self):
!         self.begin()
!         self.top.mainloop()
  
      def readline(self):
--- 929,934 ----
          self.showprompt()
          import Tkinter
!         Tkinter._default_root = None # 03Jan04 KBK What's this?
!         return client
  
      def readline(self):
***************
*** 1276,1284 ****
              if not args:
                  flist.new()
!         if enable_shell:
!             flist.open_shell()
!     elif enable_shell:
!         flist.pyshell = PyShell(flist)
!         flist.pyshell.begin()
      shell = flist.pyshell
      # handle remaining options:
--- 1313,1319 ----
              if not args:
                  flist.new()
!     if enable_shell:
!         if not flist.open_shell():
!             return # couldn't open shell
      shell = flist.pyshell
      # handle remaining options:
***************
*** 1290,1294 ****
          if filename and os.path.isfile(filename):
              shell.interp.execfile(filename)
!     if cmd or script:
          shell.interp.runcommand("""if 1:
              import sys as _sys
--- 1325,1329 ----
          if filename and os.path.isfile(filename):
              shell.interp.execfile(filename)
!     if shell and cmd or script:
          shell.interp.runcommand("""if 1:
              import sys as _sys
***************
*** 1303,1324 ****
      root.mainloop()
      root.destroy()
- 
- 
- def display_port_binding_error():
-     print """\
- \nIDLE cannot run.
- 
- IDLE needs to use a specific TCP/IP port (8833) in order to communicate with
- its Python execution server.  IDLE is unable to bind to this port, and so
- cannot start. Here are some possible causes of this problem:
- 
-   1. TCP/IP networking is not installed or not working on this computer
-   2. Another program (another IDLE?) is running that uses this port
-   3. Personal firewall software is preventing IDLE from using this port
- 
- Run IDLE with the -n command line switch to start without a subprocess
- and refer to Help/IDLE Help "Running without a subprocess" for further
- details.
- """
  
  if __name__ == "__main__":
--- 1338,1341 ----

Index: ScriptBinding.py
===================================================================
RCS file: /cvsroot/idlefork/idle/ScriptBinding.py,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -r1.25 -r1.26
*** ScriptBinding.py	5 Jun 2003 02:38:32 -0000	1.25
--- ScriptBinding.py	5 Jan 2004 04:58:51 -0000	1.26
***************
*** 138,141 ****
--- 138,143 ----
          flist = self.editwin.flist
          shell = flist.open_shell()
+         if not shell:
+             return  # couldn't open the shell
          interp = shell.interp
          if PyShell.use_subprocess:

Index: run.py
===================================================================
RCS file: /cvsroot/idlefork/idle/run.py,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -r1.25 -r1.26
*** run.py	2 Jan 2004 02:35:36 -0000	1.25
--- run.py	5 Jan 2004 04:58:51 -0000	1.26
***************
*** 50,53 ****
--- 50,54 ----
      no_exitfunc = del_exitfunc
      port = 8833
+     #time.sleep(15) # test subprocess not responding
      if sys.argv[1:]:
          port = int(sys.argv[1])
***************
*** 93,97 ****
  
  def manage_socket(address):
!     for i in range(6):
          time.sleep(i)
          try:
--- 94,98 ----
  
  def manage_socket(address):
!     for i in range(3):
          time.sleep(i)
          try:
***************
*** 99,109 ****
              break
          except socket.error, err:
!             if i < 3:
!                 print>>sys.__stderr__, ".. ",
!             else:
!                 print>>sys.__stderr__,"\nPython subprocess socket error: "\
!                                               + err[1] + ", retrying...."
      else:
!         print>>sys.__stderr__, "\nConnection to Idle failed, exiting."
          global exit_now
          exit_now = True
--- 100,109 ----
              break
          except socket.error, err:
!             print>>sys.__stderr__,"IDLE Subprocess: socket error: "\
!                                         + err[1] + ", retrying...."
      else:
!         print>>sys.__stderr__, "IDLE Subprocess: Connection to "\
!                                "IDLE GUI failed, exiting."
!         show_socket_error(err, address)
          global exit_now
          exit_now = True
***************
*** 111,114 ****
--- 111,129 ----
      server.handle_request() # A single request only
  
+ def show_socket_error(err, address):
+     import Tkinter
+     import tkMessageBox
+     root = Tkinter.Tk()
+     root.withdraw()
+     if err[0] == 61: # connection refused
+         msg = "IDLE's subprocess can't connect to %s:%d.  This may be due "\
+               "to your personal firewall configuration.  It is safe to "\
+               "allow this internal connection because no data is visible on "\
+               "external ports." % address
+         tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
+     else:
+         tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1])
+     root.destroy()
+ 
  def print_exception():
      import linecache
***************
*** 119,123 ****
      sys.last_type, sys.last_value, sys.last_traceback = excinfo
      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")
--- 134,138 ----
      sys.last_type, sys.last_value, sys.last_traceback = excinfo
      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")




More information about the IDLE-dev mailing list