summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib
diff options
context:
space:
mode:
authorKurt B. Kaiser <kbk@shore.net>2003-05-12 02:33:47 (GMT)
committerKurt B. Kaiser <kbk@shore.net>2003-05-12 02:33:47 (GMT)
commit9ec454ec00088e051195e80363499a14cafc131a (patch)
tree2bb4d5c15dda1bd85e201951a8777136fc49841d /Lib/idlelib
parent8f51526837b7edae4a4424657f0105b35e1c4648 (diff)
downloadcpython-9ec454ec00088e051195e80363499a14cafc131a.zip
cpython-9ec454ec00088e051195e80363499a14cafc131a.tar.gz
cpython-9ec454ec00088e051195e80363499a14cafc131a.tar.bz2
1. RemoteDebugger now runs user code in subprocess MainThread
2. run.py: move exception printing to toplevel to allow access from main() 3. Clarification in PyShell.py: when the subprocess is restarted, the debugger GUI is reused with a fresh instance of the subprocess debugger. M PyShell.py M RemoteDebugger.py M run.py
Diffstat (limited to 'Lib/idlelib')
-rw-r--r--Lib/idlelib/PyShell.py2
-rw-r--r--Lib/idlelib/RemoteDebugger.py2
-rw-r--r--Lib/idlelib/run.py111
3 files changed, 61 insertions, 54 deletions
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index ba898b2..af3267a 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -368,6 +368,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
debug = self.getdebugger()
if debug:
try:
+ # Only close subprocess debugger, don't unregister gui_adap!
RemoteDebugger.close_subprocess_debugger(self.rpcclt)
except:
pass
@@ -387,6 +388,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
console.text.mark_gravity("restart", "left")
# restart subprocess debugger
if debug:
+ # Restarted debugger connects to current instance of debug GUI
gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
# reload remote debugger breakpoints for all PyShellEditWindows
debug.load_breakpoints()
diff --git a/Lib/idlelib/RemoteDebugger.py b/Lib/idlelib/RemoteDebugger.py
index 41f910f..bdcef51 100644
--- a/Lib/idlelib/RemoteDebugger.py
+++ b/Lib/idlelib/RemoteDebugger.py
@@ -300,7 +300,7 @@ class IdbProxy:
def run(self, cmd, locals):
# Ignores locals on purpose!
- seq = self.conn.asynccall(self.oid, "run", (cmd,), {})
+ seq = self.conn.asyncqueue(self.oid, "run", (cmd,), {})
self.shell.interp.active_seq = seq
def get_stack(self, frame, tbid):
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index 320525c..e05be8f 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -62,7 +62,9 @@ def main():
method, args, kwargs = request
ret = method(*args, **kwargs)
rpc.response_queue.put((seq, ret))
- except KeyboardInterrupt:
+ except:
+ print_exception()
+ rpc.response_queue.put((seq, None))
continue
def manage_socket(address):
@@ -84,6 +86,59 @@ def manage_socket(address):
return
server.handle_request() # A single request only
+def print_exception():
+ flush_stdout()
+ efile = sys.stderr
+ typ, val, tb = info = sys.exc_info()
+ tbe = traceback.extract_tb(tb)
+ print >>efile, 'Traceback (most recent call last):'
+ exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
+ "RemoteDebugger.py", "bdb.py")
+ cleanup_traceback(tbe, exclude)
+ traceback.print_list(tbe, file=efile)
+ lines = traceback.format_exception_only(typ, val)
+ for line in lines:
+ print>>efile, line,
+
+def cleanup_traceback(tb, exclude):
+ "Remove excluded traces from beginning/end of tb; get cached lines"
+ orig_tb = tb[:]
+ while tb:
+ for rpcfile in exclude:
+ if tb[0][0].count(rpcfile):
+ break # found an exclude, break for: and delete tb[0]
+ else:
+ break # no excludes, have left RPC code, break while:
+ del tb[0]
+ while tb:
+ for rpcfile in exclude:
+ if tb[-1][0].count(rpcfile):
+ break
+ else:
+ break
+ del tb[-1]
+ if len(tb) == 0:
+ # exception was in IDLE internals, don't prune!
+ tb[:] = orig_tb[:]
+ print>>sys.stderr, "** IDLE Internal Exception: "
+ rpchandler = rpc.objecttable['exec'].rpchandler
+ for i in range(len(tb)):
+ fn, ln, nm, line = tb[i]
+ if nm == '?':
+ nm = "-toplevel-"
+ if not line and fn.startswith("<pyshell#"):
+ line = rpchandler.remotecall('linecache', 'getline',
+ (fn, ln), {})
+ tb[i] = fn, ln, nm, line
+
+def flush_stdout():
+ try:
+ if sys.stdout.softspace:
+ sys.stdout.softspace = 0
+ sys.stdout.write("\n")
+ except (AttributeError, EOFError):
+ pass
+
class MyRPCServer(rpc.RPCServer):
@@ -153,62 +208,12 @@ class Executive:
try:
if exit_requested:
os._exit(0)
- self.flush_stdout()
- efile = sys.stderr
- typ, val, tb = info = sys.exc_info()
- sys.last_type, sys.last_value, sys.last_traceback = info
- tbe = traceback.extract_tb(tb)
- print >>efile, 'Traceback (most recent call last):'
- exclude = ("run.py", "rpc.py", "threading.py",
- "RemoteDebugger.py", "bdb.py")
- self.cleanup_traceback(tbe, exclude)
- traceback.print_list(tbe, file=efile)
- lines = traceback.format_exception_only(typ, val)
- for line in lines:
- print>>efile, line,
+ print_exception()
except:
sys.stderr = sys.__stderr__
raise
else:
- self.flush_stdout()
-
- def flush_stdout(self):
- try:
- if sys.stdout.softspace:
- sys.stdout.softspace = 0
- sys.stdout.write("\n")
- except (AttributeError, EOFError):
- pass
-
- def cleanup_traceback(self, tb, exclude):
- "Remove excluded traces from beginning/end of tb; get cached lines"
- orig_tb = tb[:]
- while tb:
- for rpcfile in exclude:
- if tb[0][0].count(rpcfile):
- break # found an exclude, break for: and delete tb[0]
- else:
- break # no excludes, have left RPC code, break while:
- del tb[0]
- while tb:
- for rpcfile in exclude:
- if tb[-1][0].count(rpcfile):
- break
- else:
- break
- del tb[-1]
- if len(tb) == 0:
- # exception was in IDLE internals, don't prune!
- tb[:] = orig_tb[:]
- print>>sys.stderr, "** IDLE Internal Exception: "
- for i in range(len(tb)):
- fn, ln, nm, line = tb[i]
- if nm == '?':
- nm = "-toplevel-"
- if not line and fn.startswith("<pyshell#"):
- line = self.rpchandler.remotecall('linecache', 'getline',
- (fn, ln), {})
- tb[i] = fn, ln, nm, line
+ flush_stdout()
def interrupt_the_server(self):
interrupt.interrupt_main()