]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-107724: Fix the signature of `PY_THROW` callback functions. (GH-107725)
authorMark Shannon <mark@hotpy.org>
Wed, 9 Aug 2023 08:30:50 +0000 (09:30 +0100)
committerGitHub <noreply@github.com>
Wed, 9 Aug 2023 08:30:50 +0000 (09:30 +0100)
Include/internal/pycore_instruments.h
Lib/test/test_monitoring.py
Misc/NEWS.d/next/Core and Builtins/2023-08-04-21-25-26.gh-issue-107724.EbBXMr.rst [new file with mode: 0644]
Python/ceval.c
Python/instrumentation.c
Python/legacy_tracing.c

index ccccd54a2f70a22200d98147480ee9e25a397280..56de9f8717148449226a04614d07ecc50e9c003f 100644 (file)
@@ -90,10 +90,6 @@ extern int
 _Py_call_instrumentation_2args(PyThreadState *tstate, int event,
     _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1);
 
-extern void
-_Py_call_instrumentation_exc0(PyThreadState *tstate, int event,
-    _PyInterpreterFrame *frame, _Py_CODEUNIT *instr);
-
 extern void
 _Py_call_instrumentation_exc2(PyThreadState *tstate, int event,
     _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1);
index b36382c8d0982d1f054586b5289d8021ecdb099b..845185be737eb2c6740abbfae81dfaf5ac489290 100644 (file)
@@ -743,6 +743,13 @@ class ExceptionHandledRecorder(ExceptionRecorder):
     def __call__(self, code, offset, exc):
         self.events.append(("handled", type(exc)))
 
+class ThrowRecorder(ExceptionRecorder):
+
+    event_type = E.PY_THROW
+
+    def __call__(self, code, offset, exc):
+        self.events.append(("throw", type(exc)))
+
 class ExceptionMonitoringTest(CheckEvents):
 
 
@@ -888,6 +895,31 @@ class ExceptionMonitoringTest(CheckEvents):
             func,
             recorders = self.exception_recorders)
 
+    def test_throw(self):
+
+        def gen():
+            yield 1
+            yield 2
+
+        def func():
+            try:
+                g = gen()
+                next(g)
+                g.throw(IndexError)
+            except IndexError:
+                pass
+
+        self.check_balanced(
+            func,
+            recorders = self.exception_recorders)
+
+        events = self.get_events(
+            func,
+            TEST_TOOL,
+            self.exception_recorders + (ThrowRecorder,)
+        )
+        self.assertEqual(events[0], ("throw", IndexError))
+
 class LineRecorder:
 
     event_type = E.LINE
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-04-21-25-26.gh-issue-107724.EbBXMr.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-04-21-25-26.gh-issue-107724.EbBXMr.rst
new file mode 100644 (file)
index 0000000..6e853cf
--- /dev/null
@@ -0,0 +1,3 @@
+In pre-release versions of 3.12, up to rc1, the sys.monitoring callback
+function for the ``PY_THROW`` event was missing the third, exception
+argument. That is now fixed.
index 1dc4fd80224bbdf18dcc60fcdd6720e837e6b73f..b966399a342d08d784e515fa71b6fb1400aa1dbd 100644 (file)
@@ -2039,7 +2039,7 @@ monitor_throw(PyThreadState *tstate,
     if (no_tools_for_event(tstate, frame, PY_MONITORING_EVENT_PY_THROW)) {
         return;
     }
-    _Py_call_instrumentation_exc0(tstate, PY_MONITORING_EVENT_PY_THROW, frame, instr);
+    do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_THROW);
 }
 
 void
index 123c20dfe1a99b1db21c34eba5f88dedfa88bb86..65ea7902a80a60e9406d1a4e045f10498ef7ba70 100644 (file)
@@ -1081,16 +1081,6 @@ call_instrumentation_vector_protected(
     assert(_PyErr_Occurred(tstate));
 }
 
-void
-_Py_call_instrumentation_exc0(
-    PyThreadState *tstate, int event,
-    _PyInterpreterFrame *frame, _Py_CODEUNIT *instr)
-{
-    assert(_PyErr_Occurred(tstate));
-    PyObject *args[3] = { NULL, NULL, NULL };
-    call_instrumentation_vector_protected(tstate, event, frame, instr, 2, args);
-}
-
 void
 _Py_call_instrumentation_exc2(
     PyThreadState *tstate, int event,
index 48db51731cfdb09af026ddd79f4e5da828d4fa60..7774d10b10172bedaa7b788a2e8f4a4fe92f678e 100644 (file)
@@ -163,7 +163,7 @@ sys_trace_func2(
 }
 
 static PyObject *
-sys_trace_unwind(
+sys_trace_func3(
     _PyLegacyEventHandler *self, PyObject *const *args,
     size_t nargsf, PyObject *kwnames
 ) {
@@ -445,7 +445,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
             return -1;
         }
         if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
-            (vectorcallfunc)sys_trace_func2, PyTrace_CALL,
+            (vectorcallfunc)sys_trace_func3, PyTrace_CALL,
                         PY_MONITORING_EVENT_PY_THROW, -1)) {
             return -1;
         }
@@ -470,7 +470,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
             return -1;
         }
         if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
-            (vectorcallfunc)sys_trace_unwind, PyTrace_RETURN,
+            (vectorcallfunc)sys_trace_func3, PyTrace_RETURN,
                         PY_MONITORING_EVENT_PY_UNWIND, -1)) {
             return -1;
         }