1:mod:`!sys.monitoring` --- Execution event monitoring 2===================================================== 3 4.. module:: sys.monitoring 5 :synopsis: Access and control event monitoring 6 7.. versionadded:: 3.12 8 9----------------- 10 11.. note:: 12 13 :mod:`sys.monitoring` is a namespace within the :mod:`sys` module, 14 not an independent module, so there is no need to 15 ``import sys.monitoring``, simply ``import sys`` and then use 16 ``sys.monitoring``. 17 18 19This namespace provides access to the functions and constants necessary to 20activate and control event monitoring. 21 22As programs execute, events occur that might be of interest to tools that 23monitor execution. The :mod:`sys.monitoring` namespace provides means to 24receive callbacks when events of interest occur. 25 26The monitoring API consists of three components: 27 28* `Tool identifiers`_ 29* `Events`_ 30* :ref:`Callbacks <callbacks>` 31 32Tool identifiers 33---------------- 34 35A tool identifier is an integer and the associated name. 36Tool identifiers are used to discourage tools from interfering with each 37other and to allow multiple tools to operate at the same time. 38Currently tools are completely independent and cannot be used to 39monitor each other. This restriction may be lifted in the future. 40 41Before registering or activating events, a tool should choose an identifier. 42Identifiers are integers in the range 0 to 5 inclusive. 43 44Registering and using tools 45''''''''''''''''''''''''''' 46 47.. function:: use_tool_id(tool_id: int, name: str, /) -> None 48 49 Must be called before *tool_id* can be used. 50 *tool_id* must be in the range 0 to 5 inclusive. 51 Raises a :exc:`ValueError` if *tool_id* is in use. 52 53.. function:: free_tool_id(tool_id: int, /) -> None 54 55 Should be called once a tool no longer requires *tool_id*. 56 57.. note:: 58 59 :func:`free_tool_id` will not disable global or local events associated 60 with *tool_id*, nor will it unregister any callback functions. This 61 function is only intended to be used to notify the VM that the 62 particular *tool_id* is no longer in use. 63 64.. function:: get_tool(tool_id: int, /) -> str | None 65 66 Returns the name of the tool if *tool_id* is in use, 67 otherwise it returns ``None``. 68 *tool_id* must be in the range 0 to 5 inclusive. 69 70All IDs are treated the same by the VM with regard to events, but the 71following IDs are pre-defined to make co-operation of tools easier:: 72 73 sys.monitoring.DEBUGGER_ID = 0 74 sys.monitoring.COVERAGE_ID = 1 75 sys.monitoring.PROFILER_ID = 2 76 sys.monitoring.OPTIMIZER_ID = 5 77 78 79Events 80------ 81 82The following events are supported: 83 84.. monitoring-event:: BRANCH 85 86 A conditional branch is taken (or not). 87 88.. monitoring-event:: CALL 89 90 A call in Python code (event occurs before the call). 91 92.. monitoring-event:: C_RAISE 93 94 An exception raised from any callable, except for Python functions (event occurs after the exit). 95 96.. monitoring-event:: C_RETURN 97 98 Return from any callable, except for Python functions (event occurs after the return). 99 100.. monitoring-event:: EXCEPTION_HANDLED 101 102 An exception is handled. 103 104.. monitoring-event:: INSTRUCTION 105 106 A VM instruction is about to be executed. 107 108.. monitoring-event:: JUMP 109 110 An unconditional jump in the control flow graph is made. 111 112.. monitoring-event:: LINE 113 114 An instruction is about to be executed that has a different line number from the preceding instruction. 115 116.. monitoring-event:: PY_RESUME 117 118 Resumption of a Python function (for generator and coroutine functions), except for ``throw()`` calls. 119 120.. monitoring-event:: PY_RETURN 121 122 Return from a Python function (occurs immediately before the return, the callee's frame will be on the stack). 123 124.. monitoring-event:: PY_START 125 126 Start of a Python function (occurs immediately after the call, the callee's frame will be on the stack) 127 128.. monitoring-event:: PY_THROW 129 130 A Python function is resumed by a ``throw()`` call. 131 132.. monitoring-event:: PY_UNWIND 133 134 Exit from a Python function during exception unwinding. 135 136.. monitoring-event:: PY_YIELD 137 138 Yield from a Python function (occurs immediately before the yield, the callee's frame will be on the stack). 139 140.. monitoring-event:: RAISE 141 142 An exception is raised, except those that cause a :monitoring-event:`STOP_ITERATION` event. 143 144.. monitoring-event:: RERAISE 145 146 An exception is re-raised, for example at the end of a :keyword:`finally` block. 147 148.. monitoring-event:: STOP_ITERATION 149 150 An artificial :exc:`StopIteration` is raised; see `the STOP_ITERATION event`_. 151 152 153More events may be added in the future. 154 155These events are attributes of the :mod:`!sys.monitoring.events` namespace. 156Each event is represented as a power-of-2 integer constant. 157To define a set of events, simply bitwise or the individual events together. 158For example, to specify both :monitoring-event:`PY_RETURN` and :monitoring-event:`PY_START` 159events, use the expression ``PY_RETURN | PY_START``. 160 161.. monitoring-event:: NO_EVENTS 162 163 An alias for ``0`` so users can do explicit comparisons like:: 164 165 if get_events(DEBUGGER_ID) == NO_EVENTS: 166 ... 167 168Events are divided into three groups: 169 170Local events 171'''''''''''' 172 173Local events are associated with normal execution of the program and happen 174at clearly defined locations. All local events can be disabled. 175The local events are: 176 177* :monitoring-event:`PY_START` 178* :monitoring-event:`PY_RESUME` 179* :monitoring-event:`PY_RETURN` 180* :monitoring-event:`PY_YIELD` 181* :monitoring-event:`CALL` 182* :monitoring-event:`LINE` 183* :monitoring-event:`INSTRUCTION` 184* :monitoring-event:`JUMP` 185* :monitoring-event:`BRANCH` 186* :monitoring-event:`STOP_ITERATION` 187 188Ancillary events 189'''''''''''''''' 190 191Ancillary events can be monitored like other events, but are controlled 192by another event: 193 194* :monitoring-event:`C_RAISE` 195* :monitoring-event:`C_RETURN` 196 197The :monitoring-event:`C_RETURN` and :monitoring-event:`C_RAISE` events 198are controlled by the :monitoring-event:`CALL` event. 199:monitoring-event:`C_RETURN` and :monitoring-event:`C_RAISE` events will only be seen if the 200corresponding :monitoring-event:`CALL` event is being monitored. 201 202Other events 203'''''''''''' 204 205Other events are not necessarily tied to a specific location in the 206program and cannot be individually disabled. 207 208The other events that can be monitored are: 209 210* :monitoring-event:`PY_THROW` 211* :monitoring-event:`PY_UNWIND` 212* :monitoring-event:`RAISE` 213* :monitoring-event:`EXCEPTION_HANDLED` 214 215 216The STOP_ITERATION event 217'''''''''''''''''''''''' 218 219:pep:`PEP 380 <380#use-of-stopiteration-to-return-values>` 220specifies that a :exc:`StopIteration` exception is raised when returning a value 221from a generator or coroutine. However, this is a very inefficient way to 222return a value, so some Python implementations, notably CPython 3.12+, do not 223raise an exception unless it would be visible to other code. 224 225To allow tools to monitor for real exceptions without slowing down generators 226and coroutines, the :monitoring-event:`STOP_ITERATION` event is provided. 227:monitoring-event:`STOP_ITERATION` can be locally disabled, unlike :monitoring-event:`RAISE`. 228 229 230Turning events on and off 231------------------------- 232 233In order to monitor an event, it must be turned on and a corresponding callback 234must be registered. 235Events can be turned on or off by setting the events either globally or 236for a particular code object. 237 238 239Setting events globally 240''''''''''''''''''''''' 241 242Events can be controlled globally by modifying the set of events being monitored. 243 244.. function:: get_events(tool_id: int, /) -> int 245 246 Returns the ``int`` representing all the active events. 247 248.. function:: set_events(tool_id: int, event_set: int, /) -> None 249 250 Activates all events which are set in *event_set*. 251 Raises a :exc:`ValueError` if *tool_id* is not in use. 252 253No events are active by default. 254 255Per code object events 256'''''''''''''''''''''' 257 258Events can also be controlled on a per code object basis. The functions 259defined below which accept a :class:`types.CodeType` should be prepared 260to accept a look-alike object from functions which are not defined 261in Python (see :ref:`c-api-monitoring`). 262 263.. function:: get_local_events(tool_id: int, code: CodeType, /) -> int 264 265 Returns all the local events for *code* 266 267.. function:: set_local_events(tool_id: int, code: CodeType, event_set: int, /) -> None 268 269 Activates all the local events for *code* which are set in *event_set*. 270 Raises a :exc:`ValueError` if *tool_id* is not in use. 271 272Local events add to global events, but do not mask them. 273In other words, all global events will trigger for a code object, 274regardless of the local events. 275 276 277Disabling events 278'''''''''''''''' 279 280.. data:: DISABLE 281 282 A special value that can be returned from a callback function to disable 283 events for the current code location. 284 285Local events can be disabled for a specific code location by returning 286:data:`sys.monitoring.DISABLE` from a callback function. This does not change 287which events are set, or any other code locations for the same event. 288 289Disabling events for specific locations is very important for high 290performance monitoring. For example, a program can be run under a 291debugger with no overhead if the debugger disables all monitoring 292except for a few breakpoints. 293 294.. function:: restart_events() -> None 295 296 Enable all the events that were disabled by :data:`sys.monitoring.DISABLE` 297 for all tools. 298 299 300.. _callbacks: 301 302Registering callback functions 303------------------------------ 304 305To register a callable for events call 306 307.. function:: register_callback(tool_id: int, event: int, func: Callable | None, /) -> Callable | None 308 309 Registers the callable *func* for the *event* with the given *tool_id* 310 311 If another callback was registered for the given *tool_id* and *event*, 312 it is unregistered and returned. 313 Otherwise :func:`register_callback` returns ``None``. 314 315 316Functions can be unregistered by calling 317``sys.monitoring.register_callback(tool_id, event, None)``. 318 319Callback functions can be registered and unregistered at any time. 320 321Registering or unregistering a callback function will generate a :func:`sys.audit` event. 322 323 324Callback function arguments 325''''''''''''''''''''''''''' 326 327.. data:: MISSING 328 329 A special value that is passed to a callback function to indicate 330 that there are no arguments to the call. 331 332When an active event occurs, the registered callback function is called. 333Different events will provide the callback function with different arguments, as follows: 334 335* :monitoring-event:`PY_START` and :monitoring-event:`PY_RESUME`:: 336 337 func(code: CodeType, instruction_offset: int) -> DISABLE | Any 338 339* :monitoring-event:`PY_RETURN` and :monitoring-event:`PY_YIELD`:: 340 341 func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any 342 343* :monitoring-event:`CALL`, :monitoring-event:`C_RAISE` and :monitoring-event:`C_RETURN`:: 344 345 func(code: CodeType, instruction_offset: int, callable: object, arg0: object | MISSING) -> DISABLE | Any 346 347 If there are no arguments, *arg0* is set to :data:`sys.monitoring.MISSING`. 348 349* :monitoring-event:`RAISE`, :monitoring-event:`RERAISE`, :monitoring-event:`EXCEPTION_HANDLED`, 350 :monitoring-event:`PY_UNWIND`, :monitoring-event:`PY_THROW` and :monitoring-event:`STOP_ITERATION`:: 351 352 func(code: CodeType, instruction_offset: int, exception: BaseException) -> DISABLE | Any 353 354* :monitoring-event:`LINE`:: 355 356 func(code: CodeType, line_number: int) -> DISABLE | Any 357 358* :monitoring-event:`BRANCH` and :monitoring-event:`JUMP`:: 359 360 func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any 361 362 Note that the *destination_offset* is where the code will next execute. 363 For an untaken branch this will be the offset of the instruction following 364 the branch. 365 366* :monitoring-event:`INSTRUCTION`:: 367 368 func(code: CodeType, instruction_offset: int) -> DISABLE | Any 369