sys.monitoring.md
1> **Источник:** https://python-all.ru/3.15/library/sys.monitoring.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `sys.monitoring` – Мониторинг событий выполнения89Добавлено в версии 3.12.1011---1213> **Примечание**14>15> `sys.monitoring` – это пространство имён в модуле [`sys`](https://python-all.ru/3.15/library/sys.html#module-sys), не независимый модуль, и попытка `import sys.monitoring` приведёт к ошибке [`ModuleNotFoundError`](https://python-all.ru/3.15/library/exceptions.html#ModuleNotFoundError). Вместо этого достаточно `import sys` и затем использовать `sys.monitoring`.1617Это пространство имён предоставляет доступ к функциям и константам, необходимым для активации и управления мониторингом событий.1819В процессе выполнения программ возникают события, которые могут представлять интерес для инструментов, отслеживающих выполнение. Пространство имён `sys.monitoring` предоставляет средства для получения колбэков при возникновении интересующих событий.2021API мониторинга состоит из трёх компонентов:2223- [Идентификаторы инструментов](https://python-all.ru/3.15/library/sys.monitoring.html#tool-identifiers)24- [События](https://python-all.ru/3.15/library/sys.monitoring.html#events)25- [Колбэки](https://python-all.ru/3.15/library/sys.monitoring.html#callbacks)2627## Идентификаторы инструментов2829Идентификатор инструмента – это целое число и связанное с ним имя. Идентификаторы инструментов используются для предотвращения взаимного вмешательства инструментов и для возможности одновременной работы нескольких инструментов. В настоящее время инструменты полностью независимы и не могут использоваться для мониторинга друг друга. В будущем это ограничение может быть снято.3031Перед регистрацией или активацией событий инструмент должен выбрать идентификатор. Идентификаторы – целые числа в диапазоне от 0 до 5 включительно.3233### Регистрация и использование инструментов3435#### `sys.monitoring.use_tool_id(tool_id: int, name: str, /) → None`3637Должен быть вызван до того, как *tool\_id* можно будет использовать. *tool\_id* должен находиться в диапазоне от 0 до 5 включительно. Вызывает исключение [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError), если *tool\_id* уже используется.3839#### `sys.monitoring.clear_tool_id(tool_id: int, /) → None`4041Отменяет регистрацию всех событий и функций обратного вызова, связанных с *tool\_id*.4243#### `sys.monitoring.free_tool_id(tool_id: int, /) → None`4445Должен быть вызван, когда инструмент больше не требует *tool\_id*. Перед освобождением *tool\_id* будет вызвана функция [`clear_tool_id()`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.clear_tool_id).4647#### `sys.monitoring.get_tool(tool_id: int, /) → str | None`4849Возвращает имя инструмента, если *tool\_id* используется, в противном случае возвращает `None`. *tool\_id* должен находиться в диапазоне от 0 до 5 включительно.5051Все идентификаторы обрабатываются виртуальной машиной одинаково с точки зрения событий, но следующие идентификаторы предопределены для упрощения совместной работы инструментов:5253```python54sys.monitoring.DEBUGGER_ID = 055sys.monitoring.COVERAGE_ID = 156sys.monitoring.PROFILER_ID = 257sys.monitoring.OPTIMIZER_ID = 558```5960## События6162Поддерживаются следующие события:6364#### `sys.monitoring.events.BRANCH_LEFT`6566Условный переход идёт влево.6768Инструмент сам решает, как представлять ветви «влево» и «вправо». Нет гарантии, какая ветвь является «левой», а какая «правой», за исключением того, что это будет единообразно на протяжении всей программы.6970#### `sys.monitoring.events.BRANCH_RIGHT`7172Условный переход идёт вправо.7374#### `sys.monitoring.events.CALL`7576Вызов в коде Python (событие происходит до вызова).7778#### `sys.monitoring.events.C_RAISE`7980Исключение, возбуждённое любым вызываемым объектом, за исключением функций Python (событие происходит после выхода).8182#### `sys.monitoring.events.C_RETURN`8384Возврат из любого вызываемого объекта, кроме функций Python (событие происходит после возврата).8586#### `sys.monitoring.events.EXCEPTION_HANDLED`8788Исключение обработано.8990#### `sys.monitoring.events.INSTRUCTION`9192Инструкция виртуальной машины будет выполнена.9394#### `sys.monitoring.events.JUMP`9596Выполняется безусловный переход в графе потока управления.9798#### `sys.monitoring.events.LINE`99100Инструкция, номер строки которой отличается от номера строки предыдущей инструкции, будет выполнена.101102#### `sys.monitoring.events.PY_RESUME`103104Возобновление функции Python (для функций-генераторов и корутинных функций), за исключением вызовов `throw()`.105106#### `sys.monitoring.events.PY_RETURN`107108Возврат из функции Python (происходит непосредственно перед возвратом, фрейм вызываемой функции будет находиться в стеке).109110#### `sys.monitoring.events.PY_START`111112Начало функции Python (происходит сразу после вызова, фрейм вызываемой функции будет находиться в стеке).113114#### `sys.monitoring.events.PY_THROW`115116Функция Python возобновляется вызовом `throw()`.117118#### `sys.monitoring.events.PY_UNWIND`119120Выход из функции Python во время раскрутки стека исключений. Сюда входят исключения, возбуждённые непосредственно внутри функции, и те, которым разрешено распространяться дальше.121122#### `sys.monitoring.events.PY_YIELD`123124Yield из функции Python (происходит непосредственно перед yield, фрейм вызываемой функции будет находиться в стеке).125126#### `sys.monitoring.events.RAISE`127128Исключение возбуждается, за исключением тех, которые приводят к событию [`STOP_ITERATION`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-STOP_ITERATION).129130#### `sys.monitoring.events.RERAISE`131132Исключение возбуждается повторно, например, в конце блока [`finally`](https://python-all.ru/3.15/reference/compound_stmts.html#finally).133134#### `sys.monitoring.events.STOP_ITERATION`135136Возбуждается искусственное [`StopIteration`](https://python-all.ru/3.15/library/exceptions.html#StopIteration); см. [событие STOP\_ITERATION](https://python-all.ru/3.15/library/sys.monitoring.html#the-stop-iteration-event).137138В будущем могут быть добавлены новые события.139140Эти события являются атрибутами пространства имён `sys.monitoring.events`. Каждое событие представлено целочисленной константой, являющейся степенью двойки. Чтобы определить набор событий, достаточно объединить отдельные события побитовым ИЛИ. Например, чтобы указать оба события [`PY_RETURN`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_RETURN) и [`PY_START`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_START), используйте выражение `PY_RETURN | PY_START`.141142#### `sys.monitoring.events.NO_EVENTS`143144Псевдоним для `0`, чтобы пользователи могли выполнять явные сравнения, например:145146```python147if get_events(DEBUGGER_ID) == NO_EVENTS:148 ...149```150151Установка этого события отключает все события.152153### Локальные события154155Локальные события связаны с нормальным выполнением программы и происходят в чётко определённых местах. Все локальные события можно отключать для каждого места отдельно. Локальные события:156157- [`PY_START`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_START)158- [`PY_RESUME`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_RESUME)159- [`PY_RETURN`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_RETURN)160- [`PY_YIELD`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_YIELD)161- [`CALL`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-CALL)162- [`LINE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-LINE)163- [`INSTRUCTION`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-INSTRUCTION)164- [`JUMP`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-JUMP)165- [`BRANCH_LEFT`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-BRANCH_LEFT)166- [`BRANCH_RIGHT`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-BRANCH_RIGHT)167- [`STOP_ITERATION`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-STOP_ITERATION)168169### Устаревшее событие170171- `BRANCH`172173Событие `BRANCH` устарело в версии 3.14. Использование событий [`BRANCH_LEFT`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-BRANCH_LEFT) и [`BRANCH_RIGHT`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-BRANCH_RIGHT) даёт гораздо лучшую производительность, так как их можно отключать независимо.174175### Вспомогательные события176177Вспомогательные события можно отслеживать, как и другие, но они управляются другим событием:178179- [`C_RAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-C_RAISE)180- [`C_RETURN`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-C_RETURN)181182События [`C_RETURN`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-C_RETURN) и [`C_RAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-C_RAISE) управляются событием [`CALL`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-CALL). События `C_RETURN` и `C_RAISE` будут видны только при отслеживании соответствующего события `CALL`.183184### Прочие события185186Другие события не обязательно привязаны к конкретному месту в программе и не могут быть отключены индивидуально для каждого места.187188Прочие события, которые можно отслеживать:189190- [`PY_THROW`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_THROW)191- [`PY_UNWIND`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_UNWIND)192- [`RAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-RAISE)193- [`EXCEPTION_HANDLED`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-EXCEPTION_HANDLED)194- [`RERAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-RERAISE)195196Изменено в версии 3.15: Другие события теперь можно включать и отключать для каждого объекта кода отдельно. Возврат [`DISABLE`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.DISABLE) из колбэка отключает событие для всего объекта кода (для текущего инструмента).197198### Событие STOP\_ITERATION199200[**PEP 380**](https://python-all.ru/3.15/library/sys.monitoring.html) указывает, что при возврате значения из генератора или корутины возбуждается исключение [`StopIteration`](https://python-all.ru/3.15/library/exceptions.html#StopIteration). Однако это очень неэффективный способ возврата значения, поэтому некоторые реализации Python, в частности CPython 3.12+, не возбуждают исключение, если оно не будет видно другому коду.201202Чтобы инструменты могли отслеживать реальные исключения без замедления генераторов и корутин, предусмотрено событие [`STOP_ITERATION`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-STOP_ITERATION). `STOP_ITERATION` может быть локально отключено.203204Обратите внимание, что событие [`STOP_ITERATION`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-STOP_ITERATION) и событие [`RAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-RAISE) для исключения [`StopIteration`](https://python-all.ru/3.15/library/exceptions.html#StopIteration) эквивалентны и при генерации событий считаются взаимозаменяемыми. Реализации будут отдавать предпочтение `STOP_ITERATION` по соображениям производительности, но могут генерировать событие `RAISE` с `StopIteration`.205206## Включение и отключение событий207208Чтобы отслеживать событие, его необходимо включить и зарегистрировать соответствующий колбэк. События можно включать и отключать, задавая их глобально и/или для конкретного объекта кода. Событие сработает только один раз, даже если оно включено и глобально, и локально.209210### Глобальная настройка событий211212События можно контролировать глобально, изменяя набор отслеживаемых событий.213214#### `sys.monitoring.get_events(tool_id: int, /) → int`215216Возвращает `int`, представляющую все активные события.217218#### `sys.monitoring.set_events(tool_id: int, event_set: int, /) → None`219220Активирует все события, установленные в *event\_set*. Возбуждает [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError), если *tool\_id* не используется.221222По умолчанию ни одно событие не активно.223224### События для каждого объекта кода225226События также можно контролировать для каждого объекта кода. Функции, определённые ниже и принимающие [`types.CodeType`](https://python-all.ru/3.15/library/types.html#types.CodeType), должны быть готовы принять объект-имитацию от функций, не определённых на Python (см. [Monitoring C API](https://python-all.ru/3.15/c-api/monitoring.html#c-api-monitoring)).227228#### `sys.monitoring.get_local_events(tool_id: int, code: CodeType, /) → int`229230Возвращает все [локальные события](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-local) для *code*231232#### `sys.monitoring.set_local_events(tool_id: int, code: CodeType, event_set: int, /) → None`233234Активирует все [локальные события](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-local) для *code*, установленные в *event\_set*. Возбуждает [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError), если *tool\_id* не используется.235236### Отключение событий237238#### `sys.monitoring.DISABLE`239240Специальное значение, которое можно вернуть из функции обратного вызова, чтобы отключить события для текущего местоположения в коде.241242[Локальные события](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-local) можно отключить для конкретного места в коде, вернув [`sys.monitoring.DISABLE`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.DISABLE) из функции обратного вызова. Это не меняет, какие события установлены, и не затрагивает другие места в коде для того же события.243244[Другие события](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-global) можно отключить для каждого объекта кода отдельно, возвращая [`sys.monitoring.DISABLE`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.DISABLE) из функции колбэка. Это отключает событие для всего объекта кода (для текущего инструмента).245246Отключение событий для конкретных местоположений очень важно для высокопроизводительного мониторинга. Например, программа может выполняться под отладчиком без накладных расходов, если отладчик отключает весь мониторинг, кроме нескольких точек останова.247248#### `sys.monitoring.restart_events() → None`249250Включить все события, которые были отключены вызовом [`sys.monitoring.DISABLE`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.DISABLE) для всех инструментов.251252## Регистрация функций обратного вызова253254#### `sys.monitoring.register_callback(tool_id: int, event: int, func: Callable | None, /) → Callable | None`255256Регистрирует вызываемый объект *func* для события *event* с заданным *tool\_id*257258Если для заданных *tool\_id* и *event* был зарегистрирован другой обратный вызов, он отменяется и возвращается. В противном случае `register_callback()` возвращает `None`.259260Вызывает [событие аудита](https://python-all.ru/3.15/library/sys.html#auditing) `sys.monitoring.register_callback` с аргументом `func`.261262Функции можно отменить, вызвав `sys.monitoring.register_callback(tool_id, event, None)`.263264Функции обратного вызова можно регистрировать и отменять в любое время.265266Обратные вызовы вызываются только один раз, независимо от того, включено ли событие глобально и локально. Таким образом, если событие может быть включено как для глобальных, так и для локальных событий вашим кодом, то обратный вызов должен быть написан так, чтобы обрабатывать любой из этих случаев.267268### Аргументы функции обратного вызова269270#### `sys.monitoring.MISSING`271272Специальное значение, которое передаётся функции обратного вызова, чтобы указать, что у вызова нет аргументов.273274Когда происходит активное событие, вызывается зарегистрированная функция обратного вызова. Функции обратного вызова, возвращающие объект, отличный от [`DISABLE`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.DISABLE), не будут иметь эффекта. Разные события передают функции обратного вызова разные аргументы, как показано ниже:275276- [`PY_START`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_START) и [`PY_RESUME`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_RESUME):277278 ```python279 func(code: CodeType, instruction_offset: int) -> object280 ```281- [`PY_RETURN`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_RETURN) и [`PY_YIELD`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_YIELD):282283 ```python284 func(code: CodeType, instruction_offset: int, retval: object) -> object285 ```286- [`CALL`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-CALL), [`C_RAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-C_RAISE) и [`C_RETURN`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-C_RETURN) (*arg0* может быть именно [`MISSING`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.MISSING)):287288 ```python289 func(code: CodeType, instruction_offset: int, callable: object, arg0: object) -> object290 ```291292 *code* представляет объект кода, в котором производится вызов, а *callable* – объект, который будет вызван (и тем самым вызвал событие). Если аргументов нет, *arg0* устанавливается в [`sys.monitoring.MISSING`](https://python-all.ru/3.15/library/sys.monitoring.html#sys.monitoring.MISSING).293294 Для методов экземпляра *callable* будет объектом функции, найденным в классе, а *arg0* устанавливается в экземпляр (т.е. аргумент `self` метода).295- [`RAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-RAISE), [`RERAISE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-RERAISE), [`EXCEPTION_HANDLED`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-EXCEPTION_HANDLED), [`PY_UNWIND`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_UNWIND), [`PY_THROW`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-PY_THROW) и [`STOP_ITERATION`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-STOP_ITERATION):296297 ```python298 func(code: CodeType, instruction_offset: int, exception: BaseException) -> object299 ```300- [`LINE`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-LINE):301302 ```python303 func(code: CodeType, line_number: int) -> object304 ```305- [`BRANCH_LEFT`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-BRANCH_LEFT), [`BRANCH_RIGHT`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-BRANCH_RIGHT) и [`JUMP`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-JUMP):306307 ```python308 func(code: CodeType, instruction_offset: int, destination_offset: int) -> object309 ```310311 Обратите внимание, что *destination\_offset* – это место, где код будет выполняться далее.312- [`INSTRUCTION`](https://python-all.ru/3.15/library/sys.monitoring.html#monitoring-event-INSTRUCTION):313314 ```python315 func(code: CodeType, instruction_offset: int) -> object316 ```317