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)
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):
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,), {})
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()
self.history = self.History(self.text)
if use_subprocess:
- self.interp.spawn_subprocess()
+ self.interp.start_subprocess()
reading = 0
executing = 0
debugging = 0
+idb_adap_oid = "idb_adapter"
+gui_adap_oid = "gui_adapter"
+
#=======================================
#
# In the PYTHON subprocess:
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)
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
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)
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)
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'
+
- 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:
- Allow specify command line arguments in the dialog box
-- Restart the interpreter when running a script
-
"""
import sys
menudefs = [
('run', [None,
# ('Check module', '<<check-module>>'),
-# ('Import module', '<<import-module>>'),
('Run script', '<<run-script>>'),
]
),
"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:
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