Accessing state from code watcher callbacks

As far as I can tell you are forced by the code watcher API to use global vars. The callbacks take raw C pointers, and they don’t carry a void* user data parameter. Is there a trick to this? Or a reason the standard user void* pattern for C callbacks isn’t used? IIUC this would prevent being able to reload a module using the API, since you will end up with two module objects but only one global.

/*
 * A callback that is invoked for different events in a code object's lifecycle.
 *
 * The callback is invoked with a borrowed reference to co, after it is
 * created and before it is destroyed.
 *
 * If the callback sets an exception, it must return -1. Otherwise
 * it should return 0.
 */
typedef int (*PyCode_WatchCallback)(
  PyCodeEvent event,
  PyCodeObject* co);

/*
 * Register a per-interpreter callback that will be invoked for code object
 * lifecycle events.
 *
 * Returns a handle that may be passed to PyCode_ClearWatcher on success,
 * or -1 and sets an error if no more handles are available.
 */
PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback);

I think the idea is that you have a global table of some kind, mapping code object ids to some data structure.

1 Like