Disclaimer: I work for Datadog and am interested in this feature in the context of dd-trace-py, our Python instrumentation library.
Summary
Python 3.14 added support for observing contextvars.Context switches through the Py_CONTEXT_SWITCHED event. Extension authors can register callbacks for this event using PyContext_AddWatcher.
It would be useful for a greenlet switch to trigger these watchers whenever resuming the target greenlet changes the current Context. This would provide a generic observability mechanism shared with asyncio and other parts of the Python ecosystem.
This is directly relevant to gevent: gevent.Greenlet subclasses greenlet.greenlet, and switching to its hub ultimately calls the underlying greenlet.switch() implementation. Implementing this in greenlet itself would therefore cover gevent without requiring a gevent-specific hook, while also benefiting other greenlet users.
Current behavior
Before switching, greenlet saves PyThreadState.context. When the target greenlet resumes, it restores that pointer directly and increments context_ver to invalidate the context variable cache.
In CPython, watcher notification is performed by the internal context_switched() helper. That helper is reached through PyContext_Enter and PyContext_Exit, but not when PyThreadState.context is changed directly.
As a result, greenlet correctly restores ContextVar values, but registered context watchers are not notified of the switch.
Design considerations
The only realistic approach I see is to push for exposing a new CPython API to trigger arbitrarily the interpreter registered watchers.
Or have an API to swap a context on PyThreadState which would handle the context_ver bump and the watcher invocations itself.
Would you be interested to support the feature, if such an API existed ?
Disclaimer: I work for Datadog and am interested in this feature in the context of dd-trace-py, our Python instrumentation library.
Summary
Python 3.14 added support for observing
contextvars.Contextswitches through thePy_CONTEXT_SWITCHEDevent. Extension authors can register callbacks for this event usingPyContext_AddWatcher.It would be useful for a greenlet switch to trigger these watchers whenever resuming the target greenlet changes the current
Context. This would provide a generic observability mechanism shared withasyncioand other parts of the Python ecosystem.This is directly relevant to gevent:
gevent.Greenletsubclassesgreenlet.greenlet, and switching to its hub ultimately calls the underlyinggreenlet.switch()implementation. Implementing this in greenlet itself would therefore cover gevent without requiring a gevent-specific hook, while also benefiting other greenlet users.Current behavior
Before switching, greenlet saves
PyThreadState.context. When the target greenlet resumes, it restores that pointer directly and incrementscontext_verto invalidate the context variable cache.In CPython, watcher notification is performed by the internal
context_switched()helper. That helper is reached throughPyContext_EnterandPyContext_Exit, but not whenPyThreadState.contextis changed directly.As a result, greenlet correctly restores
ContextVarvalues, but registered context watchers are not notified of the switch.Design considerations
The only realistic approach I see is to push for exposing a new CPython API to trigger arbitrarily the interpreter registered watchers.
Or have an API to swap a context on PyThreadState which would handle the
context_verbump and the watcher invocations itself.Would you be interested to support the feature, if such an API existed ?