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 -
Возврат значения 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.
По умолчанию активных событий нет.
События для отдельных объектов кода
Событиями также можно управлять отдельно для каждого объекта кода.
-
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(tool_id, event, None).
Функции обратного вызова можно регистрировать и удалять в любое время.
Регистрация или отмена регистрации функции обратного вызова генерирует событие sys.audit().
Аргументы функций обратного вызова
-
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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/sys.monitoring.html