From 0930c43e43f79617a33a6c3be32afbe184780307 Mon Sep 17 00:00:00 2001
From: "Kurt B. Kaiser" <kbk@shore.net>
Date: Fri, 6 Dec 2002 21:45:24 +0000
Subject: M PyShell.py 1. Format and print exceptions raised in user code.

M rpc.py
1. Additional debug messages in rpc.py
2. Move debug message enable switch from SocketIO to Client and Server
   to allow separate activation.
3. Add indication of origin (client or server) to debug message
4. Add sequence number to appropriate debug messages

5. Pass string exception arg as a string rather than a tuple.
---
 Lib/idlelib/PyShell.py | 24 +++++++++++++++++++-----
 Lib/idlelib/rpc.py     | 35 ++++++++++++++++++++---------------
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index 28dc256..27bae5f 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -11,6 +11,7 @@ import time
 import traceback
 import types
 import warnings
+import exceptions
 
 import linecache
 from code import InteractiveInterpreter
@@ -340,6 +341,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
         if clt is None:
             return
         response = clt.pollresponse(self.active_seq)
+        # Reschedule myself in 50 ms
         self.tkconsole.text.after(50, self.poll_subprocess)
         if response:
             self.tkconsole.resetoutput()
@@ -362,14 +364,24 @@ class ModifiedInterpreter(InteractiveInterpreter):
                         line = linecache.getline(fn, ln)
                         tb[i] = fn, ln, nm, line
                 traceback.print_list(tb, file=file)
-                if mod and mod != "exceptions":
-                    name = mod + "." + name
-                print >>file, name + ":", " ".join(map(str, args))
+                # 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(file, line, '')
+                traceback._print(file, lines[-1], '')
                 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
                     self.remote_stack_viewer()
             elif how == "ERROR":
-                print >>sys.__stderr__, "Oops:", how, what
-                print >>file, "Oops:", how, what
+                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
+                print >>sys.__stderr__, errmsg, what
+                print >>file, errmsg, what
             self.tkconsole.endexecuting()
 
     def kill_subprocess(self):
@@ -416,6 +428,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
             code = compile(source, filename, "exec")
         except (OverflowError, SyntaxError):
             self.tkconsole.resetoutput()
+            console = self.tkconsole.console
+            print >>console, 'Traceback (most recent call last):'
             InteractiveInterpreter.showsyntaxerror(self, filename)
             self.tkconsole.showprompt()
         else:
diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py
index 4bbf0bb..3f1a746 100644
--- a/Lib/idlelib/rpc.py
+++ b/Lib/idlelib/rpc.py
@@ -90,8 +90,6 @@ objecttable = {}
 
 class SocketIO:
 
-    debugging = False
-
     def __init__(self, sock, objtable=None, debugging=None):
         self.mainthread = threading.currentThread()
         if debugging is not None:
@@ -113,11 +111,10 @@ class SocketIO:
     def debug(self, *args):
         if not self.debugging:
             return
-        s = str(threading.currentThread().getName())
+        s = self.location + " " + str(threading.currentThread().getName())
         for a in args:
             s = s + " " + str(a)
-        s = s + "\n"
-        sys.__stderr__.write(s)
+        print>>sys.__stderr__, s
 
     def register(self, oid, object):
         self.objtable[oid] = object
@@ -159,7 +156,7 @@ class SocketIO:
             typ, val, tb = info = sys.exc_info()
             sys.last_type, sys.last_value, sys.last_traceback = info
             if isinstance(typ, type(Exception)):
-                # Class exceptions
+                # Class exception
                 mod = typ.__module__
                 name = typ.__name__
                 if issubclass(typ, Exception):
@@ -167,29 +164,29 @@ class SocketIO:
                 else:
                     args = (str(val),)
             else:
-                # String exceptions
+                # User string exception
                 mod = None
                 name = typ
-                args = (str(val),)
+                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))
 
     def remotecall(self, oid, methodname, args, kwargs):
-        self.debug("remotecall:", oid, methodname, args, kwargs) 
+        self.debug("remotecall:") 
         seq = self.asynccall(oid, methodname, args, kwargs)
-        ret = self.asyncreturn(seq)
-        self.debug("return:", ret)
-        return ret
+        return self.asyncreturn(seq)
 
     def asynccall(self, oid, methodname, args, kwargs):
-        self.debug("asyncall:", oid, methodname, args, kwargs)
         request = ("call", (oid, methodname, args, kwargs))
         seq = self.putrequest(request)
+        self.debug(("asyncall:%d:" % seq), oid, methodname, args, kwargs)
         return seq
 
     def asyncreturn(self, seq):
         response = self.getresponse(seq)
-        self.debug("asyncreturn:", response)
+        self.debug(("asyncreturn:%d:" % seq), response)
         return self.decoderesponse(response)
 
     def decoderesponse(self, response):
@@ -197,6 +194,7 @@ class SocketIO:
         if how == "OK":
             return what
         if how == "EXCEPTION":
+            self.debug("decoderesponse: Internal EXCEPTION:", what)
             mod, name, args, tb = what
             self.traceback = tb
             if mod: # not string exception
@@ -217,6 +215,7 @@ class SocketIO:
             # do the best we can:
             raise name, args
         if how == "ERROR":
+            self.debug("decoderesponse: Internal ERROR:", what)            
             raise RuntimeError, what
         raise SystemError, (how, what)
 
@@ -274,6 +273,7 @@ class SocketIO:
         return seq
 
     def putmessage(self, message):
+        ##self.debug("putmessage: ", message)
         try:
             s = pickle.dumps(message)
         except:
@@ -345,6 +345,7 @@ class SocketIO:
             wait = 0.0
             seq, resq = message
             if resq[0] == "call":
+                self.debug("call_localcall:%d:" % seq)
                 response = self.localcall(resq)
                 self.putmessage((seq, response))
                 continue
@@ -377,7 +378,8 @@ class RemoteProxy:
 
 class RPCHandler(SocketServer.BaseRequestHandler, SocketIO):
 
-    debugging = 0
+    debugging = False
+    location = "#S"  # Server
 
     def __init__(self, sock, addr, svr):
         svr.current_handler = self ## cgt xxx
@@ -393,6 +395,9 @@ class RPCHandler(SocketServer.BaseRequestHandler, SocketIO):
 
 class RPCClient(SocketIO):
 
+    debugging = False
+    location = "#C"  # Client
+
     nextseq = 1 # Requests coming from the client are odd numbered
 
     def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM):
-- 
cgit v0.12

