This looks promising. I have a dedicate library for in-production runtime profiling, but the goal of that library is more high-level than this PEP: I suspect monitoring every function call, then checking if the called function is in the set of functions I want to monitor, could still lead to a significant performance penalty.
I usually know callbacks which are invoked when events occur as “event handlers”.
Do you expect tools to update their event handlers for newer versions of Python, or are you guaranteeing that the required event handler signature stays the same in newer versions (or uses some dynamic argument-passing via inspection)? If not, would you consider some struct / named-tuple / slotted-dataclass as the only argument (or code, struct
as two arguments) for all handlers going forward?
You say that “the callee’s frame will be on the stack”, suggesting that the event handler will have access to that frame (and the rest of the stack). Does that mean the event handler’s (invocation’s) frame will be on the same stack (as the next frame)? That’s seems to be the case judging by the event handler’s signature. This would mean exceptions raised in the handler could bubble to the user, and look like the user is partly responsible (as their code is part of the traceback). Alternatively, I suggest putting the event handler in its own new stack, and passing the stack/frame in to the handler (or you could just warn raised exceptions in handlers).