diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/idlelib/PyShell.py | 45 | ||||
-rw-r--r-- | Lib/idlelib/ScriptBinding.py | 11 | ||||
-rw-r--r-- | Lib/idlelib/rpc.py | 7 | ||||
-rw-r--r-- | Lib/idlelib/run.py | 58 |
4 files changed, 57 insertions, 64 deletions
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index dc47f07..cb38411 100644 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -296,6 +296,14 @@ class ModifiedUndoDelegator(UndoDelegator): pass UndoDelegator.delete(self, index1, index2) + +class MyRPCClient(rpc.RPCClient): + + def handle_EOF(self): + "Override the base class - just re-raise EOFError" + raise EOFError + + class ModifiedInterpreter(InteractiveInterpreter): def __init__(self, tkconsole): @@ -329,7 +337,7 @@ class ModifiedInterpreter(InteractiveInterpreter): for i in range(3): time.sleep(i) try: - self.rpcclt = rpc.RPCClient(addr) + self.rpcclt = MyRPCClient(addr) break except socket.error, err: print>>sys.__stderr__,"IDLE socket error: " + err[1]\ @@ -426,9 +434,10 @@ class ModifiedInterpreter(InteractiveInterpreter): except (EOFError, IOError, KeyboardInterrupt): # lost connection or subprocess terminated itself, restart # [the KBI is from rpc.SocketIO.handle_EOF()] + if self.tkconsole.closing: + return response = None self.restart_subprocess() - self.tkconsole.endexecuting() if response: self.tkconsole.resetoutput() self.active_seq = None @@ -673,7 +682,9 @@ class PyShell(OutputWindow): def __init__(self, flist=None): if use_subprocess: - self.menu_specs.insert(2, ("shell", "_Shell")) + ms = self.menu_specs + if ms[2][0] != "shell": + ms.insert(2, ("shell", "_Shell")) self.interp = ModifiedInterpreter(self) if flist is None: root = Tk() @@ -793,15 +804,9 @@ class PyShell(OutputWindow): parent=self.text) if response == False: return "cancel" - # interrupt the subprocess - self.canceled = True - if use_subprocess: - self.interp.interrupt_subprocess() - return "cancel" - else: - self.closing = True - # Wait for poll_subprocess() rescheduling to stop - self.text.after(2 * self.pollinterval, self.close2) + self.closing = True + # Wait for poll_subprocess() rescheduling to stop + self.text.after(2 * self.pollinterval, self.close2) def close2(self): return EditorWindow.close(self) @@ -885,7 +890,10 @@ class PyShell(OutputWindow): if self.reading: self.top.quit() elif (self.executing and self.interp.rpcclt): - self.interp.interrupt_subprocess() + if self.interp.getdebugger(): + self.interp.restart_subprocess() + else: + self.interp.interrupt_subprocess() return "break" def eof_callback(self, event): @@ -1021,16 +1029,7 @@ class PyShell(OutputWindow): self.text.see("restart") def restart_shell(self, event=None): - if self.executing: - self.cancel_callback() - # Wait for subprocess to interrupt and restart - # This can be a long time if shell is scrolling on a slow system - # XXX 14 May 03 KBK This delay (and one in ScriptBinding) could be - # shorter if we didn't print the KeyboardInterrupt on - # restarting while user code is running.... - self.text.after(2000, self.interp.restart_subprocess) - else: - self.interp.restart_subprocess() + self.interp.restart_subprocess() def showprompt(self): self.resetoutput() diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py index 252526d..b6d9da3 100644 --- a/Lib/idlelib/ScriptBinding.py +++ b/Lib/idlelib/ScriptBinding.py @@ -125,17 +125,6 @@ class ScriptBinding: interp = shell.interp if PyShell.use_subprocess: shell.restart_shell() - if shell.executing: - delay = 2700 - else: - delay = 500 - # Wait for the interrupt and reset to finish - shell.text.after(delay, self.run_module_event2, interp, - filename, code) - else: - self.run_module_event2(interp, filename, code) - - def run_module_event2(self, interp, filename, code): # XXX Too often this discards arguments the user just set... interp.runcommand("""if 1: _filename = %s diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index 8bb1aba..658aaf3 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -41,7 +41,6 @@ import copy_reg import types import marshal -import interrupt def unpickle_code(ms): co = marshal.loads(ms) @@ -327,12 +326,9 @@ class SocketIO: while len(s) > 0: try: n = self.sock.send(s) - except AttributeError: + except (AttributeError, socket.error): # socket was closed raise IOError - except socket.error: - self.debug("putmessage:socketerror:pid:%s" % os.getpid()) - os._exit(0) else: s = s[n:] @@ -471,7 +467,6 @@ class SocketIO: self.responses[key] = ('EOF', None) cv.notify() cv.release() - interrupt.interrupt_main() # call our (possibly overridden) exit function self.exithook() diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 98255c7..abc9969 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -21,7 +21,8 @@ import __main__ # the socket) and the main thread (which runs user code), plus global # completion and exit flags: -exit_requested = False +exit_now = False +quitting = False def main(): """Start the Python execution server in a subprocess @@ -41,6 +42,8 @@ def main(): register and unregister themselves. """ + global exit_now + global quitting port = 8833 if sys.argv[1:]: port = int(sys.argv[1]) @@ -52,8 +55,12 @@ def main(): sockthread.start() while 1: try: - if exit_requested: - sys.exit(0) + if exit_now: + try: + sys.exit(0) + except KeyboardInterrupt: + # exiting but got an extra KBI? Try again! + continue try: seq, request = rpc.request_queue.get(0) except Queue.Empty: @@ -63,17 +70,22 @@ def main(): ret = method(*args, **kwargs) rpc.response_queue.put((seq, ret)) except KeyboardInterrupt: + if quitting: + exit_now = True continue except SystemExit: raise except: + type, value, tb = sys.exc_info() try: print_exception() rpc.response_queue.put((seq, None)) except: - traceback.print_exc(file=sys.__stderr__) - sys.exit(1.1) - continue + # Link didn't work, print same exception to __stderr__ + traceback.print_exception(type, value, tb, file=sys.__stderr__) + sys.exit(0) + else: + continue def manage_socket(address): for i in range(6): @@ -89,17 +101,17 @@ def manage_socket(address): + err[1] + ", retrying...." else: print>>sys.__stderr__, "\nConnection to Idle failed, exiting." - global exit_requested - exit_requested = True + global exit_now + exit_now = True return server.handle_request() # A single request only def print_exception(): flush_stdout() efile = sys.stderr - typ, val, tb = info = sys.exc_info() + typ, val, tb = sys.exc_info() tbe = traceback.extract_tb(tb) - print >>efile, 'Traceback (most recent call last):' + print >>efile, '\nTraceback (most recent call last):' exclude = ("run.py", "rpc.py", "threading.py", "Queue.py", "RemoteDebugger.py", "bdb.py") cleanup_traceback(tbe, exclude) @@ -161,8 +173,8 @@ class MyRPCServer(rpc.RPCServer): except SystemExit: raise except EOFError: - global exit_requested - exit_requested = True + global exit_now + exit_now = True interrupt.interrupt_main() except: erf = sys.__stderr__ @@ -174,7 +186,7 @@ class MyRPCServer(rpc.RPCServer): traceback.print_exc(file=erf) print>>erf, '\n*** Unrecoverable, server exiting!' print>>erf, '-'*40 - os._exit(0) + sys.exit(0) class MyHandler(rpc.RPCHandler): @@ -190,15 +202,18 @@ class MyHandler(rpc.RPCHandler): def exithook(self): "override SocketIO method - wait for MainThread to shut us down" - while 1: pass + time.sleep(10) def EOFhook(self): "Override SocketIO method - terminate wait on callback and exit thread" - global exit_requested - exit_requested = True + global quitting + quitting = True + interrupt.interrupt_main() def decode_interrupthook(self): "interrupt awakened thread" + global quitting + quitting = True interrupt.interrupt_main() @@ -213,15 +228,10 @@ class Executive: try: exec code in self.locals except: - if exit_requested: + if quitting: sys.exit(0) - try: - # even print a user code SystemExit exception, continue - print_exception() - except: - # link not working? - traceback.print_exc(file=sys.__stderr__) - sys.exit(1.2) + # even print a user code SystemExit exception, continue + print_exception() else: flush_stdout() |