[pypy-svn] r4812 - in pypy/trunk/src/pypy/interpreter: . test

pedronis at codespeak.net pedronis at codespeak.net
Tue Jun 1 17:41:27 CEST 2004


Author: pedronis
Date: Tue Jun  1 17:41:27 2004
New Revision: 4812

Modified:
   pypy/trunk/src/pypy/interpreter/error.py
   pypy/trunk/src/pypy/interpreter/pyframe.py
   pypy/trunk/src/pypy/interpreter/pyopcode.py
   pypy/trunk/src/pypy/interpreter/test/test_interpreter.py
Log:
added 3 args raise and re-raise 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 17:41:27 2004
@@ -20,10 +20,10 @@
     (frame, instruction_position) making the application-level traceback.
     """
 
-    def __init__(self, w_type, w_value):
+    def __init__(self, w_type, w_value, tb=None):
         self.w_type = w_type
         self.w_value = w_value
-        self.application_traceback = None
+        self.application_traceback = tb
         self.debug_tbs = []
 
     def match(self, space, w_check_class):

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 17:41:27 2004
@@ -49,12 +49,8 @@
                         # dispatch() is abstract, see pyopcode.
                         self.dispatch()
                     except OperationError, e:
-                        #import traceback
-                        #traceback.print_exc()
                         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
                         # exception
                         import sys
@@ -263,10 +259,23 @@
 class SApplicationException(ControlFlowException):
     """Unroll the stack because of an application-level exception
     (i.e. an OperationException)."""
+
+    def action(self, frame, last_instr, executioncontext):
+        e = self.args[0]
+        frame.last_exception = e
+        executioncontext.exception_trace(e)
+
+        ControlFlowException.action(self, frame,
+                                    last_instr, executioncontext)
+
     def emptystack(self, frame):
         # propagate the exception to the caller
-        operationerr, tb = self.args
-        raise operationerr.__class__, operationerr, tb
+        if len(self.args) == 2:
+            operationerr, tb = self.args
+            raise operationerr.__class__, operationerr, tb
+        else:
+            operationerr = self.args[0]
+            raise operationerr
 
 class SBreakLoop(ControlFlowException):
     """Signals a 'break' statement."""

Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyopcode.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyopcode.py	Tue Jun  1 17:41:27 2004
@@ -6,7 +6,8 @@
 
 from pypy.interpreter.baseobjspace import OperationError, NoValue
 from pypy.interpreter.eval import UNDEFINED
-from pypy.interpreter import baseobjspace, pyframe, gateway, function
+from pypy.interpreter import baseobjspace, gateway, function
+from pypy.interpreter import pyframe, pytraceback
 from pypy.interpreter.miscutils import InitializedClass
 
 
@@ -302,8 +303,17 @@
         if nbargs >= 1: w_type      = f.valuestack.pop()
         w_resulttuple = prepare_raise(f.space, w_type, w_value, w_traceback)
         w_type, w_value, w_traceback = f.space.unpacktuple(w_resulttuple, 3)
-        # XXX the three-arguments 'raise' is not supported yet
-        raise OperationError(w_type, w_value)
+        tb = f.space.unwrap(w_traceback)
+        if tb is not None:
+            if not isinstance(tb,pytraceback.PyTraceback):
+                raise OperationError(f.space.w_TypeError,
+                      f.space.wrap("raise: arg 3 must be a traceback or None"))
+            operror = OperationError(w_type,w_value,tb)
+            # re-raise, no new traceback obj will be attached
+            raise pyframe.SApplicationException(operror) 
+        else:
+            # common-case
+            raise OperationError(w_type, w_value)
 
     def LOAD_LOCALS(f):
         f.valuestack.push(f.w_locals)
@@ -850,11 +860,12 @@
         value = etype
         etype = value.__class__
     elif isinstance(etype, type) and issubclass(etype, Exception):
-        if value is None:
-            value = ()
-        elif not isinstance(value, tuple):
-            value = (value,)
-        value = etype(*value)
+        if not isinstance(value,etype):
+            if value is None:
+                value = ()
+            elif not isinstance(value, tuple):
+                value = (value,)
+            value = etype(*value)
     else:
         raise TypeError("exceptions must be instances or subclasses of "
                         "Exception or strings (deprecated), not %s" %

Modified: pypy/trunk/src/pypy/interpreter/test/test_interpreter.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/test/test_interpreter.py	(original)
+++ pypy/trunk/src/pypy/interpreter/test/test_interpreter.py	Tue Jun  1 17:41:27 2004
@@ -185,6 +185,20 @@
         else:
             self.fail("shouldn't be able to raise 1")
 
+    def test_raise_three_args(self):
+        import sys
+        try:
+            raise ValueError
+        except:
+            exc_type,exc_val,exc_tb = sys.exc_info()
+        try:
+            raise exc_type,exc_val,exc_tb
+        except:
+            exc_type2,exc_val2,exc_tb2 = sys.exc_info()
+        self.assertEquals(exc_type,exc_type2)
+        self.assertEquals(exc_val,exc_val2)
+        self.assertEquals(exc_tb,exc_tb2)
+
     def test_trivial_call(self):
         def f(): return 42
         self.assertEquals(f(), 42)



More information about the Pypy-commit mailing list