code.md
1> **Источник:** https://python-all.ru/3.12/c-api/code.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Объекты кода89Объекты кода – это низкоуровневая деталь реализации CPython. Каждый из них представляет блок исполняемого кода, который ещё не привязан к функции.1011#### `type PyCodeObject`1213C-структура объектов, используемых для описания объектов кода. Поля этого типа могут быть изменены в любое время.1415#### `PyTypeObject PyCode_Type`1617Это экземпляр [`PyTypeObject`](https://python-all.ru/3.12/c-api/type.html#c.PyTypeObject), представляющий [объект кода](https://python-all.ru/3.12/reference/datamodel.html#code-objects) Python.1819#### `int PyCode_Check(PyObject *co)`2021Возвращает true, если *co* является [объектом кода](https://python-all.ru/3.12/reference/datamodel.html#code-objects). Эта функция всегда выполняется успешно.2223#### `Py_ssize_t PyCode_GetNumFree(PyCodeObject *co)`2425Возвращает количество свободных переменных в объекте кода.2627#### `int PyCode_GetFirstFree(PyCodeObject *co)`2829Возвращает позицию первой свободной переменной в объекте кода.3031#### `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)`3233> *Это [нестабильное API](https://python-all.ru/3.12/c-api/stable.html#unstable-c-api). Оно может меняться без предупреждения в минорных версиях.*3435Возвращает новый объект кода. Если нужен фиктивный объект кода для создания фрейма, используйте [`PyCode_NewEmpty()`](https://python-all.ru/3.12/c-api/code.html#c.PyCode_NewEmpty).3637Поскольку определение байт-кода часто меняется, прямой вызов [`PyUnstable_Code_New()`](https://python-all.ru/3.12/c-api/code.html#c.PyUnstable_Code_New) может привязать к конкретной версии Python.3839Многочисленные аргументы этой функции сложным образом взаимозависимы, поэтому незначительные изменения значений могут привести к некорректному исполнению или сбою виртуальной машины. Используйте эту функцию с крайней осторожностью.4041Изменено в версии 3.11: Добавлены параметры `qualname` и `exceptiontable`.4243Изменено в версии 3.12: Переименовано из `PyCode_New` в рамках [нестабильного C API](https://python-all.ru/3.12/c-api/stable.html#unstable-c-api). Старое имя устарело, но останется доступным до следующего изменения сигнатуры.4445#### `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)`4647> *Это [нестабильное API](https://python-all.ru/3.12/c-api/stable.html#unstable-c-api). Оно может меняться без предупреждения в минорных версиях.*4849Аналогично [`PyUnstable_Code_New()`](https://python-all.ru/3.12/c-api/code.html#c.PyUnstable_Code_New), но с дополнительным параметром “posonlyargcount” для позиционных аргументов. Те же предостережения, что и для `PyUnstable_Code_New`, применимы к этой функции.5051Добавлено в версии 3.8: как `PyCode_NewWithPosOnlyArgs`5253Изменено в версии 3.11: Добавлены параметры `qualname` и `exceptiontable`.5455Изменено в версии 3.12: Переименован в `PyUnstable_Code_NewWithPosOnlyArgs`. Старое имя устарело, но останется доступным до следующего изменения сигнатуры.5657#### `PyCodeObject *PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)`5859*Возвращаемое значение: новая ссылка.*6061Возвращает новый пустой объект кода с указанными именем файла, именем функции и номером первой строки. Полученный объект кода вызовет `Exception` при выполнении.6263#### `int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)`6465Возвращает номер строки инструкции, которая начинается до или на `byte_offset` и заканчивается после него. Если нужен просто номер строки фрейма, используйте [`PyFrame_GetLineNumber()`](https://python-all.ru/3.12/c-api/frame.html#c.PyFrame_GetLineNumber).6667Для эффективного перебора номеров строк в объекте кода используйте [**API, описанный в PEP 626**](https://python-all.ru/3.12/c-api/code.html).6869#### `int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)`7071Устанавливает переданные указатели `int` на номера строки и столбца исходного кода для инструкции по адресу `byte_offset`. Устанавливает значение `0`, если информация для какого-либо элемента недоступна.7273Возвращает `1` при успехе функции и 0 в противном случае.7475Добавлено в версии 3.12.7677#### `PyObject *PyCode_GetCode(PyCodeObject *co)`7879Эквивалент кода Python `getattr(co, 'co_code')`. Возвращает сильную ссылку на [`PyBytesObject`](https://python-all.ru/3.12/c-api/bytes.html#c.PyBytesObject), представляющий байт-код в объекте кода. В случае ошибки возвращается `NULL` и возбуждается исключение.8081Этот `PyBytesObject` может быть создан интерпретатором по требованию и не обязательно представляет байт-код, который действительно выполняется CPython. Основное назначение этой функции – отладчики и профилировщики.8283Добавлено в версии 3.12.8485#### `PyObject *PyCode_GetVarnames(PyCodeObject *co)`8687Эквивалент кода Python `getattr(co, 'co_varnames')`. Возвращает новую ссылку на [`PyTupleObject`](https://python-all.ru/3.12/c-api/tuple.html#c.PyTupleObject), содержащий имена локальных переменных. В случае ошибки возвращается `NULL` и возбуждается исключение.8889Добавлено в версии 3.12.9091#### `PyObject *PyCode_GetCellvars(PyCodeObject *co)`9293Эквивалент кода Python `getattr(co, 'co_cellvars')`. Возвращает новую ссылку на [`PyTupleObject`](https://python-all.ru/3.12/c-api/tuple.html#c.PyTupleObject), содержащий имена локальных переменных, на которые ссылаются вложенные функции. В случае ошибки возвращается `NULL` и возбуждается исключение.9495Добавлено в версии 3.12.9697#### `PyObject *PyCode_GetFreevars(PyCodeObject *co)`9899Эквивалентно коду Python `getattr(co, 'co_freevars')`. Возвращает новую ссылку на [`PyTupleObject`](https://python-all.ru/3.12/c-api/tuple.html#c.PyTupleObject), содержащий имена свободных переменных. В случае ошибки возвращается `NULL` и возбуждается исключение.100101Добавлено в версии 3.12.102103#### `int PyCode_AddWatcher(PyCode_WatchCallback callback)`104105Регистрирует *колбэк* как наблюдатель за объектами кода для текущего интерпретатора. Возвращает идентификатор, который можно передать в [`PyCode_ClearWatcher()`](https://python-all.ru/3.12/c-api/code.html#c.PyCode_ClearWatcher). В случае ошибки (например, нет свободных идентификаторов наблюдателей) возвращает `-1` и устанавливает исключение.106107Добавлено в версии 3.12.108109#### `int PyCode_ClearWatcher(int watcher_id)`110111Удаляет наблюдатель, заданный идентификатором *watcher\_id*, ранее полученным от [`PyCode_AddWatcher()`](https://python-all.ru/3.12/c-api/code.html#c.PyCode_AddWatcher) для текущего интерпретатора. Возвращает `0` при успехе или `-1` с установкой исключения при ошибке (например, если указанный *watcher\_id* никогда не был зарегистрирован).112113Добавлено в версии 3.12.114115#### `type PyCodeEvent`116117Перечисление возможных событий наблюдателя объекта кода: - `PY_CODE_EVENT_CREATE` - `PY_CODE_EVENT_DESTROY`118119Добавлено в версии 3.12.120121#### `typedef int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject *co)`122123Тип функции обратного вызова наблюдателя объекта кода.124125Если *event* равно `PY_CODE_EVENT_CREATE`, то обратный вызов вызывается после полной инициализации *co*. В противном случае обратный вызов вызывается до того, как произойдет уничтожение *co*, так что можно проверить предыдущее состояние *co*.126127Если *event* равно `PY_CODE_EVENT_DESTROY`, то получение ссылки в обратном вызове на объект кода, который должен быть уничтожен, воскресит его и предотвратит его освобождение в данный момент. Когда воскрешенный объект будет уничтожен позже, все активные на тот момент обратные вызовы наблюдателей будут вызваны снова.128129Пользователи этого API не должны полагаться на внутренние детали реализации среды выполнения. Такие детали могут включать, но не ограничиваясь, точный порядок и время создания и уничтожения объектов кода. Хотя изменения этих деталей могут привести к различиям, наблюдаемым наблюдателями (включая то, вызывается ли обратный вызов или нет), это не меняет семантику выполняемого кода Python.130131Если обратный вызов устанавливает исключение, он должен вернуть `-1`; это исключение будет выведено как неподнимаемое исключение с помощью [`PyErr_WriteUnraisable()`](https://python-all.ru/3.12/c-api/exceptions.html#c.PyErr_WriteUnraisable). В противном случае он должен вернуть `0`.132133На момент входа в обратный вызов уже может быть установлено отложенное исключение. В этом случае обратный вызов должен вернуть `0`, оставив то же исключение установленным. Это означает, что обратный вызов не может вызывать никакой другой API, который может установить исключение, если только он сначала не сохранит и не очистит состояние исключения, а затем не восстановит его перед возвратом.134135Добавлено в версии 3.12.136137# Дополнительная информация138139Для поддержки низкоуровневых расширений механизма вычисления кадров, таких как внешние JIT-компиляторы, к объектам кода можно прикреплять произвольные дополнительные данные.140141Эти функции относятся к нестабильному уровню C API: данная функциональность является деталью реализации CPython, и API может измениться без предупреждения об устаревании.142143#### `Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)`144145> *Это [нестабильное API](https://python-all.ru/3.12/c-api/stable.html#unstable-c-api). Оно может меняться без предупреждения в минорных версиях.*146147Возвращает новое непрозрачное значение индекса, используемое для добавления данных в объекты кода.148149Обычно эту функцию вызывают один раз (на каждый интерпретатор) и используют полученный результат с `PyCode_GetExtra` и `PyCode_SetExtra` для управления данными на отдельных объектах кода.150151Если *free* не равен `NULL`: при освобождении объекта кода будет вызван *free* для данных, не являющихся `NULL`, хранящихся под новым индексом. Используйте [`Py_DecRef()`](https://python-all.ru/3.12/c-api/refcounting.html#c.Py_DecRef) при хранении [`PyObject`](https://python-all.ru/3.12/c-api/structures.html#c.PyObject).152153Добавлено в версии 3.6: как `_PyEval_RequestCodeExtraIndex`154155Изменено в версии 3.12: Переименовано в `PyUnstable_Eval_RequestCodeExtraIndex`. Старое приватное имя устарело, но будет доступно до изменения API.156157#### `int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)`158159> *Это [нестабильное API](https://python-all.ru/3.12/c-api/stable.html#unstable-c-api). Оно может меняться без предупреждения в минорных версиях.*160161Устанавливает *extra* в дополнительные данные, хранящиеся по указанному индексу. Возвращает 0 в случае успеха. В случае ошибки устанавливает исключение и возвращает -1.162163Если по индексу не было установлено никаких данных, устанавливает *extra* в `NULL` и возвращает 0 без установки исключения.164165Добавлено в версии 3.6: как `_PyCode_GetExtra`166167Изменено в версии 3.12: Переименовано в `PyUnstable_Code_GetExtra`. Старое приватное имя устарело, но будет доступно до изменения API.168169#### `int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)`170171> *Это [нестабильное API](https://python-all.ru/3.12/c-api/stable.html#unstable-c-api). Оно может меняться без предупреждения в минорных версиях.*172173Устанавливает дополнительные данные, хранящиеся по указанному индексу, в *extra*. Возвращает 0 в случае успеха. В случае ошибки устанавливает исключение и возвращает -1.174175Добавлено в версии 3.6: как `_PyCode_SetExtra`176177Изменено в версии 3.12: Переименовано в `PyUnstable_Code_SetExtra`. Старое приватное имя устарело, но будет доступно до изменения API.178