[Idle-dev] CVS: idle PyShell.py,1.18,1.19 RemoteDebugger.py,1.4,1.5 rpc.py,1.2,1.3 run.py,1.2,1.3

Kurt B. Kaiser kbk@users.sourceforge.net
Tue, 25 Jun 2002 19:32:11 -0700


Update of /cvsroot/idlefork/idle
In directory usw-pr-cvs1:/tmp/cvs-serv27871

Modified Files:
	PyShell.py RemoteDebugger.py rpc.py run.py 
Log Message:
Shutdown subprocess debugger and associated Proxies/Adapters when closing
the Idle debugger.

M PyShell.py       : Call RemoteDebugger.close_remote_debugger()
M RemoteDebugger.py: Add close_remote_debugger(); further polish code used
                     to start the debugger sections.
M rpc.py           : Add comments on Idlefork methods register(), unregister()
                     comment out unused methods
M run.py           : Add stop_the_debugger(); polish code


Index: PyShell.py
===================================================================
RCS file: /cvsroot/idlefork/idle/PyShell.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -r1.18 -r1.19
*** PyShell.py	24 Jun 2002 17:03:37 -0000	1.18
--- PyShell.py	26 Jun 2002 02:32:08 -0000	1.19
***************
*** 26,29 ****
--- 26,30 ----
  
  import rpc
+ import RemoteDebugger
  
  # XX hardwire this for now, remove later  KBK 09Jun02
***************
*** 90,95 ****
  
  class PyShellEditorWindow(EditorWindow):
! 
!     # Regular text edit window when a shell is present
      # XXX ought to merge with regular editor window
  
--- 91,95 ----
  
  class PyShellEditorWindow(EditorWindow):
!     "Regular text edit window when a shell is present"
      # XXX ought to merge with regular editor window
  
***************
*** 533,536 ****
--- 533,538 ----
              self.interp.setdebugger(None)
              db.close()
+             if self.interp.rpcclt:
+                 RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
              self.resetoutput()
              self.console.write("[DEBUG OFF]\n")
***************
*** 552,556 ****
  
      def open_remote_debugger(self):
-         import RemoteDebugger
          gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt, self)
          self.interp.setdebugger(gui)
--- 554,557 ----
***************
*** 560,564 ****
  
      def beginexecuting(self):
!         # Helper for ModifiedInterpreter
          self.resetoutput()
          self.executing = 1
--- 561,565 ----
  
      def beginexecuting(self):
!         "Helper for ModifiedInterpreter"
          self.resetoutput()
          self.executing = 1

Index: RemoteDebugger.py
===================================================================
RCS file: /cvsroot/idlefork/idle/RemoteDebugger.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** RemoteDebugger.py	24 Jun 2002 17:03:37 -0000	1.4
--- RemoteDebugger.py	26 Jun 2002 02:32:09 -0000	1.5
***************
*** 53,56 ****
--- 53,57 ----
  
      def interaction(self, message, frame, info=None):
+         # calls rpc.SocketIO.remotecall() via run.MyHandler instance
          self.conn.remotecall(self.oid, "interaction",
                               (message, wrap_frame(frame), wrap_info(info)),
***************
*** 157,174 ****
  
  
! def start_debugger(conn, gui_adap_oid):
      """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, Idb 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)
      idb_adap_oid = "idb_adapter"
!     conn.register(idb_adap_oid, idb_adap)
      return idb_adap_oid
  
--- 158,176 ----
  
  
! def start_debugger(rpchandler, gui_adap_oid):
      """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, Idb debugger, and IdbAdapter
!     objects and linking them together.  Register the IdbAdapter with the
!     RPCServer to handle RPC requests from the split debugger GUI via the
!     IdbProxy.
  
      """
!     gui_proxy = GUIProxy(rpchandler, gui_adap_oid)
      idb = Debugger.Idb(gui_proxy)
      idb_adap = IdbAdapter(idb)
      idb_adap_oid = "idb_adapter"
!     rpchandler.register(idb_adap_oid, idb_adap)
      return idb_adap_oid
  
***************
*** 316,320 ****
          
  
! def start_remote_debugger(conn, pyshell):
      """Start the subprocess debugger, initialize the debugger GUI and RPC link
  
--- 318,322 ----
          
  
! def start_remote_debugger(rpcclt, pyshell):
      """Start the subprocess debugger, initialize the debugger GUI and RPC link
  
***************
*** 323,328 ****
      debugger GUI, and debugger GUIAdapter objects and linking them together.
  
!     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
--- 325,330 ----
      debugger GUI, and debugger GUIAdapter objects and linking them together.
  
!     Register the GUIAdapter with the RPCClient 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
***************
*** 331,339 ****
      """
      gui_adap_oid = "gui_adapter"
!     idb_adap_oid = conn.remotecall("exec", "start_the_debugger",\
                                     (gui_adap_oid,), {})
!     idb_proxy = IdbProxy(conn, idb_adap_oid)
      gui = Debugger.Debugger(pyshell, idb_proxy)
!     gui_adap = GUIAdapter(conn, gui)
!     conn.register(gui_adap_oid, gui_adap)
      return gui
--- 333,355 ----
      """
      gui_adap_oid = "gui_adapter"
!     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)
!     rpcclt.register(gui_adap_oid, gui_adap)
      return gui
+ 
+ def close_remote_debugger(rpcclt):
+     """Shut down subprocess debugger and Idle side of debugger RPC link
+ 
+     Request that the RPCServer shut down the subprocess debugger and link.
+     Unregister the GUIAdapter, which will cause a GC on the Idle process
+     debugger and RPC link objects.  (The second reference to the debugger GUI
+     is deleted in PyShell.close_remote_debugger().)
+ 
+     """    
+     idb_adap_oid = "idb_adapter"
+     rpcclt.remotecall("exec", "stop_the_debugger", (idb_adap_oid,), {})
+     gui_adap_oid = "gui_adapter"
+     rpcclt.unregister(gui_adap_oid)

Index: rpc.py
===================================================================
RCS file: /cvsroot/idlefork/idle/rpc.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** rpc.py	16 Jun 2002 03:32:24 -0000	1.2
--- rpc.py	26 Jun 2002 02:32:09 -0000	1.3
***************
*** 56,78 ****
          if handlerclass is None:
              handlerclass = RPCHandler
!         self.objtable = objecttable 
          SocketServer.TCPServer.__init__(self, addr, handlerclass)
  
!     def verify_request(self, request, client_address):
!         host, port = client_address
!         if host != "127.0.0.1":
!             print "Disallowed host:", host
!             return 0
!         else:
!             return 1
! 
!     def register(self, oid, object):
!         self.objtable[oid] = object
! 
!     def unregister(self, oid):
!         try:
!             del self.objtable[oid]
!         except KeyError:
!             pass
  
  
--- 56,101 ----
          if handlerclass is None:
              handlerclass = RPCHandler
! # XXX KBK 25Jun02 Not used in Idlefork, see register/unregister note below.
! #        self.objtable = objecttable 
          SocketServer.TCPServer.__init__(self, addr, handlerclass)
  
!     # XXX KBK 25Jun02 Following method is not used (yet)
! #      def verify_request(self, request, client_address):
! #          host, port = client_address
! #          if host != "127.0.0.1":
! #              print "Disallowed host:", host
! #              return 0
! #          else:
! #              return 1
! 
! # XXX KBK 25Jun02 The handlerclass is expected to provide register/unregister
! #                 methods.  In Idle, RPCServer is instantiated with
! #                 handlerclass MyHandler, which in turn inherits the
! #                 register/unregister methods from the mix-in class SocketIO.
! #                 It is true that this is asymmetric with the RPCClient's use
! #                 of register/unregister, but I guess that's how a SocketServer
! #                 is supposed to work.
! 
! #                 Exactly how this gets set up is convoluted.  When the
! #                 TCPServer is instantiated, it creates an instance of
! #                 run.MyHandler and calls its handle() method.  handle()
! #                 instantiates a run.Executive, passing it a reference to the
! #                 MyHandler object.  That reference is saved as an attribute of
! #                 the Executive instance.  The Executive methods have access to
! #                 the reference and can pass it on to entities that they
! #                 command (e.g. RemoteDebugger.Debugger.start_debugger()).  The
! #                 latter, in turn, can call MyHandler(SocketIO)
! #                 register/unregister methods via the reference to register and
! #                 unregister themselves.  Whew.
! 
!     # The following two methods are not currently used in Idlefork.
! #      def register(self, oid, object):
! #          self.objtable[oid] = object
! 
! #      def unregister(self, oid):
! #          try:
! #              del self.objtable[oid]
! #          except KeyError:
! #              pass
  
  
***************
*** 199,207 ****
                      else:
                          raise getattr(__import__(mod), name)(*args)
- # XXX KBK 15Jun02  mod is False here, also want to raise remaining exceptions
- #           else:
- #               if mod:
- #                   name = mod + "." + name
- #               raise name, args
              raise name, args
          if how == "ERROR":
--- 222,225 ----

Index: run.py
===================================================================
RCS file: /cvsroot/idlefork/idle/run.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** run.py	16 Jun 2002 03:32:24 -0000	1.2
--- run.py	26 Jun 2002 02:32:09 -0000	1.3
***************
*** 24,28 ****
  
      def __init__(self, rpchandler):
!         self.conn = rpchandler
          import __main__
          self.locals = __main__.__dict__
--- 24,28 ----
  
      def __init__(self, rpchandler):
!         self.rpchandler = rpchandler
          import __main__
          self.locals = __main__.__dict__
***************
*** 33,37 ****
      def start_the_debugger(self, gui_adap_oid):
          import RemoteDebugger
!         return RemoteDebugger.start_debugger(self.conn, gui_adap_oid)
  
      def stackviewer(self, flist_oid=None):
--- 33,41 ----
      def start_the_debugger(self, gui_adap_oid):
          import RemoteDebugger
!         return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
! 
!     def stop_the_debugger(self, idb_adap_oid):
!         "Unregister the Idb Adapter.  Link objects and Idb then subject to GC"
!         self.rpchandler.unregister(idb_adap_oid)
  
      def stackviewer(self, flist_oid=None):
***************
*** 40,44 ****
          flist = None
          if flist_oid is not None:
!             flist = self.conn.get_remote_proxy(flist_oid)
          import RemoteObjectBrowser
          import StackViewer
--- 44,48 ----
          flist = None
          if flist_oid is not None:
!             flist = self.rpchandler.get_remote_proxy(flist_oid)
          import RemoteObjectBrowser
          import StackViewer