diff options
Diffstat (limited to 'Lib/idlelib')
-rw-r--r-- | Lib/idlelib/PyShell.py | 48 | ||||
-rw-r--r-- | Lib/idlelib/rpc.py | 78 |
2 files changed, 42 insertions, 84 deletions
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index cbfd203..98e0918 100644 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -353,6 +353,7 @@ class ModifiedInterpreter(InteractiveInterpreter): self.rpcclt.register("stdout", self.tkconsole.stdout) self.rpcclt.register("stderr", self.tkconsole.stderr) self.rpcclt.register("flist", self.tkconsole.flist) + self.rpcclt.register("linecache", linecache) self.transfer_path() self.poll_subprocess() @@ -404,23 +405,6 @@ class ModifiedInterpreter(InteractiveInterpreter): if what is not None: print >>console, `what` elif how == "EXCEPTION": - mod, name, args, tb = what - print >>console, 'Traceback (most recent call last):' - exclude = ("run.py", "rpc.py", "RemoteDebugger.py", "bdb.py") - self.cleanup_traceback(tb, exclude, console) - traceback.print_list(tb, file=console) - # try to reinstantiate the exception, stuff in the args: - try: - etype = eval(mod + '.' + name) - val = etype() - val.args = args - except TypeError: # string exception! - etype = name - val = args - lines = traceback.format_exception_only(etype, val) - for line in lines[:-1]: - traceback._print(console, line, '') - traceback._print(console, lines[-1], '') if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"): self.remote_stack_viewer() elif how == "ERROR": @@ -430,36 +414,6 @@ class ModifiedInterpreter(InteractiveInterpreter): # we received a response to the currently active seq number: self.tkconsole.endexecuting() - def cleanup_traceback(self, tb, exclude, console): - "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: - # error was in IDLE internals, don't prune! - tb[:] = orig_tb[:] - print>>sys.__stderr__, "** IDLE Internal Error: ", tb - print>>console, "** IDLE Internal Error **" - for i in range(len(tb)): - fn, ln, nm, line = tb[i] - if nm == '?': - nm = "-toplevel-" - if not line and fn.startswith("<pyshell#"): - line = linecache.getline(fn, ln) - tb[i] = fn, ln, nm, line - def kill_subprocess(self): clt = self.rpcclt self.rpcclt = None diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index c7644e1..b50643a 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -154,26 +154,49 @@ class SocketIO: ret = remoteref(ret) return ("OK", ret) except: - ##traceback.print_exc(file=sys.__stderr__) + self.debug("localcall:EXCEPTION") + efile = sys.stderr typ, val, tb = info = sys.exc_info() sys.last_type, sys.last_value, sys.last_traceback = info - if isinstance(typ, type(Exception)): - # Class exception - mod = typ.__module__ - name = typ.__name__ - if issubclass(typ, Exception): - args = val.args - else: - args = (str(val),) + tbe = traceback.extract_tb(tb) + print >>efile, 'Traceback (most recent call last):' + exclude = ("run.py", "rpc.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, + return ("EXCEPTION", None) + + 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: - # User string exception - mod = None - name = typ - if val is None: val = '' - args = str(val) - tb = traceback.extract_tb(tb) - self.debug("localcall:EXCEPTION: ", mod, name, args, tb) - return ("EXCEPTION", (mod, name, args, tb)) + 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: + # error was in RPC internals, don't prune! + tb[:] = orig_tb[:] + print>>sys.stderr, "** RPC Internal Error: ", tb + 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.remotecall('linecache', 'getline', + (fn, ln), {}) + tb[i] = fn, ln, nm, line def remotecall(self, oid, methodname, args, kwargs): self.debug("calling asynccall via remotecall") @@ -198,26 +221,7 @@ class SocketIO: if how == "OK": return what if how == "EXCEPTION": - self.debug("decoderesponse: EXCEPTION:", what) - mod, name, args, tb = what - self.traceback = tb - if mod: # not string exception - try: - __import__(mod) - module = sys.modules[mod] - except ImportError: - pass - else: - try: - cls = getattr(module, name) - except AttributeError: - pass - else: - # instantiate a built-in exception object and raise it - raise getattr(__import__(mod), name)(*args) - name = mod + "." + name - # do the best we can: - raise name, args + raise Exception, "RPC SocketIO.decoderesponse exception" if how == "ERROR": self.debug("decoderesponse: Internal ERROR:", what) raise RuntimeError, what |