summaryrefslogtreecommitdiff
path: root/Lib/idlelib
diff options
context:
space:
mode:
authorKurt B. Kaiser <kbk@shore.net>2003-01-31 05:06:43 +0000
committerKurt B. Kaiser <kbk@shore.net>2003-01-31 05:06:43 +0000
commit8cd0def10dc028e3522a04bd136c67f92f90da04 (patch)
tree29e3d148f95ddc1c3c824f6d7c32ed61ca4364ec /Lib/idlelib
parentd17406830cef6ee1f34e42013ae60e69dc91d71f (diff)
downloadcpython-git-8cd0def10dc028e3522a04bd136c67f92f90da04.tar.gz
M PyShell.py
M rpc.py SF Bug 676398 Doesn't handle non-built-in exceptions 1. Move exception formatting to the subprocess; allows subclassing of exceptions, including subclasses created in the shell without introducing excessive complexity in the RPC mechanism. 2. Provide access to linecache from subprocess to support this.
Diffstat (limited to 'Lib/idlelib')
-rw-r--r--Lib/idlelib/PyShell.py48
-rw-r--r--Lib/idlelib/rpc.py78
2 files changed, 42 insertions, 84 deletions
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index cbfd2036db..98e091821b 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 c7644e1681..b50643ada8 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