8000 gh-99633: Add context manager support to `contextvars.Context` by rhansen · Pull Request #99634 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-99633: Add context manager support to contextvars.Context #99634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
gh-124872: Change PyContext_WatchCallback to take PyObject
The PyContext struct is not intended to be public, and users of the
API don't need anything more specific than PyObject.  Also see
gh-78943.
  • Loading branch information
rhansen committed Oct 10, 2024
commit 7681358931d0300b91955a8f8123a1e607d5c621
2 changes: 1 addition & 1 deletion Doc/c-api/contextvars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ Context object management functions:

.. versionadded:: 3.14

.. c:type:: int (*PyContext_WatchCallback)(PyContextEvent event, PyContext* ctx)
.. c:type:: int (*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.
Expand Down
2 changes: 1 addition & 1 deletion Include/cpython/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ typedef enum {
* if the callback returns with an exception set, it must return -1. Otherwise
* it should return 0
*/
typedef int (*PyContext_WatchCallback)(PyContextEvent, PyContext *);
typedef int (*PyContext_WatchCallback)(PyContextEvent, PyObject *);

/*
* Register a per-interpreter callback that will be invoked for context object
Expand Down
10 changes: 5 additions & 5 deletions Modules/_testcapi/watchers.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ 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
handle_context_watcher_event(int which_watcher, PyContextEvent event, PyContext *ctx) {
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 @@ -644,22 +644,22 @@ handle_context_watcher_event(int which_watcher, PyContextEvent event, PyContext
}

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

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

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

static int
error_context_event_handler(PyContextEvent event, PyContext *ctx) {
error_context_event_handler(PyContextEvent event, PyObject *ctx) {
PyErr_SetString(PyExc_RuntimeError, "boom!");
return -1;
}
Expand Down
7 changes: 4 additions & 3 deletions Python/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ context_event_name(PyContextEvent event) {
Py_UNREACHABLE();
}

static void notify_context_watchers(PyContextEvent event, PyContext *ctx, PyThreadState *ts)
static void
notify_context_watchers(PyContextEvent event, PyObject *ctx, PyThreadState *ts)
{
assert(Py_REFCNT(ctx) > 0);
PyInterpreterState *interp = ts->interp;
Expand Down Expand Up @@ -192,7 +193,7 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx)
ts->context = Py_NewRef(ctx);
ts->context_ver++;

notify_context_watchers(Py_CONTEXT_EVENT_ENTER, ctx, ts);
notify_context_watchers(Py_CONTEXT_EVENT_ENTER, octx, ts);
return 0;
}

Expand Down Expand Up @@ -226,7 +227,7 @@ _PyContext_Exit(PyThreadState *ts, PyObject *octx)
return -1;
}

notify_context_watchers(Py_CONTEXT_EVENT_EXIT, ctx, ts);
notify_context_watchers(Py_CONTEXT_EVENT_EXIT, octx, ts);
Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev);
ts->context_ver++;

Expand Down
Loading
0