Документация Python неофициальный перевод
Содержание страницы

sys.monitoring – Мониторинг событий выполненияsys.monitoring – Execution event monitoring

Добавлено в версии 3.12.


Примечание

sys.monitoring – это пространство имён в модуле sys, не независимый модуль, и попытка import sys.monitoring приведёт к ошибке ModuleNotFoundError. Вместо этого достаточно import sys и затем использовать sys.monitoring.

Это пространство имён предоставляет доступ к функциям и константам, необходимым для активации и управления мониторингом событий.

В процессе выполнения программ возникают события, которые могут представлять интерес для инструментов, отслеживающих выполнение. Пространство имён sys.monitoring предоставляет средства для получения колбэков при возникновении интересующих событий.

API мониторинга состоит из трёх компонентов:

Идентификаторы инструментовTool identifiers

Идентификатор инструмента – это целое число и связанное с ним имя. Идентификаторы инструментов используются для предотвращения взаимного вмешательства инструментов и для возможности одновременной работы нескольких инструментов. В настоящее время инструменты полностью независимы и не могут использоваться для мониторинга друг друга. В будущем это ограничение может быть снято.

Перед регистрацией или активацией событий инструмент должен выбрать идентификатор. Идентификаторы – целые числа в диапазоне от 0 до 5 включительно.

Регистрация и использование инструментовRegistering and using tools

sys.monitoring.use_tool_id(tool_id: int, name: str, /) None

Должен быть вызван до того, как tool_id можно будет использовать. tool_id должен находиться в диапазоне от 0 до 5 включительно. Вызывает исключение ValueError, если tool_id уже используется.

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

СобытияEvents

Поддерживаются следующие события:

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 (происходит непосредственно перед yield, фрейм вызываемой функции будет находиться в стеке).

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:
    ...

События разделены на три группы:

Локальные событияLocal events

Локальные события связаны с обычным выполнением программы и происходят в четко определенных местах. Все локальные события можно отключить. Локальные события:

Вспомогательные событияAncillary events

Вспомогательные события можно отслеживать, как и другие, но они управляются другим событием:

События C_RETURN и C_RAISE управляются событием CALL. События C_RETURN и C_RAISE будут видны только при отслеживании соответствующего события CALL.

Прочие событияOther events

Прочие события не обязательно привязаны к конкретному месту в программе и не могут быть отключены по отдельности через DISABLE.

Прочие события, которые можно отслеживать:

Событие STOP_ITERATIONThe STOP_ITERATION event

PEP 380 указывает, что при возврате значения из генератора или корутины возбуждается исключение StopIteration. Однако это очень неэффективный способ возврата значения, поэтому некоторые реализации Python, в частности CPython 3.12+, не возбуждают исключение, если оно не будет видно другому коду.

Чтобы инструменты могли отслеживать реальные исключения, не замедляя работу генераторов и корутин, предоставляется событие STOP_ITERATION. STOP_ITERATION можно отключать локально, в отличие от RAISE.

Включение и отключение событийTurning events on and off

Чтобы отслеживать событие, его необходимо включить и зарегистрировать соответствующий колбэк. События можно включать или отключать, задавая их глобально или для конкретного объекта кода.

Глобальная настройка событийSetting events globally

События можно контролировать глобально, изменяя набор отслеживаемых событий.

sys.monitoring.get_events(tool_id: int, /) int

Возвращает int, представляющую все активные события.

sys.monitoring.set_events(tool_id: int, event_set: int, /) None

Активирует все события, установленные в event_set. Возбуждает ValueError, если tool_id не используется.

По умолчанию ни одно событие не активно.

События для каждого объекта кодаPer code object events

События также можно контролировать для каждого объекта кода. Функции, определённые ниже и принимающие types.CodeType, должны быть готовы принять объект-имитацию от функций, не определённых на Python (см. Monitoring C API).

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. Возбуждает ValueError, если tool_id не используется.

Локальные события добавляются к глобальным, но не скрывают их. Иными словами, все глобальные события срабатывают для объекта кода независимо от локальных событий.

Отключение событийDisabling events

sys.monitoring.DISABLE

Специальное значение, которое можно вернуть из функции обратного вызова, чтобы отключить события для текущего местоположения в коде.

Локальные события можно отключить для конкретного места в коде, вернув sys.monitoring.DISABLE из функции обратного вызова. Это не меняет, какие события установлены, и не затрагивает другие места в коде для того же события.

Отключение событий для конкретных мест очень важно для высокопроизводительного мониторинга. Например, программу можно запускать под отладчиком без накладных расходов, если отладчик отключает весь мониторинг, кроме нескольких точек останова.

Если DISABLE возвращается функцией обратного вызова для глобального события, то ValueError будет возбуждено интерпретатором в неопределённом месте (то есть traceback не будет предоставлен).

sys.monitoring.restart_events() None

Включить все события, которые были отключены вызовом sys.monitoring.DISABLE для всех инструментов.

Регистрация функций обратного вызоваRegistering callback functions

Чтобы зарегистрировать вызываемый объект для событий, вызовите

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).

Функции обратного вызова можно регистрировать и отменять в любое время.

Аргументы функции обратного вызоваCallback function arguments

sys.monitoring.MISSING

Специальное значение, которое передаётся функции обратного вызова, чтобы указать, что у вызова нет аргументов.

Когда происходит активное событие, вызывается зарегистрированный колбэк. Разные события передают колбэку различные аргументы, как показано ниже:

  • PY_START и PY_RESUME:

    func(code: CodeType, instruction_offset: int) -> DISABLE | Any
    
  • PY_RETURN и PY_YIELD:

    func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any
    
  • CALL, C_RAISE и C_RETURN:

    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
    
  • BRANCH и JUMP:

    func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any
    

    Обратите внимание, что destination_offset – это смещение, по которому код будет выполняться далее. Для невыбранной ветки это будет смещение инструкции, следующей за веткой.

  • INSTRUCTION:

    func(code: CodeType, instruction_offset: int) -> DISABLE | Any