[pypy-commit] pypy py3.5: Test and fix for a similar exception_trace() inside YIELD_FROM

arigo pypy.commits at gmail.com
Mon Dec 12 08:04:16 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r89019:d05548c7343d
Date: 2016-12-12 14:02 +0100
http://bitbucket.org/pypy/pypy/changeset/d05548c7343d/

Log:	Test and fix for a similar exception_trace() inside YIELD_FROM

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -185,6 +185,7 @@
             if not e.match(space, space.w_StopIteration):
                 raise
             e.normalize_exception(space)
+            space.getexecutioncontext().exception_trace(frame, e)
             try:
                 w_stop_value = space.getattr(e.get_w_value(space),
                                              space.wrap("value"))
diff --git a/pypy/interpreter/test/test_pyframe.py b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -652,9 +652,11 @@
         gen = f()
         assert next(gen) == 5
         seen = []
+        frames = []
         def trace_func(frame, event, *args):
             print('TRACE:', frame, event, args)
             seen.append(event)
+            frames.append(frame)
             return trace_func
         def g():
             for x in gen:
@@ -666,6 +668,63 @@
         # on Python 3 we get an extra 'exception' when 'for' catches
         # StopIteration
         assert seen == ['call', 'line', 'call', 'return', 'exception', 'return']
+        assert frames[-2].f_code.co_name == 'g'
+
+    def test_yieldfrom_trace_stopiteration(self): """
+        import sys
+        def f2():
+            yield 5
+        def f():
+            yield from f2()
+        gen = f()
+        assert next(gen) == 5
+        seen = []
+        frames = []
+        def trace_func(frame, event, *args):
+            print('TRACE:', frame, event, args)
+            seen.append(event)
+            frames.append(frame)
+            return trace_func
+        def g():
+            for x in gen:
+                never_entered
+        sys.settrace(trace_func)
+        g()      # invokes next_yield_from() from resume_execute_frame()
+        sys.settrace(None)
+        print('seen:', seen)
+        assert seen == ['call', 'line', 'call', 'call', 'return',
+                        'exception', 'return', 'exception', 'return']
+        assert frames[-4].f_code.co_name == 'f'
+        assert frames[-2].f_code.co_name == 'g'
+        """
+
+    def test_yieldfrom_trace_stopiteration_2(self): """
+        import sys
+        def f2():
+            if False:
+                yield 5
+        def f():
+            yield from f2()
+        gen = f()
+        seen = []
+        frames = []
+        def trace_func(frame, event, *args):
+            print('TRACE:', frame, event, args)
+            seen.append(event)
+            frames.append(frame)
+            return trace_func
+        def g():
+            for x in gen:
+                never_entered
+        sys.settrace(trace_func)
+        g()      # invokes next_yield_from() from YIELD_FROM()
+        sys.settrace(None)
+        print('seen:', seen)
+        assert seen == ['call', 'line', 'call', 'line', 'call', 'line',
+                        'return', 'exception', 'return', 'exception', 'return']
+        assert frames[-4].f_code.co_name == 'f'
+        assert frames[-2].f_code.co_name == 'g'
+        """
 
     def test_clear_locals(self):
         def make_frames():


More information about the pypy-commit mailing list