summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTian Gao <gaogaotiantian@hotmail.com>2023-10-09 08:38:45 (GMT)
committerGitHub <noreply@github.com>2023-10-09 08:38:45 (GMT)
commitdd4bb0529e44ac6f75a9ebbfcbf5d73dc251b7a7 (patch)
tree74449cf04513063416fc4a2ba624af0510b1611f
parent9f8282de6bdc3e1f976318821ff151ed45fedc56 (diff)
downloadcpython-dd4bb0529e44ac6f75a9ebbfcbf5d73dc251b7a7.zip
cpython-dd4bb0529e44ac6f75a9ebbfcbf5d73dc251b7a7.tar.gz
cpython-dd4bb0529e44ac6f75a9ebbfcbf5d73dc251b7a7.tar.bz2
gh-110514: Add PY_THROW to `sys.setprofile` events (GH-110524)
-rw-r--r--Lib/test/test_sys_setprofile.py19
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-10-08-20-08-54.gh-issue-110514.Q9bdRU.rst1
-rw-r--r--Python/legacy_tracing.c8
3 files changed, 27 insertions, 1 deletions
diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py
index 34c70d6..9e893663 100644
--- a/Lib/test/test_sys_setprofile.py
+++ b/Lib/test/test_sys_setprofile.py
@@ -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
index 0000000..96363c2
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-10-08-20-08-54.gh-issue-110514.Q9bdRU.rst
@@ -0,0 +1 @@
+Add ``PY_THROW`` to :func:`sys.setprofile` events
diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c
index 9258091..97d39a1 100644
--- a/Python/legacy_tracing.c
+++ b/Python/legacy_tracing.c
@@ -378,6 +378,11 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
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)) {
return -1;
@@ -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);
}