diff options
Diffstat (limited to 'Lib/idlelib/ExecBinding.py')
-rw-r--r-- | Lib/idlelib/ExecBinding.py | 193 |
1 files changed, 0 insertions, 193 deletions
diff --git a/Lib/idlelib/ExecBinding.py b/Lib/idlelib/ExecBinding.py deleted file mode 100644 index e148769..0000000 --- a/Lib/idlelib/ExecBinding.py +++ /dev/null @@ -1,193 +0,0 @@ -"""Extension to execute a script in a separate process - -David Scherer <dscherer@cmu.edu> - - The ExecBinding module, a replacement for ScriptBinding, executes - programs in a separate process. Unlike previous versions, this version - communicates with the user process via an RPC protocol (see the 'protocol' - module). The user program is loaded by the 'loader' and 'Remote' - modules. Its standard output and input are directed back to the - ExecBinding class through the RPC mechanism and implemented here. - - A "stop program" command is provided and bound to control-break. Closing - the output window also stops the running program. -""" - -import sys -import os -import imp -import OutputWindow -import protocol -import spawn -import traceback -import tempfile - -# Find Python and the loader. This should be done as early in execution -# as possible, because if the current directory or sys.path is changed -# it may no longer be possible to get correct paths for these things. - -pyth_exe = spawn.hardpath( sys.executable ) -load_py = spawn.hardpath( imp.find_module("loader")[1] ) - -# The following mechanism matches loaders up with ExecBindings that are -# trying to load something. - -waiting_for_loader = [] - -def loader_connect(client, addr): - if waiting_for_loader: - a = waiting_for_loader.pop(0) - try: - return a.connect(client, addr) - except: - return loader_connect(client,addr) - -protocol.publish('ExecBinding', loader_connect) - -class ExecBinding: - menudefs = [ - ('run', [None, - ('Run program', '<<run-complete-script>>'), - ('Stop program', '<<stop-execution>>'), - ] - ), - ] - - delegate = 1 - - def __init__(self, editwin): - self.editwin = editwin - self.client = None - self.temp = [] - - if not hasattr(editwin, 'source_window'): - self.delegate = 0 - self.output = OutputWindow.OnDemandOutputWindow(editwin.flist) - self.output.close_hook = self.stopProgram - self.output.source_window = editwin - else: - if (self.editwin.source_window and - self.editwin.source_window.extensions.has_key('ExecBinding') and - not self.editwin.source_window.extensions['ExecBinding'].delegate): - delegate = self.editwin.source_window.extensions['ExecBinding'] - self.run_complete_script_event = delegate.run_complete_script_event - self.stop_execution_event = delegate.stop_execution_event - - def __del__(self): - self.stopProgram() - - def stop_execution_event(self, event): - if self.client: - self.stopProgram() - self.write('\nProgram stopped.\n','stderr') - - def run_complete_script_event(self, event): - filename = self.getfilename() - if not filename: return - filename = os.path.abspath(filename) - - self.stopProgram() - - self.commands = [ ('run', filename) ] - waiting_for_loader.append(self) - spawn.spawn( pyth_exe, load_py ) - - def connect(self, client, addr): - # Called by loader_connect() above. It is remotely possible that - # we get connected to two loaders if the user is running the - # program repeatedly in a short span of time. In this case, we - # simply return None, refusing to connect and letting the redundant - # loader die. - if self.client: return None - - self.client = client - client.set_close_hook( self.connect_lost ) - - title = self.editwin.short_title() - if title: - self.output.set_title(title + " Output") - else: - self.output.set_title("Output") - self.output.write('\n',"stderr") - self.output.scroll_clear() - - return self - - def connect_lost(self): - # Called by the client's close hook when the loader closes its - # socket. - - # We print a disconnect message only if the output window is already - # open. - if self.output.owin and self.output.owin.text: - self.output.owin.interrupt() - self.output.write("\nProgram disconnected.\n","stderr") - - for t in self.temp: - try: - os.remove(t) - except: - pass - self.temp = [] - self.client = None - - def get_command(self): - # Called by Remote to find out what it should be executing. - # Later this will be used to implement debugging, interactivity, etc. - if self.commands: - return self.commands.pop(0) - return ('finish',) - - def program_exception(self, type, value, tb, first, last): - if type == SystemExit: return 0 - - for i in range(len(tb)): - filename, lineno, name, line = tb[i] - if filename in self.temp: - filename = 'Untitled' - tb[i] = filename, lineno, name, line - - list = traceback.format_list(tb[first:last]) - exc = traceback.format_exception_only( type, value ) - - self.write('Traceback (innermost last)\n', 'stderr') - for i in (list+exc): - self.write(i, 'stderr') - - self.commands = [] - return 1 - - def write(self, text, tag): - self.output.write(text,tag) - - def readline(self): - return self.output.readline() - - def stopProgram(self): - if self.client: - self.client.close() - self.client = None - - def getfilename(self): - # Save all files which have been named, because they might be modules - for edit in self.editwin.flist.inversedict.keys(): - if edit.io and edit.io.filename and not edit.get_saved(): - edit.io.save(None) - - # Experimental: execute unnamed buffer - if not self.editwin.io.filename: - filename = os.path.normcase(os.path.abspath(tempfile.mktemp())) - self.temp.append(filename) - if self.editwin.io.writefile(filename): - return filename - - # If the file isn't save, we save it. If it doesn't have a filename, - # the user will be prompted. - if self.editwin.io and not self.editwin.get_saved(): - self.editwin.io.save(None) - - # If the file *still* isn't saved, we give up. - if not self.editwin.get_saved(): - return - - return self.editwin.io.filename |