]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-110514: Add PY_THROW to `sys.setprofile` events (GH-110524) (#110541)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 9 Oct 2023 09:11:51 +0000 (11:11 +0200)
committerGitHub <noreply@github.com>
Mon, 9 Oct 2023 09:11:51 +0000 (09:11 +0000)
gh-110514: Add PY_THROW to `sys.setprofile` events (GH-110524)
(cherry picked from commit dd4bb0529e44ac6f75a9ebbfcbf5d73dc251b7a7)

Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
Lib/test/test_sys_setprofile.py
Misc/NEWS.d/next/Core and Builtins/2023-10-08-20-08-54.gh-issue-110514.Q9bdRU.rst [new file with mode: 0644]
Python/legacy_tracing.c

index 34c70d6c8de0c458b9236e20fee822c2cf1d41bc..9e8936630de920c186804f501e3ff1c20dcc5e30 100644 (file)
@@ -255,6 +255,25 @@ class ProfileHookTestCase(TestCaseBase):
                               (1, 'return', g_ident),
                               ])
 
+    def test_unfinished_generator(self):
+        def f():
+            for i in range(2):
+                yield i
+        def g(p):
+            next(f())
+
+        f_ident = ident(f)
+        g_ident = ident(g)
+        self.check_events(g, [(1, 'call', g_ident),
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              # once more; the generator is being garbage collected
+                              # and it will do a PY_THROW
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              (1, 'return', g_ident),
+                              ])
+
     def test_stop_iteration(self):
         def f():
             for i in range(2):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-08-20-08-54.gh-issue-110514.Q9bdRU.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-08-20-08-54.gh-issue-110514.Q9bdRU.rst
new file mode 100644 (file)
index 0000000..96363c2
--- /dev/null
@@ -0,0 +1 @@
+Add ``PY_THROW`` to :func:`sys.setprofile` events
index b0136d2ebc75548c459bdc6635e7c0003a657190..43fa5910ef6dd179e1ad1d13e5f48e05fabb2eee 100644 (file)
@@ -377,6 +377,11 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
                         PY_MONITORING_EVENT_PY_START, PY_MONITORING_EVENT_PY_RESUME)) {
             return -1;
         }
+        if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
+            (vectorcallfunc)sys_profile_func3, PyTrace_CALL,
+                        PY_MONITORING_EVENT_PY_THROW, -1)) {
+            return -1;
+        }
         if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
             (vectorcallfunc)sys_profile_func3, PyTrace_RETURN,
                         PY_MONITORING_EVENT_PY_RETURN, PY_MONITORING_EVENT_PY_YIELD)) {
@@ -417,7 +422,8 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
         events =
             (1 << PY_MONITORING_EVENT_PY_START) | (1 << PY_MONITORING_EVENT_PY_RESUME) |
             (1 << PY_MONITORING_EVENT_PY_RETURN) | (1 << PY_MONITORING_EVENT_PY_YIELD) |
-            (1 << PY_MONITORING_EVENT_CALL) | (1 << PY_MONITORING_EVENT_PY_UNWIND);
+            (1 << PY_MONITORING_EVENT_CALL) | (1 << PY_MONITORING_EVENT_PY_UNWIND) |
+            (1 << PY_MONITORING_EVENT_PY_THROW);
     }
     return _PyMonitoring_SetEvents(PY_MONITORING_SYS_PROFILE_ID, events);
 }