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

iko at codespeak.net iko at codespeak.net
Wed Apr 15 17:59:22 CEST 2009


Author: iko
Date: Wed Apr 15 17:59:21 2009
New Revision: 64105

Modified:
   pypy/trunk/pypy/interpreter/pyframe.py
   pypy/trunk/pypy/interpreter/test/test_pyframe.py
Log:
(iko, tismer)

'return' trace event should happen even if the return is caused by
raising an exception



Modified: pypy/trunk/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pyframe.py	(original)
+++ pypy/trunk/pypy/interpreter/pyframe.py	Wed Apr 15 17:59:21 2009
@@ -109,6 +109,7 @@
         assert isinstance(self, self.space.FrameClass)
         executioncontext = self.space.getexecutioncontext()
         executioncontext.enter(self)
+        w_exitvalue = self.space.w_None
         try:
             executioncontext.call_trace(self)
             # Execution starts just after the last_instr.  Initially,
@@ -118,12 +119,14 @@
             w_exitvalue = self.dispatch(self.pycode, next_instr,
                                         executioncontext)
             rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue)
-            executioncontext.return_trace(self, w_exitvalue)
             # on exit, we try to release self.last_exception -- breaks an
             # obvious reference cycle, so it helps refcounting implementations
             self.last_exception = None
         finally:
-            executioncontext.leave(self)
+            try:
+                executioncontext.return_trace(self, w_exitvalue)
+            finally:
+                executioncontext.leave(self)
         return w_exitvalue
     execute_frame.insert_stack_check_here = True
 

Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py
==============================================================================
--- pypy/trunk/pypy/interpreter/test/test_pyframe.py	(original)
+++ pypy/trunk/pypy/interpreter/test/test_pyframe.py	Wed Apr 15 17:59:21 2009
@@ -140,6 +140,49 @@
         assert len(l) == 1
         assert isinstance(l[0][1], Exception)
 
+    def test_trace_return_exc(self):
+        import sys
+        l = []
+        def trace(a,b,c): 
+            if b in ('exception', 'return'):
+                l.append((b, c))
+            return trace
+
+        def g():
+            raise Exception            
+        def f():
+            try:
+                g()
+            except:
+                pass
+        sys.settrace(trace)
+        f()
+        sys.settrace(None)
+        assert len(l) == 4
+        assert l[0][0] == 'exception'
+        assert isinstance(l[0][1][1], Exception)
+        assert l[1] == ('return', None)
+        assert l[2][0] == 'exception'
+        assert isinstance(l[2][1][1], Exception)
+        assert l[3] == ('return', None)
+
+    def test_trace_raises_on_return(self):
+        import sys
+        def trace(frame, event, arg):
+            if event == 'return':
+                raise ValueError
+            else:
+                return trace
+
+        def f(): return 1
+
+        for i in xrange(sys.getrecursionlimit() + 1):
+            sys.settrace(trace)
+            try:
+                f()
+            except ValueError:
+                pass
+
     def test_dont_trace_on_reraise(self):
         import sys
         l = []



More information about the Pypy-commit mailing list