Nota
¡Ayúdanos a traducir la documentación oficial de Python al Español! Puedes encontrar más información en Como contribuir. Ayuda a acercar Python a más personas de habla hispana.
sys.monitoring
— Monitoreo de eventos de ejecución¶
Nota
sys.monitoring
es un espacio de nombres dentro del módulo sys
, no un módulo independiente, así que no hay necesidad de usar import sys.monitoring
, simplemente use import sys
y luego sys.monitoring
.
Este espacio de nombres proporciona acceso a las funciones y constantes necesarias para activar y controlar el monitoreo de eventos.
A medida que se ejecutan los programas, ocurren eventos que podrían ser de interés para las herramientas que monitorean la ejecución. El espacio de nombres sys.monitoring
proporciona medios para recibir retrollamadas cuando ocurren eventos de interés.
La API de monitoreo consta de tres componentes:
Identificadores de herramientas
Eventos
Retrollamadas
Identificadores de herramientas¶
Un identificador de herramienta es un número entero y un nombre asociado. Los identificadores de herramientas se utilizan para evitar que las herramientas interfieran entre sí y para permitir que varias herramientas funcionen al mismo tiempo. Actualmente las herramientas son completamente independientes y no se pueden utilizar para monitorearse entre sí. Esta restricción podría eliminarse en el futuro.
Antes de registrar o activar eventos, una herramienta debe elegir un identificador. Los identificadores son números enteros en el rango de 0 a 5.
Registro y uso de herramientas¶
- sys.monitoring.use_tool_id(id: int, name: str) None ¶
Debe llamarse antes de poder utilizar
id
.id
debe estar inclusive en el rango de 0 a 5. Lanza unValueError
siid
está en uso.
- sys.monitoring.free_tool_id(id: int) None ¶
Se debe llamar una vez que una herramienta ya no requiera
id
.
- sys.monitoring.get_tool(id: int) str | None ¶
Retorna el nombre de la herramienta si
id
está en uso; de lo contrario, devuelveNone
.id
debe estar dentro del rango de 0 a 5.
La máquina virtual trata todos los ID de la misma manera con respecto a los eventos, pero los siguientes ID están predefinidos para facilitar la cooperación de las herramientas:
sys.monitoring.DEBUGGER_ID = 0
sys.monitoring.COVERAGE_ID = 1
sys.monitoring.PROFILER_ID = 2
sys.monitoring.OPTIMIZER_ID = 5
No hay obligación de establecer un ID, ni hay nada que impida que una herramienta use un ID, incluso si ya está en uso. Sin embargo, se recomienda que las herramientas utilicen un identificación única y respeten otras herramientas.
Eventos¶
Son aceptados los siguientes eventos:
- BRANCH
Una rama condicional es aceptada (o no).
- CALL
Una llamada en código Python (el evento ocurre antes de la llamada).
- C_RAISE
Excepción generada por cualquier función invocable, excepto las funciones Python (el evento ocurre después de la salida).
- C_RETURN
Retorno de cualquier función invocable, excepto las funciones Python (el evento ocurre después del retorno).
- EXCEPTION_HANDLED
Se maneja una excepción.
- INSTRUCTION
Está a punto de ejecutarse una instrucción de VM.
- JUMP
Se realiza un salto incondicional en el gráfico de flujo de control.
- LINE
Está a punto de ejecutarse una instrucción que tiene un número de línea diferente al de la instrucción anterior.
- PY_RESUME
Reanudación de una función Python (para funciones generadoras y de corutina), excepto para llamadas throw().
- PY_RETURN
Retorna de una función Python (ocurre inmediatamente antes del retorno, el marco del destinatario estará en la pila).
- PY_START
Inicio de una función Python (ocurre inmediatamente después de la llamada, el marco del destinatario estará en la pila)
- PY_THROW
Una función Python se reanuda mediante una llamada throw().
- PY_UNWIND
Salida de una función Python durante la resolución de excepciones.
- PY_YIELD
Rinde (yield) desde una función Python (ocurre inmediatamente antes del rendimiento, el marco del destinatario estará en la pila).
- RAISE
Se lanza una excepción, excepto aquellas que causan un evento
STOP_ITERATION
.- RERAISE
Se vuelve a lanzar una excepción, por ejemplo, al final de un bloque
finally
.- STOP_ITERATION
Se genera un
StopIteration
artificial; ver el evento STOP_ITERATION.
Es posible que se agreguen más eventos en el futuro.
Estos eventos son atributos del espacio de nombres sys.monitoring.events
. Cada evento se representa como una constante entera de potencia de 2. Para definir un conjunto de eventos, simplemente combine los eventos individuales bit a bit con OR. Por ejemplo, para especificar eventos PY_RETURN
y PY_START
, use la expresión PY_RETURN | PY_START
.
Los eventos se dividen en tres grupos:
Eventos locales¶
Los eventos locales están asociados con la ejecución normal del programa y ocurren en lugares claramente definidos. Todos los eventos locales se pueden desactivar. Los eventos locales son:
PY_START
PY_RESUME
PY_RETURN
PY_YIELD
CALL
LINE
INSTRUCTION
JUMP
BRANCH
STOP_ITERATION
Eventos auxiliares¶
Los eventos auxiliares se pueden monitorear como otros eventos, pero están controlados por otros eventos:
C_RAISE
C_RETURN
El C_RETURN
y C_RAISE
son eventos controlados por el evento CALL
. Los eventos C_RETURN
y C_RAISE
serán vistos si el evento correspondiente CALL
está siendo monitoreado.
Otros eventos¶
Otros eventos no están necesariamente vinculados a una ubicación específica del programa y no se pueden desactivar individualmente.
Los otros eventos que se pueden monitorear son:
PY_THROW
PY_UNWIND
RAISE
EXCEPTION_HANDLED
El evento STOP_ITERATION¶
PEP 380 especifica que se lanza una excepción StopIteration
al retornar un valor de un generador o corutina. Sin embargo, esta es una forma muy ineficiente de devolver un valor, por lo que algunas implementaciones de Python, en particular CPython 3.12+, no lanzan una excepción a menos que sea visible para otro código.
Para permitir que las herramientas monitoreen excepciones reales sin ralentizar los generadores y las corrutinas, se proporciona el evento STOP_ITERATION
. STOP_ITERATION
se puede desactivar localmente, a diferencia de RAISE
.
Activar y desactivar eventos¶
Para monitorear un evento, se debe activar y registrar una retrollamada. Los eventos se pueden activar o desactivar configurándolos globalmente o para un objeto de código en particular.
Configuración de eventos globalmente¶
Los eventos se pueden controlar globalmente modificando el conjunto de eventos que están siendo monitoreados.
- sys.monitoring.get_events(tool_id: int) int ¶
Retorna el
int
que representa todos los eventos activos.
- sys.monitoring.set_events(tool_id: int, event_set: int)¶
Activa todos los eventos que están configurados en
event_set
. Lanza unValueError
sitool_id
no está en uso.
No hay eventos activos de forma predeterminada.
Eventos por objeto de código¶
Los eventos también se pueden controlar por objeto de código.
- sys.monitoring.get_local_events(tool_id: int, code: CodeType) int ¶
Retorna todos los eventos locales de
code
- sys.monitoring.set_local_events(tool_id: int, code: CodeType, event_set: int)¶
Activa todos los eventos locales para
code
que están configurados enevent_set
. Lanza unValueError
sitool_id
no está en uso.
Los eventos locales se suman a los eventos globales, pero no los enmascaran. En otras palabras, todos los eventos globales se activarán para un objeto de código, independientemente de los eventos locales.
Deshabilitando eventos¶
Los eventos locales se pueden deshabilitar para una ubicación de código específica retornando sys.monitoring.DISABLE
desde una función de retrollamada. Esto no cambia cuales eventos se configuran ni ninguna otra ubicación de código para el mismo evento.
Deshabilitar eventos para ubicaciones específicas es muy importante para el monitoreo de alto rendimiento. Por ejemplo, un programa se puede ejecutar con un depurador sin gastos adicionales si el depurador desactiva toda la supervisión excepto algunos puntos de interrupción.
Registrando funciones de retrollamada¶
Para registrar un invocable para eventos llame
- sys.monitoring.register_callback(tool_id: int, event: int, func: Callable | None) Callable | None ¶
Registra el invocable
func
para elevent
con eltool_id
proporcionadoSi se registró otra retrollamada por los
tool_id
yevent
proporcionados, ésta se cancela y se retorna. De lo contrarioregister_callback
retornaNone
.
Funciones pueden ser canceladas llamando sys.monitoring.register_callback(tool_id, event, None)
.
Las funciones de retrollamada se pueden registrar y cancelar en cualquier momento.
Registrar o cancelar el registro de una función de retrollamada generará un evento sys.audit
.
Argumentos de la función de retrollamada¶
Cuando ocurre un evento activo, se llama a la función de retrollamada registrada. Diferentes eventos proporcionarán a la función de retrollamada con diferentes argumentos, de la siguiente manera:
PY_START
yPY_RESUME
:func(code: CodeType, instruction_offset: int) -> DISABLE | Any
PY_RETURN
yPY_YIELD
:func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any
CALL
,C_RAISE
yC_RETURN
:func(code: CodeType, instruction_offset: int, callable: object, arg0: object | MISSING) -> DISABLE | Any
Si no hay argumentos,
arg0
se establece comoMISSING
.RAISE
,RERAISE
,EXCEPTION_HANDLED
,PY_UNWIND
,PY_THROW
ySTOP_ITERATION
:func(code: CodeType, instruction_offset: int, exception: BaseException) -> DISABLE | Any
LINE
:func(code: CodeType, line_number: int) -> DISABLE | Any
BRANCH
yJUMP
:func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any
Tenga en cuenta que
destination_offset
es donde el siguiente código se ejecutará. Para una rama no tomada, este será el desplazamiento de la instrucción que sigue la rama.INSTRUCTION
:func(code: CodeType, instruction_offset: int) -> DISABLE | Any