]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Set line number of END_ASYNC_FOR so that it doesn't show in traces. (GH-27255)
authorMark Shannon <mark@hotpy.org>
Tue, 20 Jul 2021 10:09:56 +0000 (11:09 +0100)
committerGitHub <noreply@github.com>
Tue, 20 Jul 2021 10:09:56 +0000 (12:09 +0200)
Lib/test/test_sys_settrace.py
Python/compile.c

index 482e918acac574a54df23ae90a89ee2ec74b3601..7519309c5e58955447e6b52ed5234ece680700d7 100644 (file)
@@ -602,6 +602,50 @@ class TraceTestCase(unittest.TestCase):
         self.compare_events(doit_async.__code__.co_firstlineno,
                             tracer.events, events)
 
+    def test_21_async_for_else(self):
+
+        async def async_gen():
+            yield -2
+
+        async def async_test():
+            global a
+            a = 2
+            async for i in async_gen():
+                a = 4
+            else:
+                a = 6
+
+        def run(tracer):
+            x = async_test()
+            try:
+                sys.settrace(tracer)
+                x.send(None)
+            finally:
+                sys.settrace(None)
+
+        tracer = self.make_tracer()
+        events = [
+                (0, 'call'),
+                (2, 'line'),
+                (3, 'line'),
+                (-3, 'call'),
+                (-2, 'line'),
+                (-2, 'return'),
+                (3, 'exception'),
+                (4, 'line'),
+                (3, 'line'),
+                (-2, 'call'),
+                (-2, 'return'),
+                (3, 'exception'),
+                (6, 'line'),
+                (6, 'return')]
+        try:
+            run(tracer.trace)
+        except Exception:
+            pass
+        self.compare_events(async_test.__code__.co_firstlineno,
+                            tracer.events, events)
+
 
 class SkipLineEventsTraceTestCase(TraceTestCase):
     """Repeat the trace tests, but with per-line events skipped"""
index 722d52dbcefb1a7ddfdd9fe77ad6ed17180cb196..f426050ccef5bce2212c366d3cc9150769a8b6fe 100644 (file)
@@ -2816,6 +2816,12 @@ compiler_async_for(struct compiler *c, stmt_ty s)
 
     /* Except block for __anext__ */
     compiler_use_next_block(c, except);
+
+    /* We don't want to trace the END_ASYNC_FOR, so make sure
+     * that it has the same lineno as the following instruction. */
+    if (asdl_seq_LEN(s->v.For.orelse)) {
+        SET_LOC(c, (stmt_ty)asdl_seq_GET(s->v.For.orelse, 0));
+    }
     ADDOP(c, END_ASYNC_FOR);
 
     /* `else` block */