sys.monitoring — Überwachung von Ausführungsereignissen¶
Hinzugefügt in Version 3.12.
Hinweis
sys.monitoring ist ein Namensraum innerhalb des sys Moduls, kein eigenständiges Modul, daher ist es nicht notwendig, import sys.monitoring zu verwenden. Importieren Sie einfach import sys und verwenden Sie dann sys.monitoring.
Dieser Namensraum bietet Zugriff auf die Funktionen und Konstanten, die zur Aktivierung und Steuerung der Ereignisüberwachung erforderlich sind.
Während Programme ausgeführt werden, treten Ereignisse auf, die für Tools zur Überwachung der Ausführung von Interesse sein können. Der Namensraum sys.monitoring bietet Mittel, um Rückruffunktionen zu erhalten, wenn interessante Ereignisse auftreten.
Die Überwachungs-API besteht aus drei Komponenten
Tool-Bezeichner¶
Ein Tool-Bezeichner ist eine Ganzzahl und der zugehörige Name. Tool-Bezeichner werden verwendet, um zu verhindern, dass Tools sich gegenseitig stören, und um mehreren Tools die gleichzeitige Ausführung zu ermöglichen. Derzeit sind Tools vollständig unabhängig und können nicht dazu verwendet werden, sich gegenseitig zu überwachen. Diese Einschränkung kann in Zukunft aufgehoben werden.
Bevor Ereignisse registriert oder aktiviert werden, sollte ein Tool einen Bezeichner wählen. Bezeichner sind Ganzzahlen im Bereich von 0 bis einschließlich 5.
Registrierung und Verwendung von Tools¶
- sys.monitoring.use_tool_id(tool_id: int, name: str, /) None¶
Muss aufgerufen werden, bevor tool_id verwendet werden kann. tool_id muss im Bereich von 0 bis einschließlich 5 liegen. Löst einen
ValueErroraus, wenn tool_id bereits verwendet wird.
- sys.monitoring.clear_tool_id(tool_id: int, /) None¶
Registriert alle Ereignisse und Rückruffunktionen ab, die mit tool_id verknüpft sind.
- sys.monitoring.free_tool_id(tool_id: int, /) None¶
Sollte aufgerufen werden, wenn ein Tool tool_id nicht mehr benötigt. Ruft
clear_tool_id()auf, bevor tool_id freigegeben wird.
- sys.monitoring.get_tool(tool_id: int, /) str | None¶
Gibt den Namen des Tools zurück, wenn tool_id verwendet wird, andernfalls gibt sie
Nonezurück. tool_id muss im Bereich von 0 bis einschließlich 5 liegen.
Alle IDs werden von der VM in Bezug auf Ereignisse gleich behandelt, aber die folgenden IDs sind vordefiniert, um die Zusammenarbeit von Tools zu erleichtern
sys.monitoring.DEBUGGER_ID = 0
sys.monitoring.COVERAGE_ID = 1
sys.monitoring.PROFILER_ID = 2
sys.monitoring.OPTIMIZER_ID = 5
Ereignisse¶
Die folgenden Ereignisse werden unterstützt
- sys.monitoring.events.BRANCH_LEFT¶
Ein bedingter Sprung geht nach links.
Es liegt am Tool zu entscheiden, wie "linke" und "rechte" Zweige dargestellt werden. Es gibt keine Garantie, welcher Zweig "links" und welcher "rechts" ist, außer dass dies für die Dauer des Programms konsistent sein wird.
- sys.monitoring.events.BRANCH_RIGHT¶
Ein bedingter Sprung geht nach rechts.
- sys.monitoring.events.CALL¶
Ein Aufruf im Python-Code (Ereignis tritt vor dem Aufruf auf).
- sys.monitoring.events.C_RAISE¶
Eine Ausnahme, die von einer beliebigen aufrufbaren Funktion ausgelöst wird, mit Ausnahme von Python-Funktionen (Ereignis tritt nach dem Verlassen auf).
- sys.monitoring.events.C_RETURN¶
Rückkehr von einer beliebigen aufrufbaren Funktion, mit Ausnahme von Python-Funktionen (Ereignis tritt nach der Rückkehr auf).
- sys.monitoring.events.EXCEPTION_HANDLED¶
Eine Ausnahme wird behandelt.
- sys.monitoring.events.INSTRUCTION¶
Eine VM-Instruktion wird ausgeführt.
- sys.monitoring.events.JUMP¶
Ein unbedingter Sprung im Kontrollflussgraphen wird durchgeführt.
- sys.monitoring.events.LINE¶
Eine Anweisung wird ausgeführt, die eine andere Zeilennummer als die vorherige Anweisung hat.
- sys.monitoring.events.PY_RESUME¶
Wiederaufnahme einer Python-Funktion (für Generator- und Coroutine-Funktionen), außer bei
throw()Aufrufen.
- sys.monitoring.events.PY_RETURN¶
Rückkehr aus einer Python-Funktion (tritt unmittelbar vor der Rückkehr auf, der Frame des Aufgerufenen befindet sich auf dem Stapel).
- sys.monitoring.events.PY_START¶
Start einer Python-Funktion (tritt unmittelbar nach dem Aufruf auf, der Frame des Aufgerufenen befindet sich auf dem Stapel)
- sys.monitoring.events.PY_THROW¶
Eine Python-Funktion wird durch einen
throw()Aufruf wieder aufgenommen.
- sys.monitoring.events.PY_UNWIND¶
Verlassen einer Python-Funktion während des Exception-Unwindings. Dies schließt Ausnahmen ein, die direkt innerhalb der Funktion ausgelöst und weiter propagiert werden.
- sys.monitoring.events.PY_YIELD¶
Yield aus einer Python-Funktion (tritt unmittelbar vor dem Yield auf, der Frame des Aufgerufenen befindet sich auf dem Stapel).
- sys.monitoring.events.RAISE¶
Eine Ausnahme wird ausgelöst, außer solchen, die ein
STOP_ITERATIONEreignis verursachen.
- sys.monitoring.events.RERAISE¶
Eine Ausnahme wird erneut ausgelöst, z.B. am Ende eines
finallyBlocks.
- sys.monitoring.events.STOP_ITERATION¶
Eine künstliche
StopIterationwird ausgelöst; siehe das STOP_ITERATION-Ereignis.
Zukünftig können weitere Ereignisse hinzugefügt werden.
Diese Ereignisse sind Attribute des Namensraums sys.monitoring.events. Jedes Ereignis wird durch eine Zweierpotenz-Ganzzahlkonstante dargestellt. Um eine Menge von Ereignissen zu definieren, werden die einzelnen Ereignisse einfach durch bitweises OR zusammengefügt. Um beispielsweise sowohl PY_RETURN als auch PY_START Ereignisse anzugeben, verwenden Sie den Ausdruck PY_RETURN | PY_START.
- sys.monitoring.events.NO_EVENTS¶
Ein Alias für
0, damit Benutzer explizite Vergleiche wie folgt durchführen können:if get_events(DEBUGGER_ID) == NO_EVENTS: ...
Das Setzen dieses Ereignisses deaktiviert alle Ereignisse.
Lokale Ereignisse¶
Lokale Ereignisse sind mit der normalen Ausführung des Programms verbunden und treten an klar definierten Stellen auf. Alle lokalen Ereignisse können deaktiviert werden. Die lokalen Ereignisse sind:
Veraltetes Ereignis¶
BRANCH
Das Ereignis BRANCH ist in 3.14 veraltet. Die Verwendung von BRANCH_LEFT und BRANCH_RIGHT Ereignissen bietet eine deutlich bessere Leistung, da sie unabhängig voneinander deaktiviert werden können.
Ancillary-Ereignisse¶
Ancillary-Ereignisse können wie andere Ereignisse überwacht werden, werden aber von einem anderen Ereignis gesteuert.
Die Ereignisse C_RETURN und C_RAISE werden vom CALL Ereignis gesteuert. C_RETURN und C_RAISE Ereignisse werden nur dann ausgelöst, wenn das entsprechende CALL Ereignis überwacht wird.
Andere Ereignisse¶
Andere Ereignisse sind nicht unbedingt an eine bestimmte Stelle im Programm gebunden und können nicht einzeln deaktiviert werden.
Die anderen Ereignisse, die überwacht werden können, sind:
Das STOP_ITERATION-Ereignis¶
PEP 380 legt fest, dass eine StopIteration Ausnahme ausgelöst wird, wenn ein Wert aus einem Generator oder Coroutine zurückgegeben wird. Dies ist jedoch eine sehr ineffiziente Methode, einen Wert zurückzugeben, daher lösen einige Python-Implementierungen, insbesondere CPython 3.12+, keine Ausnahme aus, es sei denn, sie wäre für anderen Code sichtbar.
Um Tools die Überwachung echter Ausnahmen zu ermöglichen, ohne Generatoren und Coroutinen zu verlangsamen, wird das Ereignis STOP_ITERATION bereitgestellt. STOP_ITERATION kann lokal deaktiviert werden, im Gegensatz zu RAISE.
Beachten Sie, dass das Ereignis STOP_ITERATION und das Ereignis RAISE für eine StopIteration Ausnahme äquivalent sind und als austauschbar behandelt werden, wenn Ereignisse generiert werden. Implementierungen bevorzugen STOP_ITERATION aus Leistungsgründen, können aber ein RAISE Ereignis mit einer StopIteration generieren.
Ereignisse ein- und ausschalten¶
Um ein Ereignis zu überwachen, muss es aktiviert und eine entsprechende Rückruffunktion registriert werden. Ereignisse können global und/oder für ein bestimmtes Code-Objekt ein- oder ausgeschaltet werden. Ein Ereignis wird nur einmal ausgelöst, auch wenn es sowohl global als auch lokal aktiviert ist.
Ereignisse global setzen¶
Ereignisse können global gesteuert werden, indem die Menge der überwachten Ereignisse geändert wird.
- sys.monitoring.get_events(tool_id: int, /) int¶
Gibt die
intzurück, die alle aktiven Ereignisse repräsentiert.
- sys.monitoring.set_events(tool_id: int, event_set: int, /) None¶
Aktiviert alle Ereignisse, die in event_set gesetzt sind. Löst einen
ValueErroraus, wenn tool_id nicht verwendet wird.
Standardmäßig sind keine Ereignisse aktiv.
Ereignisse pro Code-Objekt¶
Ereignisse können auch pro Code-Objekt gesteuert werden. Die unten definierten Funktionen, die einen types.CodeType akzeptieren, sollten darauf vorbereitet sein, ein ähnliches Objekt von Funktionen zu akzeptieren, die nicht in Python definiert sind (siehe Monitoring C API).
Ereignisse deaktivieren¶
- sys.monitoring.DISABLE¶
Ein spezieller Wert, der von einer Rückruffunktion zurückgegeben werden kann, um Ereignisse für den aktuellen Code-Ort zu deaktivieren.
Lokale Ereignisse können für einen bestimmten Code-Ort deaktiviert werden, indem sys.monitoring.DISABLE aus einer Rückruffunktion zurückgegeben wird. Dies ändert nicht, welche Ereignisse gesetzt sind, oder andere Code-Orte für dasselbe Ereignis.
Die Deaktivierung von Ereignissen für bestimmte Orte ist für eine hochleistungsfähige Überwachung sehr wichtig. Ein Programm kann beispielsweise ohne Overhead unter einem Debugger ausgeführt werden, wenn der Debugger die gesamte Überwachung bis auf wenige Breakpoints deaktiviert.
- sys.monitoring.restart_events() None¶
Aktiviert alle Ereignisse, die von
sys.monitoring.DISABLEfür alle Tools deaktiviert wurden.
Registrierung von Rückruffunktionen¶
- sys.monitoring.register_callback(tool_id: int, event: int, func: Callable | None, /) Callable | None¶
Registriert die aufrufbare Funktion func für das event mit der gegebenen tool_id.
Wenn eine andere Rückruffunktion für die gegebene tool_id und das event registriert war, wird diese abgemeldet und zurückgegeben. Andernfalls gibt
register_callback()Nonezurück.Löst ein Audit-Ereignis
sys.monitoring.register_callbackmit dem Argumentfuncaus.
Funktionen können durch Aufruf von sys.monitoring.register_callback(tool_id, event, None) abgemeldet werden.
Rückruffunktionen können jederzeit registriert und abgemeldet werden.
Rückruffunktionen werden nur einmal aufgerufen, unabhängig davon, ob das Ereignis sowohl global als auch lokal aktiviert ist. Daher muss die Rückruffunktion so geschrieben sein, dass sie beide Auslöser verarbeiten kann.
Argumente der Rückruffunktion¶
- sys.monitoring.MISSING¶
Ein spezieller Wert, der an eine Rückruffunktion übergeben wird, um anzuzeigen, dass die Funktion keine Argumente hat.
Wenn ein aktives Ereignis auftritt, wird die registrierte Rückruffunktion aufgerufen. Rückruffunktionen, die ein anderes Objekt als DISABLE zurückgeben, haben keine Auswirkungen. Verschiedene Ereignisse übergeben der Rückruffunktion unterschiedliche Argumente, wie folgt:
-
func(code: CodeType, instruction_offset: int) -> object
-
func(code: CodeType, instruction_offset: int, retval: object) -> object
CALL,C_RAISEundC_RETURN(arg0 kann spezifischMISSINGsein)func(code: CodeType, instruction_offset: int, callable: object, arg0: object) -> object
code repräsentiert das Code-Objekt, an dem der Aufruf getätigt wird, während callable das Objekt ist, das aufgerufen werden soll (und somit das Ereignis ausgelöst hat). Wenn keine Argumente vorhanden sind, wird arg0 auf
MISSINGgesetzt.Bei Instanzmethoden ist callable das Funktions-Objekt, wie es auf der Klasse gefunden wird, mit arg0 auf die Instanz gesetzt (d.h. das
self-Argument der Methode).RAISE,RERAISE,EXCEPTION_HANDLED,PY_UNWIND,PY_THROWundSTOP_ITERATIONfunc(code: CodeType, instruction_offset: int, exception: BaseException) -> object
LINE:func(code: CodeType, line_number: int) -> object
BRANCH_LEFT,BRANCH_RIGHTundJUMPfunc(code: CodeType, instruction_offset: int, destination_offset: int) -> object
Beachten Sie, dass destination_offset der Ort ist, an dem der Code als nächstes ausgeführt wird.
-
func(code: CodeType, instruction_offset: int) -> object