diff options
-rw-r--r-- | Lib/idlelib/PyShell.py | 46 | ||||
-rw-r--r-- | Lib/idlelib/RemoteDebugger.py | 22 | ||||
-rw-r--r-- | Lib/idlelib/ScriptBinding.py | 44 |
3 files changed, 55 insertions, 57 deletions
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index b483ea8..9ef2ff7 100644 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -187,17 +187,19 @@ class ModifiedInterpreter(InteractiveInterpreter): InteractiveInterpreter.__init__(self, locals=locals) self.save_warnings_filters = None + port = 8833 rpcclt = None rpcpid = None def spawn_subprocess(self): - port = 8833 - addr = ("localhost", port) - # Spawn the Python execution "server" w = ['-W' + s for s in sys.warnoptions] args = [sys.executable] + w + ["-c", "__import__('run').main()", - str(port)] + str(self.port)] self.rpcpid = os.spawnv(os.P_NOWAIT, args[0], args) + + def start_subprocess(self): + addr = ("localhost", self.port) + self.spawn_subprocess() # Idle starts listening for connection on localhost for i in range(6): time.sleep(i) @@ -221,6 +223,21 @@ class ModifiedInterpreter(InteractiveInterpreter): self.rpcclt.register("flist", self.tkconsole.flist) self.poll_subprocess() + def restart_subprocess(self): + # close only the subprocess debugger + db = self.getdebugger() + if db: + RemoteDebugger.close_subprocess_debugger(self.rpcclt) + # kill subprocess, spawn a new one, accept connection + self.rpcclt.close() + self.spawn_subprocess() + self.rpcclt.accept() + # restart remote debugger + if db: + gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt) + # reload remote debugger breakpoints + pass # XXX KBK 04Sep02 TBD + active_seq = None def poll_subprocess(self): @@ -383,15 +400,18 @@ class ModifiedInterpreter(InteractiveInterpreter): def getdebugger(self): return self.debugger + 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" # The code better not raise an exception! if self.tkconsole.executing: - tkMessageBox.showerror( - "Already executing", - "The Python Shell window is already executing a command; " - "please wait until it is finished.", - master=self.tkconsole.text) + display_executing_dialog() return 0 if self.rpcclt: self.rpcclt.remotecall("exec", "runcode", (code,), {}) @@ -402,11 +422,7 @@ class ModifiedInterpreter(InteractiveInterpreter): def runcode(self, code): "Override base class method" if self.tkconsole.executing: - tkMessageBox.showerror( - "Already executing", - "The Python Shell window is already executing a command; " - "please wait until it is finished.", - master=self.tkconsole.text) + display_executing_dialog() return # self.checklinecache() @@ -509,7 +525,7 @@ class PyShell(OutputWindow): self.history = self.History(self.text) if use_subprocess: - self.interp.spawn_subprocess() + self.interp.start_subprocess() reading = 0 executing = 0 diff --git a/Lib/idlelib/RemoteDebugger.py b/Lib/idlelib/RemoteDebugger.py index 84e94df..f9430d0 100644 --- a/Lib/idlelib/RemoteDebugger.py +++ b/Lib/idlelib/RemoteDebugger.py @@ -27,6 +27,9 @@ import Debugger debugging = 0 +idb_adap_oid = "idb_adapter" +gui_adap_oid = "gui_adapter" + #======================================= # # In the PYTHON subprocess: @@ -113,6 +116,7 @@ class IdbAdapter: def clear_break(self, filename, lineno): msg = self.idb.clear_break(filename, lineno) + return msg def clear_all_file_breaks(self, filename): msg = self.idb.clear_all_file_breaks(filename) @@ -183,7 +187,6 @@ def start_debugger(rpchandler, gui_adap_oid): 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 @@ -325,6 +328,7 @@ class IdbProxy: def clear_break(self, filename, lineno): msg = self.call("clear_break", filename, lineno) + return msg def clear_all_file_breaks(self, filename): msg = self.call("clear_all_file_breaks", filename) @@ -344,7 +348,8 @@ def start_remote_debugger(rpcclt, pyshell): Idle debugger GUI to the subprocess debugger via the IdbProxy. """ - gui_adap_oid = "gui_adapter" + global idb_adap_oid + idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\ (gui_adap_oid,), {}) idb_proxy = IdbProxy(rpcclt, idb_adap_oid) @@ -362,7 +367,14 @@ def close_remote_debugger(rpcclt): 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" + close_subprocess_debugger(rpcclt) rpcclt.unregister(gui_adap_oid) + +def close_subprocess_debugger(rpcclt): + rpcclt.remotecall("exec", "stop_the_debugger", (idb_adap_oid,), {}) + +def restart_subprocess_debugger(rpcclt): + idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\ + (gui_adap_oid,), {}) + assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid' + diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py index 8ab0cf6..cc26510 100644 --- a/Lib/idlelib/ScriptBinding.py +++ b/Lib/idlelib/ScriptBinding.py @@ -5,13 +5,9 @@ This adds the following commands: - Check module does a full syntax check of the current module. It also runs the tabnanny to catch any inconsistent tabs. -- Import module is equivalent to either import or reload of the -current module. The window must have been saved previously. The -module is added to sys.modules, and is also added to the __main__ -namespace. Output goes to the shell window. - -- Run module does the same but executes the module's -code in the __main__ namespace. +- Run module executes the module's code in the __main__ namespace. The window +must have been saved previously. The module is added to sys.modules, and is +also added to the __main__ namespace. XXX Redesign this interface (yet again) as follows: @@ -19,8 +15,6 @@ XXX Redesign this interface (yet again) as follows: - Allow specify command line arguments in the dialog box -- Restart the interpreter when running a script - """ import sys @@ -47,7 +41,6 @@ class ScriptBinding: menudefs = [ ('run', [None, # ('Check module', '<<check-module>>'), -# ('Import module', '<<import-module>>'), ('Run script', '<<run-script>>'), ] ), @@ -113,33 +106,6 @@ class ScriptBinding: "There's an error in your program:\n" + msg) return 1 - def import_module_event(self, event): - flist = self.editwin.flist - shell = flist.open_shell() - interp = shell.interp - - filename = self.getfilename() - if not filename: - return - - modname, ext = os.path.splitext(os.path.basename(filename)) - - dir = os.path.dirname(filename) - dir = os.path.normpath(os.path.abspath(dir)) - - interp.runcode("""if 1: - import sys as _sys - if %s not in _sys.path: - _sys.path.insert(0, %s) - if _sys.modules.get(%s): - del _sys - import %s - reload(%s) - else: - del _sys - import %s - \n""" % (`dir`, `dir`, `modname`, modname, modname, modname)) - def run_script_event(self, event): filename = self.getfilename() if not filename: @@ -147,6 +113,10 @@ class ScriptBinding: flist = self.editwin.flist shell = flist.open_shell() interp = shell.interp + if interp.tkconsole.executing: + interp.display_executing_dialog() + return + interp.restart_subprocess() # XXX Too often this discards arguments the user just set... interp.runcommand("""if 1: _filename = %s |