Кодовые объекты¶
Объекты кода - это низкоуровневая деталь реализации CPython. Каждый из них представляет собой фрагмент исполняемого кода, который еще не был связан с функцией.
-
type PyCodeObject¶
C-структура объектов, используемых для описания объектов кода. Поля этого типа могут быть изменены в любое время.
-
PyTypeObject PyCode_Type¶
Это экземпляр
PyTypeObject
, представляющий питоновский code object.
-
int PyCode_Check(PyObject *co)¶
Возвращает true, если co является code object. Эта функция всегда успешна.
-
Py_ssize_t PyCode_GetNumFree(PyCodeObject *co)¶
Возвращает количество свободных переменных в объекте кода.
-
int PyUnstable_Code_GetFirstFree(PyCodeObject *co)¶
- Это Нестабильный API. Она может меняться без предупреждения в небольших выпусках.
Возвращает позицию первой свободной переменной в кодовом объекте.
Изменено в версии 3.13: Переименовано из
PyCode_GetFirstFree
в часть Нестабильный API на языке C. Старое имя устарело, но будет оставаться доступным до тех пор, пока сигнатура не изменится.
-
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)¶
- Это Нестабильный API. Она может меняться без предупреждения в небольших выпусках.
Возвращает новый объект кода. Если вам нужен фиктивный объект кода для создания фрейма, используйте вместо него
PyCode_NewEmpty()
.Поскольку определение байткода часто меняется, прямой вызов
PyUnstable_Code_New()
может привязать вас к точной версии Python.Многие аргументы этой функции сложным образом зависят друг от друга, поэтому незначительные изменения значений могут привести к неправильному выполнению или сбоям в работе виртуальной машины. Используйте эту функцию только с особой осторожностью.
Изменено в версии 3.11: Добавлены параметры
qualname
иexceptiontable
.Изменено в версии 3.12: Переименовано из
PyCode_New
в часть Нестабильный API на языке C. Старое имя устарело, но будет оставаться доступным до тех пор, пока сигнатура не изменится.
-
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)¶
- Это Нестабильный API. Она может меняться без предупреждения в небольших выпусках.
Аналогична
PyUnstable_Code_New()
, но с дополнительным параметром «posonlyargcount» для аргументов только с позицией. Те же предостережения, что и дляPyUnstable_Code_New
, применимы и к этой функции.Added in version 3.8: как
PyCode_NewWithPosOnlyArgs
Изменено в версии 3.11: Добавлены параметры
qualname
иexceptiontable
.Изменено в версии 3.12: Переименовано в
PyUnstable_Code_NewWithPosOnlyArgs
. Старое имя устарело, но будет оставаться доступным до тех пор, пока сигнатура не изменится.
-
PyCodeObject *PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)¶
- Возвращаемое значение: Новая ссылка.
Возвращает новый пустой объект кода с указанным именем файла, именем функции и номером первой строки. При выполнении результирующий объект кода вызовет сообщение
Exception
.
-
int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)¶
Возвращает номер строки инструкции, которая начинается на или до
byte_offset
и заканчивается после него. Если вам нужен только номер строки кадра, используйте вместо этогоPyFrame_GetLineNumber()
.Для эффективного итеративного перебора номеров строк в кодовом объекте используйте the API described in PEP 626.
-
int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)¶
Устанавливает переданные указатели
int
на номера строк и столбцов исходного кода для инструкции по адресуbyte_offset
. Устанавливает значение0
, если для какого-либо элемента информация недоступна.Возвращает
1
в случае успешного выполнения функции и 0 в противном случае.Added in version 3.11.
-
PyObject *PyCode_GetCode(PyCodeObject *co)¶
Эквивалентно коду Python
getattr(co, 'co_code')
. Возвращает сильную ссылку наPyBytesObject
, представляющую байткод в кодовом объекте. При ошибке возвращаетсяNULL
и поднимается исключение.Этот
PyBytesObject
может быть создан по требованию интерпретатора и не обязательно представляет собой байткод, фактически выполняемый CPython. Основная область применения этой функции - отладчики и профилировщики.Added in version 3.11.
-
PyObject *PyCode_GetVarnames(PyCodeObject *co)¶
Эквивалентно коду Python
getattr(co, 'co_varnames')
. Возвращает новую ссылку наPyTupleObject
, содержащую имена локальных переменных. При ошибке возвращаетсяNULL
и поднимается исключение.Added in version 3.11.
-
PyObject *PyCode_GetCellvars(PyCodeObject *co)¶
Эквивалентно коду Python
getattr(co, 'co_cellvars')
. Возвращает новую ссылку наPyTupleObject
, содержащую имена локальных переменных, на которые ссылаются вложенные функции. При ошибке возвращаетсяNULL
и вызывается исключение.Added in version 3.11.
-
PyObject *PyCode_GetFreevars(PyCodeObject *co)¶
Эквивалентно коду Python
getattr(co, 'co_freevars')
. Возвращает новую ссылку наPyTupleObject
, содержащую имена свободных переменных. При ошибке возвращаетсяNULL
и поднимается исключение.Added in version 3.11.
-
int PyCode_AddWatcher(PyCode_WatchCallback callback)¶
Зарегистрируйте callback в качестве наблюдателя за объектами кода для текущего интерпретатора. Возвращает идентификатор, который может быть передан в
PyCode_ClearWatcher()
. В случае ошибки (например, нет больше доступных идентификаторов наблюдателя) верните-1
и установите исключение.Added in version 3.12.
-
int PyCode_ClearWatcher(int watcher_id)¶
Очистить наблюдателя, идентифицированного watcher_id, ранее возвращенного из
PyCode_AddWatcher()
для текущего интерпретатора. Возвращает0
в случае успеха, или-1
и устанавливает исключение в случае ошибки (например, если данный watcher_id никогда не был зарегистрирован).Added in version 3.12.
-
type PyCodeEvent¶
Перечисление возможных событий наблюдателя за объектами кода: -
PY_CODE_EVENT_CREATE
-PY_CODE_EVENT_DESTROY
Added in version 3.12.
-
typedef int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject *co)¶
Тип функции обратного вызова наблюдателя за объектами кода.
Если event - это
PY_CODE_EVENT_CREATE
, то обратный вызов вызывается после полной инициализации co. В противном случае обратный вызов вызывается до уничтожения co, так что можно проверить предыдущее состояние co.Если event имеет значение
PY_CODE_EVENT_DESTROY
, то получение в обратном вызове ссылки на объект кода, который будет уничтожен, воскресит его и предотвратит его освобождение в это время. Когда воскрешенный объект будет уничтожен позже, все активные в это время обратные вызовы наблюдателя будут вызваны снова.Пользователи этого API не должны полагаться на внутренние детали реализации во время выполнения. Такие детали могут включать, но не ограничиваться, точным порядком и временем создания и уничтожения объектов кода. Хотя изменения в этих деталях могут привести к различиям, наблюдаемым наблюдателями (включая то, вызывается ли обратный вызов или нет), они не меняют семантику выполняемого кода Python.
Если обратный вызов устанавливает исключение, он должен вернуть
-1
; это исключение будет выведено как нераскрываемое исключение с помощьюPyErr_WriteUnraisable()
. В противном случае он должен вернуть0
.При входе в обратный вызов уже может быть установлено исключение. В этом случае обратный вызов должен вернуть
0
с тем же самым исключением, которое все еще установлено. Это означает, что обратный вызов не может вызывать другие API, которые могут установить исключение, если только он не сохранит и не очистит состояние исключения сначала, а затем восстановит его перед возвратом.Added in version 3.12.
Дополнительная информация¶
Для поддержки низкоуровневых расширений оценки кадров, таких как внешние компиляторы «точно в срок», к объектам кода можно присоединять произвольные дополнительные данные.
Эти функции являются частью нестабильного уровня C API: эта функциональность является деталью реализации CPython, и API может измениться без предупреждений об устаревании.
-
Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)¶
- Это Нестабильный API. Она может меняться без предупреждения в небольших выпусках.
Возвращает новое непрозрачное значение индекса, используемое для добавления данных в объекты кода.
Обычно вы вызываете эту функцию один раз (для каждого интерпретатора) и используете результат с помощью
PyCode_GetExtra
иPyCode_SetExtra
для манипулирования данными в отдельных объектах кода.Если free не
NULL
: при деаллокации объекта кода будет вызвано free для данных, хранящихся не под индексомNULL
, а под новым индексом. ИспользуйтеPy_DecRef()
при храненииPyObject
.Added in version 3.6: как
_PyEval_RequestCodeExtraIndex
Изменено в версии 3.12: Переименовано в
PyUnstable_Eval_RequestCodeExtraIndex
. Старое приватное имя устарело, но будет доступно до изменения API.
-
int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)¶
- Это Нестабильный API. Она может меняться без предупреждения в небольших выпусках.
Устанавливает extra в дополнительные данные, хранящиеся под заданным индексом. Возвращает 0 при успехе. При неудаче создайте исключение и верните -1.
Если под индексом не было установлено никаких данных, установите extra в
NULL
и верните 0, не создавая исключения.Added in version 3.6: как
_PyCode_GetExtra
Изменено в версии 3.12: Переименовано в
PyUnstable_Code_GetExtra
. Старое приватное имя устарело, но будет доступно до изменения API.
-
int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)¶
- Это Нестабильный API. Она может меняться без предупреждения в небольших выпусках.
Устанавливает дополнительные данные, хранящиеся под заданным индексом, в значение extra. Возвращает 0 при успехе. При неудаче создайте исключение и верните -1.
Added in version 3.6: как
_PyCode_SetExtra
Изменено в версии 3.12: Переименовано в
PyUnstable_Code_SetExtra
. Старое приватное имя устарело, но будет доступно до изменения API.