https://github.com/python/cpython/commit/ddf7156babdfce174c3e5e86ffd5869adc62cfe5
commit: ddf7156babdfce174c3e5e86ffd5869adc62cfe5
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2026-10-22T15:20:56-07:00
summary:

[3.14] gh-159739: Skip context watchers cleared during notification (GH-160164) 
(#160289)



A context watcher callback can clear a later watcher while a context-switch 
notification is being dispatched. The dispatcher still uses its earlier 
snapshot of active watchers, so it calls a NULL callback and crashes; check 
that each callback is still registered before invoking it. Backport to 3.15 and 
3.14.
(cherry picked from commit 0a5762621ff6b4110fae01caf2f85ea93c54a238)

Co-authored-by: Jelle Zijlstra <[email protected]>

files:
A Misc/NEWS.d/next/C_API/2026-10-21-19-55-00.gh-issue-159739.ctxt01.rst
M Python/context.c

diff --git 
a/Misc/NEWS.d/next/C_API/2026-10-21-19-55-00.gh-issue-159739.ctxt01.rst 
b/Misc/NEWS.d/next/C_API/2026-10-21-19-55-00.gh-issue-159739.ctxt01.rst
new file mode 100644
index 000000000000000..10c268e1043c9ed
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2026-10-21-19-55-00.gh-issue-159739.ctxt01.rst
@@ -0,0 +1,2 @@
+Avoid a crash if a context watcher is cleared while other context watchers
+are being notified.
diff --git a/Python/context.c b/Python/context.c
index 5ea677d86a4aafe..65b5d5a036eb36a 100644
--- a/Python/context.c
+++ b/Python/context.c
@@ -169,8 +169,8 @@ notify_context_watchers(PyThreadState *ts, PyContextEvent 
event, PyObject *ctx)
         assert(i < CONTEXT_MAX_WATCHERS);
         if (bits & 1) {
             PyContext_WatchCallback cb = interp->context_watchers[i];
-            assert(cb != NULL);
-            if (cb(event, ctx) < 0) {
+            // A previous callback may have cleared this watcher.
+            if (cb != NULL && cb(event, ctx) < 0) {
                 PyErr_FormatUnraisable(
                     "Exception ignored in %s watcher callback for %R",
                     context_event_name(event), ctx);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to