[pypy-svn] r4806 - in pypy/trunk/src/pypy: interpreter module module/test

pedronis at codespeak.net pedronis at codespeak.net
Tue Jun 1 16:11:36 CEST 2004


Author: pedronis
Date: Tue Jun  1 16:11:35 2004
New Revision: 4806

Added:
   pypy/trunk/src/pypy/interpreter/pytraceback.py
Modified:
   pypy/trunk/src/pypy/interpreter/error.py
   pypy/trunk/src/pypy/interpreter/interactive.py
   pypy/trunk/src/pypy/interpreter/pyframe.py
   pypy/trunk/src/pypy/module/sysinterp.py
   pypy/trunk/src/pypy/module/sysmodule.py
   pypy/trunk/src/pypy/module/test/test_sysmodule.py
Log:
added traceback objects and sys.exc_info support


Modified: pypy/trunk/src/pypy/interpreter/error.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/error.py	(original)
+++ pypy/trunk/src/pypy/interpreter/error.py	Tue Jun  1 16:11:35 2004
@@ -23,12 +23,9 @@
     def __init__(self, w_type, w_value):
         self.w_type = w_type
         self.w_value = w_value
-        self.application_traceback = []
+        self.application_traceback = None
         self.debug_tbs = []
 
-    def record_application_traceback(self, frame, last_instruction):
-        self.application_traceback.append((frame, last_instruction))
-
     def match(self, space, w_check_class):
         "Check if this application-level exception matches 'w_check_class'."
         return space.exception_match(self.w_type, w_check_class)
@@ -47,8 +44,7 @@
     def getframe(self):
         "The frame this exception was raised in, or None."
         if self.application_traceback:
-            frame, last_instruction = self.application_traceback[0]
-            return frame
+            return self.application_traceback.frame
         else:
             return None
 
@@ -65,14 +61,13 @@
         print >> file, self.errorstr(space)
 
     def print_app_tb_only(self, file):
-        tb = self.application_traceback[:]
+        tb = self.application_traceback
         if tb:
             import linecache
-            tb.reverse()
             print >> file, "Traceback (application-level):"
-            for f, i in tb:
-                co = f.code
-                lineno = offset2lineno(co, i)
+            while tb is not None:
+                co = tb.frame.code
+                lineno = tb.lineno
                 fname = co.co_filename
                 if fname.startswith('<inline>\n'):
                     lines = fname.split('\n')
@@ -89,6 +84,7 @@
                     if l.endswith('\n'):
                         l = l[:-1]
                     print >> file, l
+                tb = tb.next
 
     def print_detailed_traceback(self, space=None, file=None):
         """Dump a nice detailed interpreter- and application-level traceback,
@@ -131,17 +127,6 @@
     return compile(w(source), w('<inline>\n%s'%source), w(symbol), w(0), w(0))
 
 
-def offset2lineno(c, stopat):
-    tab = c.co_lnotab
-    line = c.co_firstlineno
-    addr = 0
-    for i in range(0, len(tab), 2):
-        addr = addr + ord(tab[i])
-        if addr > stopat:
-            break
-        line = line + ord(tab[i+1])
-    return line
-
 class LinePrefixer:
     """File-like class that inserts a prefix string
     at the beginning of each line it prints."""

Modified: pypy/trunk/src/pypy/interpreter/interactive.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/interactive.py	(original)
+++ pypy/trunk/src/pypy/interpreter/interactive.py	Tue Jun  1 16:11:35 2004
@@ -6,17 +6,6 @@
 import linecache
 
 
-def offset2lineno(c, stopat):
-    tab = c.co_lnotab
-    line = c.co_firstlineno
-    addr = 0
-    for i in range(0, len(tab), 2):
-        addr = addr + ord(tab[i])
-        if addr > stopat:
-            break
-        line = line + ord(tab[i+1])
-    return line
-
 class PyPyConsole(code.InteractiveConsole):
     def __init__(self, objspace):
         code.InteractiveConsole.__init__(self)

Modified: pypy/trunk/src/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyframe.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyframe.py	Tue Jun  1 16:11:35 2004
@@ -4,6 +4,7 @@
 from pypy.interpreter import eval, baseobjspace, gateway
 from pypy.interpreter.miscutils import Stack
 from pypy.interpreter.error import OperationError
+from pypy.interpreter import pytraceback
 
 
 class PyFrame(eval.Frame, baseobjspace.Wrappable):
@@ -50,7 +51,8 @@
                     except OperationError, e:
                         #import traceback
                         #traceback.print_exc()
-                        e.record_application_traceback(self, last_instr)
+                        pytraceback.record_application_traceback(
+                            self.space, e, self, last_instr)
                         self.last_exception = e
                         executioncontext.exception_trace(e)
                         # convert an OperationError into a control flow

Added: pypy/trunk/src/pypy/interpreter/pytraceback.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/interpreter/pytraceback.py	Tue Jun  1 16:11:35 2004
@@ -0,0 +1,49 @@
+from pypy.interpreter import baseobjspace
+
+
+class PyTraceback(baseobjspace.Wrappable):
+    """Traceback object
+
+    Public fields:
+     * 'tb_frame'
+     * 'tb_lasti'
+     * 'tb_lineno'
+     * 'tb_next'
+    """
+
+    def __init__(self, space, frame, lasti, lineno, next):
+        self.space = space
+        self.frame = frame
+        self.lasti = lasti
+        self.lineno = lineno
+        self.next = next
+
+    ### application level visible attributes ###
+    def app_visible(self):
+        def makedict(**kw): return kw
+        space = self.space
+        d = makedict(
+            tb_frame = space.wrap(self.frame),
+            tb_lasti = space.wrap(self.lasti),
+            tb_lineno = space.wrap(self.lineno),
+            tb_next = space.wrap(self.next),
+            )
+        return d.items() 
+
+
+def record_application_traceback(space, operror, frame, last_instruction):
+    lineno = offset2lineno(frame.code, last_instruction)
+    tb = operror.application_traceback
+    tb = PyTraceback(space, frame, last_instruction, lineno, tb)
+    operror.application_traceback = tb
+
+def offset2lineno(c, stopat):
+    tab = c.co_lnotab
+    line = c.co_firstlineno
+    addr = 0
+    for i in range(0, len(tab), 2):
+        addr = addr + ord(tab[i])
+        if addr > stopat:
+            break
+        line = line + ord(tab[i+1])
+    return line

Modified: pypy/trunk/src/pypy/module/sysinterp.py
==============================================================================
--- pypy/trunk/src/pypy/module/sysinterp.py	(original)
+++ pypy/trunk/src/pypy/module/sysinterp.py	Tue Jun  1 16:11:35 2004
@@ -104,3 +104,12 @@
     # XXX No Argument Accepted Yet
     f = space.getexecutioncontext().framestack.items[-1]
     return space.wrap(f)
+
+def exc_info():
+    operror = space.getexecutioncontext().sys_exc_info()
+    if operror is None:
+        return space.newtuple([space.w_None,space.w_None,space.w_None])
+    else:
+        return space.newtuple([operror.w_type,operror.w_value,
+                               space.wrap(operror.application_traceback)])
+    

Modified: pypy/trunk/src/pypy/module/sysmodule.py
==============================================================================
--- pypy/trunk/src/pypy/module/sysmodule.py	(original)
+++ pypy/trunk/src/pypy/module/sysmodule.py	Tue Jun  1 16:11:35 2004
@@ -13,7 +13,7 @@
 from __interplevel__ import hexversion, platform
 
 # Functions from interpreter-level
-from __interplevel__ import displayhook, _getframe
+from __interplevel__ import displayhook, _getframe, exc_info
 
 # Dummy
 executable = ''

Modified: pypy/trunk/src/pypy/module/test/test_sysmodule.py
==============================================================================
--- pypy/trunk/src/pypy/module/test/test_sysmodule.py	(original)
+++ pypy/trunk/src/pypy/module/test/test_sysmodule.py	Tue Jun  1 16:11:35 2004
@@ -65,6 +65,23 @@
         self.failUnless('__builtin__' in names,
                         "__builtin__ is not listed as a builtin module.")
 
+    def test_sys_exc_info(self):
+        try:
+            raise Exception
+        except Exception,e:
+            import sys
+            exc_type,exc_val,tb = sys.exc_info()
+        try:
+            raise Exception   # 5 lines below the previous one
+        except Exception,e2:
+            exc_type2,exc_val2,tb2 = sys.exc_info()
+        self.assertEquals(exc_type,Exception)
+        self.assertEquals(exc_val,e)
+        self.assertEquals(exc_type2,Exception)
+        self.assertEquals(exc_val2,e2)
+        self.assertEquals(tb2.tb_lineno - tb.tb_lineno, 5)
+        
+
 if __name__ == '__main__':
     testit.main()
 



More information about the Pypy-commit mailing list