Skip to content

Commit ca49b94

Browse files
committed
gh-124872: Change PyContext_WatchCallback return type to void
The exception is ignored so change the return type from `int` to `void` to discourage callbacks from raising an exception in the first place.
1 parent c5789a9 commit ca49b94

File tree

4 files changed

+14
-19
lines changed

4 files changed

+14
-19
lines changed

Doc/c-api/contextvars.rst

+2-4
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,15 @@ Context object management functions:
136136
137137
.. versionadded:: 3.14
138138
139-
.. c:type:: int (*PyContext_WatchCallback)(PyContextEvent event, PyObject *obj)
139+
.. c:type:: void (*PyContext_WatchCallback)(PyContextEvent event, PyObject *obj)
140140
141141
Context object watcher callback function. The object passed to the callback
142142
is event-specific; see :c:type:`PyContextEvent` for details.
143143
144144
Any pending exception is cleared before the callback is called and restored
145145
after the callback returns.
146146
147-
If the callback returns with an exception set, it must return ``-1``; this
148-
exception will be printed as an unraisable exception using
149-
:c:func:`PyErr_FormatUnraisable`. Otherwise it should return ``0``.
147+
If the callback raises an exception it will be ignored.
150148
151149
.. versionadded:: 3.14
152150

Include/cpython/context.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ typedef enum {
5252
* Any pending exception is cleared before the callback is called and restored
5353
* after the callback returns.
5454
*
55-
* if the callback returns with an exception set, it must return -1. Otherwise
56-
* it should return 0
55+
* If the callback raises an exception it will be ignored.
5756
*/
58-
typedef int (*PyContext_WatchCallback)(PyContextEvent, PyObject *);
57+
typedef void (*PyContext_WatchCallback)(PyContextEvent, PyObject *);
5958

6059
/*
6160
* Register a per-interpreter callback that will be invoked for context object

Modules/_testcapi/watchers.c

+8-11
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ static int context_watcher_ids[NUM_CONTEXT_WATCHERS] = {-1, -1};
629629
static int num_context_object_enter_events[NUM_CONTEXT_WATCHERS] = {0, 0};
630630
static int num_context_object_exit_events[NUM_CONTEXT_WATCHERS] = {0, 0};
631631

632-
static int
632+
static void
633633
handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *ctx) {
634634
if (event == Py_CONTEXT_EVENT_ENTER) {
635635
num_context_object_enter_events[which_watcher]++;
@@ -638,30 +638,27 @@ handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *
638638
num_context_object_exit_events[which_watcher]++;
639639
}
640640
else {
641-
return -1;
641+
Py_UNREACHABLE();
642642
}
643-
return 0;
644643
}
645644

646-
static int
645+
static void
647646
first_context_watcher_callback(PyContextEvent event, PyObject *ctx) {
648-
return handle_context_watcher_event(0, event, ctx);
647+
handle_context_watcher_event(0, event, ctx);
649648
}
650649

651-
static int
650+
static void
652651
second_context_watcher_callback(PyContextEvent event, PyObject *ctx) {
653-
return handle_context_watcher_event(1, event, ctx);
652+
handle_context_watcher_event(1, event, ctx);
654653
}
655654

656-
static int
655+
static void
657656
noop_context_event_handler(PyContextEvent event, PyObject *ctx) {
658-
return 0;
659657
}
660658

661-
static int
659+
static void
662660
error_context_event_handler(PyContextEvent event, PyObject *ctx) {
663661
PyErr_SetString(PyExc_RuntimeError, "boom!");
664-
return -1;
665662
}
666663

667664
static PyObject *

Python/context.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyObject *ctx)
126126
PyContext_WatchCallback cb = interp->context_watchers[i];
127127
assert(cb != NULL);
128128
PyObject *exc = _PyErr_GetRaisedException(ts);
129-
if (cb(event, ctx) < 0) {
129+
cb(event, ctx);
130+
if (_PyErr_Occurred(ts) != NULL) {
130131
PyErr_FormatUnraisable(
131132
"Exception ignored in %s watcher callback for %R",
132133
context_event_name(event), ctx);

0 commit comments

Comments
 (0)