Code-Objekte

Code-Objekte sind ein Low-Level-Detail der CPython-Implementierung. Jedes repräsentiert einen Code-Block, der noch nicht an eine Funktion gebunden wurde.

type PyCodeObject

Die C-Struktur der Objekte, die zur Beschreibung von Code-Objekten verwendet werden. Die Felder dieses Typs können sich jederzeit ändern.

PyTypeObject PyCode_Type

Dies ist eine Instanz von PyTypeObject, die das Python- Code-Objekt repräsentiert.

int PyCode_Check(PyObject *co)

Gibt wahr zurück, wenn co ein Code-Objekt ist. Diese Funktion ist immer erfolgreich.

Py_ssize_t PyCode_GetNumFree(PyCodeObject *co)

Gibt die Anzahl der freien (Closure) Variablen in einem Code-Objekt zurück.

int PyUnstable_Code_GetFirstFree(PyCodeObject *co)
Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.

Gibt die Position der ersten freien (Closure) Variablen in einem Code-Objekt zurück.

Geändert in Version 3.13: Umbenannt von PyCode_GetFirstFree als Teil der Instabilen C-API. Der alte Name ist veraltet, bleibt aber verfügbar, bis sich die Signatur erneut ändert.

PyCodeObject *PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.

Gibt ein neues Code-Objekt zurück. Wenn Sie ein Dummy-Code-Objekt zum Erstellen eines Frames benötigen, verwenden Sie stattdessen PyCode_NewEmpty().

Da die Definition des Bytecodes sich häufig ändert, kann der direkte Aufruf von PyUnstable_Code_New() Sie an eine bestimmte Python-Version binden.

Die vielen Argumente dieser Funktion sind auf komplexe Weise voneinander abhängig, was bedeutet, dass subtile Änderungen an den Werten wahrscheinlich zu fehlerhafter Ausführung oder VM-Abstürzen führen. Verwenden Sie diese Funktion nur mit äußerster Vorsicht.

Geändert in Version 3.11: Hinzugefügt wurden die Parameter qualname und exceptiontable.

Geändert in Version 3.12: Umbenannt von PyCode_New als Teil der Instabilen C-API. Der alte Name ist veraltet, bleibt aber verfügbar, bis sich die Signatur erneut ändert.

PyCodeObject *PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.

Ähnlich wie PyUnstable_Code_New(), aber mit einem zusätzlichen "posonlyargcount" für positionsabhängige Argumente. Die gleichen Vorbehalte, die für PyUnstable_Code_New gelten, gelten auch für diese Funktion.

Hinzugefügt in Version 3.8: als PyCode_NewWithPosOnlyArgs

Geändert in Version 3.11: Hinzugefügt wurden die Parameter qualname und exceptiontable.

Geändert in Version 3.12: Umbenannt zu PyUnstable_Code_NewWithPosOnlyArgs. Der alte Name ist veraltet, bleibt aber verfügbar, bis sich die Signatur erneut ändert.

PyCodeObject *PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
Rückgabewert: Neue Referenz.

Gibt ein neues leeres Code-Objekt mit dem angegebenen Dateinamen, Funktionsnamen und der ersten Zeilennummer zurück. Das resultierende Code-Objekt löst eine Exception aus, wenn es ausgeführt wird.

int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)

Gibt die Zeilennummer der Instruktion zurück, die auf oder vor byte_offset liegt und danach endet. Wenn Sie nur die Zeilennummer eines Frames benötigen, verwenden Sie stattdessen PyFrame_GetLineNumber().

Für eine effiziente Iteration über die Zeilennummern eines Code-Objekts verwenden Sie die in PEP 626 beschriebene API.

int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)

Setzt die übergebenen int-Zeiger auf die Quellcodezeilen- und Spaltennummern für die Instruktion bei byte_offset. Setzt den Wert auf 0, wenn für ein bestimmtes Element keine Informationen verfügbar sind.

Gibt 1 zurück, wenn die Funktion erfolgreich ist, andernfalls 0.

Hinzugefügt in Version 3.11.

PyObject *PyCode_GetCode(PyCodeObject *co)

Entspricht dem Python-Code getattr(co, 'co_code'). Gibt eine starke Referenz auf ein PyBytesObject zurück, das den Bytecode in einem Code-Objekt repräsentiert. Bei einem Fehler wird NULL zurückgegeben und eine Ausnahme ausgelöst.

Dieses PyBytesObject kann bei Bedarf vom Interpreter erstellt werden und repräsentiert nicht unbedingt den tatsächlich von CPython ausgeführten Bytecode. Der Hauptanwendungsfall für diese Funktion sind Debugger und Profiler.

Hinzugefügt in Version 3.11.

PyObject *PyCode_GetVarnames(PyCodeObject *co)

Entspricht dem Python-Code getattr(co, 'co_varnames'). Gibt eine neue Referenz auf ein PyTupleObject zurück, das die Namen der lokalen Variablen enthält. Bei einem Fehler wird NULL zurückgegeben und eine Ausnahme ausgelöst.

Hinzugefügt in Version 3.11.

PyObject *PyCode_GetCellvars(PyCodeObject *co)

Entspricht dem Python-Code getattr(co, 'co_cellvars'). Gibt eine neue Referenz auf ein PyTupleObject zurück, das die Namen der lokalen Variablen enthält, auf die von verschachtelten Funktionen verwiesen wird. Bei einem Fehler wird NULL zurückgegeben und eine Ausnahme ausgelöst.

Hinzugefügt in Version 3.11.

PyObject *PyCode_GetFreevars(PyCodeObject *co)

Entspricht dem Python-Code getattr(co, 'co_freevars'). Gibt eine neue Referenz auf ein PyTupleObject zurück, das die Namen der freien (Closure) Variablen enthält. Bei einem Fehler wird NULL zurückgegeben und eine Ausnahme ausgelöst.

Hinzugefügt in Version 3.11.

int PyCode_AddWatcher(PyCode_WatchCallback callback)

Registriert callback als Code-Objekt-Watcher für den aktuellen Interpreter. Gibt eine ID zurück, die an PyCode_ClearWatcher() übergeben werden kann. Im Fehlerfall (z. B. keine weiteren Watcher-IDs verfügbar) gibt sie -1 zurück und setzt eine Ausnahme.

Hinzugefügt in Version 3.12.

int PyCode_ClearWatcher(int watcher_id)

Löscht den Watcher mit der ID watcher_id, die zuvor von PyCode_AddWatcher() für den aktuellen Interpreter zurückgegeben wurde. Gibt bei Erfolg 0 zurück, andernfalls -1 und setzt eine Ausnahme (z. B. wenn die angegebene watcher_id nie registriert wurde).

Hinzugefügt in Version 3.12.

type PyCodeEvent

Enumeration möglicher Ereignisse für Code-Objekt-Watcher: - PY_CODE_EVENT_CREATE - PY_CODE_EVENT_DESTROY

Hinzugefügt in Version 3.12.

typedef int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject *co)

Typ einer Callback-Funktion für Code-Objekt-Watcher.

Wenn event PY_CODE_EVENT_CREATE ist, wird der Callback aufgerufen, nachdem co vollständig initialisiert wurde. Andernfalls wird der Callback vor der Zerstörung von co aufgerufen, sodass der vorherige Zustand von co inspiziert werden kann.

Wenn event PY_CODE_EVENT_DESTROY ist, wird durch das Erstellen einer Referenz im Callback auf das kurz vor der Zerstörung stehende Code-Objekt dieses wiederbelebt und dessen Freigabe zu diesem Zeitpunkt verhindert. Wenn das wiederbelebte Objekt später zerstört wird, werden alle zu diesem Zeitpunkt aktiven Watcher-Callbacks erneut aufgerufen.

Benutzer dieser API sollten sich nicht auf interne Laufzeitimplementierungsdetails verlassen. Solche Details können die genaue Reihenfolge und den Zeitpunkt der Erstellung und Zerstörung von Code-Objekten umfassen, sind aber nicht darauf beschränkt. Während Änderungen an diesen Details zu beobachtbaren Unterschieden für Watcher führen können (einschließlich, ob ein Callback aufgerufen wird oder nicht), ändern sie nicht die Semantik des ausgeführten Python-Codes.

Wenn der Callback eine Ausnahme setzt, muss er -1 zurückgeben; diese Ausnahme wird als nicht aufhebbare Ausnahme mit PyErr_WriteUnraisable() ausgegeben. Andernfalls sollte er 0 zurückgeben.

Es kann bereits eine ausstehende Ausnahme beim Eintritt in den Callback gesetzt sein. In diesem Fall sollte der Callback 0 zurückgeben, wobei die Ausnahme weiterhin gesetzt ist. Das bedeutet, der Callback darf keine andere API aufrufen, die eine Ausnahme setzen kann, es sei denn, er speichert und löscht zuerst den Ausnahmezustand und stellt ihn vor der Rückgabe wieder her.

Hinzugefügt in Version 3.12.

Flags für Code-Objekte

Code-Objekte enthalten ein Bitfeld von Flags, das als Python-Attribut co_flags abgerufen (z. B. mit PyObject_GetAttrString()) und mit einem flags-Argument an PyUnstable_Code_New() und ähnliche Funktionen gesetzt werden kann.

Flags, deren Namen mit CO_FUTURE_ beginnen, entsprechen Features, die normalerweise über Future-Anweisungen auswählbar sind. Diese Flags können in PyCompilerFlags.cf_flags verwendet werden. Beachten Sie, dass viele CO_FUTURE_-Flags in aktuellen Python-Versionen obligatorisch sind und deren Setzen keine Auswirkung hat.

Die folgenden Flags sind verfügbar. Für ihre Bedeutung siehe die verlinkte Dokumentation ihrer Python-Äquivalente.

Flag

Bedeutung

CO_OPTIMIZED

inspect.CO_OPTIMIZED

CO_NEWLOCALS

inspect.CO_NEWLOCALS

CO_VARARGS

inspect.CO_VARARGS

CO_VARKEYWORDS

inspect.CO_VARKEYWORDS

CO_NESTED

inspect.CO_NESTED

CO_GENERATOR

inspect.CO_GENERATOR

CO_COROUTINE

inspect.CO_COROUTINE

CO_ITERABLE_COROUTINE

inspect.CO_ITERABLE_COROUTINE

CO_ASYNC_GENERATOR

inspect.CO_ASYNC_GENERATOR

CO_HAS_DOCSTRING

inspect.CO_HAS_DOCSTRING

CO_METHOD

inspect.CO_METHOD

CO_FUTURE_DIVISION

keine Auswirkung (__future__.division)

CO_FUTURE_ABSOLUTE_IMPORT

keine Auswirkung (__future__.absolute_import)

CO_FUTURE_WITH_STATEMENT

keine Auswirkung (__future__.with_statement)

CO_FUTURE_PRINT_FUNCTION

keine Auswirkung (__future__.print_function)

CO_FUTURE_UNICODE_LITERALS

keine Auswirkung (__future__.unicode_literals)

CO_FUTURE_GENERATOR_STOP

keine Auswirkung (__future__.generator_stop)

CO_FUTURE_ANNOTATIONS

__future__.annotations

Zusätzliche Informationen

Um die Low-Level-Erweiterung der Frame-Auswertung zu unterstützen, wie z. B. externe Just-in-Time-Compiler, ist es möglich, beliebige zusätzliche Daten an Code-Objekte anzuhängen.

Diese Funktionen sind Teil der instabilen C-API-Ebene: diese Funktionalität ist ein CPython-Implementierungsdetail, und die API kann sich ohne Verwarnungen vor der Veraltung ändern.

Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.

Gibt einen neuen, undurchsichtigen Indexwert zurück, der zum Hinzufügen von Daten zu Code-Objekten verwendet wird.

Normalerweise rufen Sie diese Funktion einmal (pro Interpreter) auf und verwenden das Ergebnis mit PyCode_GetExtra und PyCode_SetExtra, um Daten auf einzelnen Code-Objekten zu manipulieren.

Wenn free nicht NULL ist: Wenn ein Code-Objekt deallokiert wird, wird free auf Nicht-NULL-Daten aufgerufen, die unter dem neuen Index gespeichert sind. Verwenden Sie Py_DecRef() beim Speichern von PyObject.

Hinzugefügt in Version 3.6: als _PyEval_RequestCodeExtraIndex

Geändert in Version 3.12: Umbenannt zu PyUnstable_Eval_RequestCodeExtraIndex. Der alte private Name ist veraltet, bleibt aber bis zur nächsten API-Änderung verfügbar.

int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.

Setzt extra auf die unter dem angegebenen Index gespeicherten zusätzlichen Daten. Gibt 0 bei Erfolg zurück. Setzt eine Ausnahme und gibt -1 bei Fehler zurück.

Wenn keine Daten unter dem Index gespeichert wurden, wird extra auf NULL gesetzt und 0 zurückgegeben, ohne eine Ausnahme zu setzen.

Hinzugefügt in Version 3.6: als _PyCode_GetExtra

Geändert in Version 3.12: Umbenannt zu PyUnstable_Code_GetExtra. Der alte private Name ist veraltet, bleibt aber bis zur nächsten API-Änderung verfügbar.

int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.

Setzt die unter dem angegebenen Index gespeicherten zusätzlichen Daten auf extra. Gibt 0 bei Erfolg zurück. Setzt eine Ausnahme und gibt -1 bei Fehler zurück.

Hinzugefügt in Version 3.6: als _PyCode_SetExtra

Geändert in Version 3.12: Umbenannt zu PyUnstable_Code_SetExtra. Der alte private Name ist veraltet, bleibt aber bis zur nächsten API-Änderung verfügbar.