summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/idlelib/PyShell.py45
-rw-r--r--Lib/idlelib/ScriptBinding.py11
-rw-r--r--Lib/idlelib/rpc.py7
-rw-r--r--Lib/idlelib/run.py58
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()