Spec-Zone.ru › Python 3.12

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

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

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

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

  • PY_START
  • PY_RESUME
  • PY_RETURN
  • PY_YIELD
  • CALL
  • LINE
  • INSTRUCTION
  • JUMP
  • BRANCH
  • STOP_ITERATION

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

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

  • C_RAISE
  • C_RETURN

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

Другие события

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

Можно отслеживать следующие другие события:

  • PY_THROW
  • PY_UNWIND
  • RAISE
  • EXCEPTION_HANDLED

Событие 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

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

При возникновении активного события вызывается зарегистрированная функция обратного вызова. Разные события передают функции обратного вызова разные аргументы:

  • 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
    

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/sys.monitoring.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API