sys.monitoring — Мониторинг событий выполнения
Добавлено в версии 3.12.
Примечание
sys.monitoring — это пространство имён внутри модуля sys, а не независимый модуль, поэтому нет необходимости import sys.monitoring: просто import sys, а затем используйте sys.monitoring.
Это пространство имён предоставляет доступ к функциям и константам, необходимым для включения мониторинга событий и управления им.
Во время выполнения программ возникают события, которые могут представлять интерес для инструментов мониторинга выполнения. Пространство имён sys.monitoring предоставляет средства для получения обратных вызовов при возникновении интересующих событий.
API мониторинга состоит из трёх компонентов:
Идентификаторы инструментов
Идентификатор инструмента — это целое число и связанное с ним имя. Идентификаторы инструментов используются, чтобы не допустить взаимных помех между инструментами и позволить нескольким инструментам работать одновременно. Сейчас инструменты полностью независимы и не могут использоваться для мониторинга друг друга. В будущем это ограничение может быть снято.
Прежде чем регистрировать или активировать события, инструменту следует выбрать идентификатор. Идентификаторы — это целые числа от 0 до 5 включительно.
Регистрация и использование инструментов
-
sys.monitoring.use_tool_id(tool_id: int, name: str, /) → None -
Эту функцию необходимо вызвать, прежде чем использовать tool_id. Значение tool_id должно находиться в диапазоне от 0 до 5 включительно. Если tool_id уже используется, возбуждается исключение
ValueError.
-
sys.monitoring.free_tool_id(tool_id: int, /) → None -
Следует вызвать, когда инструменту больше не требуется tool_id.
Примечание
free_tool_id() не отключит глобальные или локальные события, связанные с tool_id, и не отменит регистрацию каких-либо функций обратного вызова. Эта функция предназначена только для уведомления виртуальной машины о том, что конкретный tool_id больше не используется.
-
sys.monitoring.get_tool(tool_id: int, /) → str | None -
Возвращает имя инструмента, если tool_id используется; в противном случае возвращает
None. Значение tool_id должно находиться в диапазоне от 0 до 5 включительно.
С точки зрения обработки событий виртуальная машина относится ко всем идентификаторам одинаково, однако следующие идентификаторы предопределены, чтобы упростить взаимодействие инструментов:
sys.monitoring.DEBUGGER_ID = 0 sys.monitoring.COVERAGE_ID = 1 sys.monitoring.PROFILER_ID = 2 sys.monitoring.OPTIMIZER_ID = 5
События
Поддерживаются следующие события:
-
sys.monitoring.events.BRANCH -
Условный переход выполнен (или не выполнен).
-
sys.monitoring.events.CALL -
Вызов в коде Python (событие возникает до вызова).
-
sys.monitoring.events.C_RAISE -
Исключение, возбуждённое любым вызываемым объектом, кроме функций Python (событие возникает после выхода).
-
sys.monitoring.events.C_RETURN -
Возврат из любого вызываемого объекта, кроме функций Python (событие возникает после возврата).
-
sys.monitoring.events.EXCEPTION_HANDLED -
Исключение обработано.
-
sys.monitoring.events.INSTRUCTION -
Скоро будет выполнена инструкция виртуальной машины.
-
sys.monitoring.events.JUMP -
В графе потока управления выполнен безусловный переход.
-
sys.monitoring.events.LINE -
Скоро будет выполнена инструкция, номер строки которой отличается от номера строки предыдущей инструкции.
-
sys.monitoring.events.PY_RESUME -
Возобновление функции Python (для функций-генераторов и функций-корутин), кроме вызовов
throw().
-
sys.monitoring.events.PY_RETURN -
Возврат из функции Python (событие возникает непосредственно перед возвратом; кадр вызываемой функции находится в стеке).
-
sys.monitoring.events.PY_START -
Начало выполнения функции Python (событие возникает непосредственно после вызова; кадр вызываемой функции находится в стеке)
-
sys.monitoring.events.PY_THROW -
Функция Python возобновляется вызовом
throw().
-
sys.monitoring.events.PY_UNWIND -
Выход из функции Python во время раскрутки стека исключения.
-
sys.monitoring.events.PY_YIELD -
Передача значения из функции Python (событие возникает непосредственно перед передачей; кадр вызываемой функции находится в стеке).
-
sys.monitoring.events.RAISE -
Возбуждено исключение, кроме исключений, вызывающих событие
STOP_ITERATION.
-
sys.monitoring.events.RERAISE -
Исключение возбуждено повторно, например в конце блока
finally.
-
sys.monitoring.events.STOP_ITERATION -
Возбуждено искусственное исключение
StopIteration; см. событие STOP_ITERATION.
В будущем могут быть добавлены другие события.
Эти события являются атрибутами пространства имён sys.monitoring.events. Каждое событие представлено целой константой, равной степени двойки. Чтобы задать набор событий, достаточно объединить отдельные события побитовой операцией ИЛИ. Например, чтобы указать события PY_RETURN и PY_START, используйте выражение PY_RETURN | PY_START.
-
sys.monitoring.events.NO_EVENTS -
Псевдоним для
0, позволяющий явно сравнивать значения, например:if get_events(DEBUGGER_ID) == NO_EVENTS: ...
События делятся на три группы:
Локальные события
Локальные события связаны с обычным выполнением программы и возникают в чётко определённых местах. Все локальные события можно отключить. К локальным событиям относятся:
Вспомогательные события
Вспомогательные события можно отслеживать так же, как и другие события, но управляются они другим событием:
События C_RETURN и C_RAISE управляются событием CALL. События C_RETURN и C_RAISE будут наблюдаться только в том случае, если отслеживается соответствующее событие CALL.
Другие события
Другие события не обязательно связаны с конкретным местом в программе, и их нельзя отключить по отдельности.
Можно отслеживать следующие другие события:
Событие STOP_ITERATION
PEP 380 указывает, что при возврате значения из генератора или корутины возбуждается исключение StopIteration. Однако это крайне неэффективный способ возврата значения, поэтому некоторые реализации Python, в частности CPython 3.12+, не возбуждают исключение, если оно не будет видно другому коду.
Чтобы инструменты могли отслеживать реальные исключения, не замедляя генераторы и корутины, предусмотрено событие STOP_ITERATION. Событие STOP_ITERATION можно отключить локально, в отличие от события RAISE.
Включение и отключение событий
Чтобы отслеживать событие, его необходимо включить и зарегистрировать соответствующий обратный вызов. События можно включать и отключать глобально или для конкретного объекта кода.
Глобальная настройка событий
Событиями можно управлять глобально, изменяя набор отслеживаемых событий.
-
sys.monitoring.get_events(tool_id: int, /) → int -
Возвращает
int, представляющий все активные события.
-
sys.monitoring.set_events(tool_id: int, event_set: int, /) → None -
Активирует все события, включённые в event_set. Если tool_id не используется, возбуждается исключение
ValueError.
По умолчанию события не активны.
События для отдельных объектов кода
Событиями также можно управлять отдельно для каждого объекта кода. Функции, определённые ниже и принимающие types.CodeType, должны быть готовы принимать объект, похожий на него, от функций, определённых не на Python (см. API мониторинга C).
-
sys.monitoring.get_local_events(tool_id: int, code: CodeType, /) → int -
Возвращает все локальные события для code
-
sys.monitoring.set_local_events(tool_id: int, code: CodeType, event_set: int, /) → None -
Активирует для code все локальные события, включённые в event_set. Если tool_id не используется, возбуждается исключение
ValueError.
Локальные события дополняют глобальные, но не маскируют их. Иными словами, все глобальные события будут срабатывать для объекта кода независимо от локальных событий.
Отключение событий
-
sys.monitoring.DISABLE -
Специальное значение, которое функция обратного вызова может вернуть, чтобы отключить события для текущей позиции в коде.
Локальные события для конкретной позиции в коде можно отключить, вернув из функции обратного вызова sys.monitoring.DISABLE. Это не меняет набор включённых событий и не влияет на другие позиции кода для того же события.
Отключение событий для отдельных позиций крайне важно для высокопроизводительного мониторинга. Например, программу можно запускать под отладчиком без дополнительных затрат, если отладчик отключит весь мониторинг, кроме нескольких точек останова.
-
sys.monitoring.restart_events() → None -
Включает все события, отключённые с помощью
sys.monitoring.DISABLE, для всех инструментов.
Регистрация функций обратного вызова
Чтобы зарегистрировать вызываемый объект для событий, вызовите
-
sys.monitoring.register_callback(tool_id: int, event: int, func: Callable | None, /) → Callable | None -
Регистрирует вызываемый объект func для события event с указанным tool_id
Если для указанного tool_id и события event уже зарегистрирован другой обратный вызов, его регистрация отменяется, и он возвращается. В противном случае
register_callback()возвращаетNone.Возбуждает событие аудита
sys.monitoring.register_callbackс аргументомfunc.
Регистрацию функций можно отменить вызовом sys.monitoring.register_callback(tool_id, event, None).
Функции обратного вызова можно регистрировать и отменять в любой момент.
Аргументы функций обратного вызова
-
sys.monitoring.MISSING -
Специальное значение, передаваемое функции обратного вызова, чтобы указать, что у вызова нет аргументов.
При возникновении активного события вызывается зарегистрированная функция обратного вызова. Для разных событий функции обратного вызова передаются разные аргументы:
-
func(code: CodeType, instruction_offset: int) -> DISABLE | Any
-
func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any
-
func(code: CodeType, instruction_offset: int, callable: object, arg0: object | MISSING) -> DISABLE | Any
Если аргументов нет, для arg0 устанавливается значение
sys.monitoring.MISSING. -
RAISE,RERAISE,EXCEPTION_HANDLED,PY_UNWIND,PY_THROWиSTOP_ITERATION:func(code: CodeType, instruction_offset: int, exception: BaseException) -> DISABLE | Any
-
LINE:func(code: CodeType, line_number: int) -> DISABLE | Any
-
func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any
Обратите внимание: destination_offset — это позиция, с которой будет продолжено выполнение кода. Для невыполненного условного перехода это позиция инструкции, следующей за переходом.
-
func(code: CodeType, instruction_offset: int) -> DISABLE | Any
© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/sys.monitoring.html