Skip to content

Commit

Permalink
pythongh-124872: Change PyContext_WatchCallback return type to void
Browse files Browse the repository at this point in the history
The exception is ignored so change the return type from `int` to
`void` to discourage callbacks from raising an exception in the first
place.
  • Loading branch information
rhansen committed Oct 12, 2024
1 parent c5789a9 commit ca49b94
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 19 deletions.
6 changes: 2 additions & 4 deletions Doc/c-api/contextvars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,15 @@ Context object management functions:
.. versionadded:: 3.14
.. c:type:: int (*PyContext_WatchCallback)(PyContextEvent event, PyObject *obj)
.. c:type:: void (*PyContext_WatchCallback)(PyContextEvent event, PyObject *obj)
Context object watcher callback function. The object passed to the callback
is event-specific; see :c:type:`PyContextEvent` for details.
Any pending exception is cleared before the callback is called and restored
after the callback returns.
If the callback returns with an exception set, it must return ``-1``; this
exception will be printed as an unraisable exception using
:c:func:`PyErr_FormatUnraisable`. Otherwise it should return ``0``.
If the callback raises an exception it will be ignored.
.. versionadded:: 3.14
Expand Down
5 changes: 2 additions & 3 deletions Include/cpython/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ typedef enum {
* Any pending exception is cleared before the callback is called and restored
* after the callback returns.
*
* if the callback returns with an exception set, it must return -1. Otherwise
* it should return 0
* If the callback raises an exception it will be ignored.
*/
typedef int (*PyContext_WatchCallback)(PyContextEvent, PyObject *);
typedef void (*PyContext_WatchCallback)(PyContextEvent, PyObject *);

/*
* Register a per-interpreter callback that will be invoked for context object
Expand Down
19 changes: 8 additions & 11 deletions Modules/_testcapi/watchers.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ static int context_watcher_ids[NUM_CONTEXT_WATCHERS] = {-1, -1};
static int num_context_object_enter_events[NUM_CONTEXT_WATCHERS] = {0, 0};
static int num_context_object_exit_events[NUM_CONTEXT_WATCHERS] = {0, 0};

static int
static void
handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *ctx) {
if (event == Py_CONTEXT_EVENT_ENTER) {
num_context_object_enter_events[which_watcher]++;
Expand All @@ -638,30 +638,27 @@ handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *
num_context_object_exit_events[which_watcher]++;
}
else {
return -1;
Py_UNREACHABLE();
}
return 0;
}

static int
static void
first_context_watcher_callback(PyContextEvent event, PyObject *ctx) {
return handle_context_watcher_event(0, event, ctx);
handle_context_watcher_event(0, event, ctx);
}

static int
static void
second_context_watcher_callback(PyContextEvent event, PyObject *ctx) {
return handle_context_watcher_event(1, event, ctx);
handle_context_watcher_event(1, event, ctx);
}

static int
static void
noop_context_event_handler(PyContextEvent event, PyObject *ctx) {
return 0;
}

static int
static void
error_context_event_handler(PyContextEvent event, PyObject *ctx) {
PyErr_SetString(PyExc_RuntimeError, "boom!");
return -1;
}

static PyObject *
Expand Down
3 changes: 2 additions & 1 deletion Python/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyObject *ctx)
PyContext_WatchCallback cb = interp->context_watchers[i];
assert(cb != NULL);
PyObject *exc = _PyErr_GetRaisedException(ts);
if (cb(event, ctx) < 0) {
cb(event, ctx);
if (_PyErr_Occurred(ts) != NULL) {
PyErr_FormatUnraisable(
"Exception ignored in %s watcher callback for %R",
context_event_name(event), ctx);
Expand Down

0 comments on commit ca49b94

Please sign in to comment.