Стабильность C API

На C API Python распространяется политика обратной совместимости PEP 387. Хотя C API будет меняться с каждым новым выпуском (например, с 3.9 по 3.10), большинство изменений будут совместимы с исходным кодом, как правило, путем добавления только нового API. Изменение существующего API или удаление API производится только по истечении периода амортизации или для устранения серьезных неполадок.

Двоичный интерфейс приложений CPython (ABI) поддерживает прямую и обратную совместимость во всех младших версиях (если они скомпилированы одинаково; смотрите Соображения, касающиеся платформы ниже). Итак, код, скомпилированный для Python 3.10.0, будет работать на 3.10.8 и наоборот, но его нужно будет скомпилировать отдельно для 3.9.x и 3.11.x.

Имена, перед которыми ставится знак подчеркивания, например _Py_InternalState, являются частными API, которые могут изменяться без предварительного уведомления даже в выпусках исправлений.

Стабильный двоичный интерфейс приложения

Для простоты в этом документе говорится о расширениях, но ограниченный API и стабильный ABI работают одинаково для всех применений API – например, для встраивания Python.

Ограниченный C API

В Python 3.2 появился Limited API, подмножество C API Python. Расширения, которые используют только Limited API, могут быть скомпилированы один раз и работать с несколькими версиями Python. Содержимое Limited API listed below.

Py_LIMITED_API

Определите этот макрос перед включением Python.h, чтобы выбрать использование только ограниченного API и выбрать версию API с ограниченным доступом.

Определите для Py_LIMITED_API значение PY_VERSION_HEX, соответствующее самой низкой версии Python, поддерживаемой вашим расширением. Расширение будет работать без перекомпиляции со всеми версиями Python 3, начиная с указанной, и может использовать ограниченный API, введенный до этой версии.

Вместо того, чтобы напрямую использовать макрос PY_VERSION_HEX, жестко запрограммируйте минимальную младшую версию (например, 0x030A0000 для Python 3.10) для обеспечения стабильности при компиляции с будущими версиями Python.

Вы также можете задать для Py_LIMITED_API значение 3. Это работает так же, как и для 0x03020000 (Python 3.2, версия, в которой представлен ограниченный API).

Стабильный АБИ

Чтобы включить это, Python предоставляет Стабильный ABI: набор символов, которые будут оставаться совместимыми во всех версиях Python 3.x.

Стабильный ABI содержит символы, отображаемые в Limited API, а также другие – например, функции, необходимые для поддержки старых версий ограниченного API.

В Windows расширения, использующие стабильный ABI, должны быть связаны с python3.dll, а не с библиотекой, зависящей от версии, такой как python39.dll.

На некоторых платформах Python будет искать и загружать файлы общей библиотеки с именами, указанными в теге abi3 (например, mymodule.abi3.so). Он не проверяет, соответствуют ли такие расширения стабильному ABI. Пользователь (или его инструменты упаковки) должны убедиться, что, например, расширения, созданные с использованием API с ограниченным использованием версии 3.10+, не установлены для более ранних версий Python.

Все функции в стабильном ABI представлены как функции в общей библиотеке Python, а не только как макросы. Это позволяет использовать их в языках, которые не используют препроцессор C.

Ограниченный объем и производительность API

Цель ограниченного API состоит в том, чтобы разрешить все, что возможно с полным C API, но, возможно, с уменьшением производительности.

Например, в то время как PyList_GetItem() доступен, его “небезопасный” вариант макроса PyList_GET_ITEM() недоступен. Макрос может работать быстрее, поскольку он может полагаться на детали реализации объекта list, зависящие от версии.

Без определения Py_LIMITED_API некоторые функции C API встраиваются или заменяются макросами. Определение Py_LIMITED_API отключает это встраивание, обеспечивая стабильность по мере улучшения структур данных Python, но, возможно, снижая производительность.

Исключив определение Py_LIMITED_API, можно скомпилировать ограниченное расширение API с помощью ABI, зависящего от версии. Это может повысить производительность для данной версии Python, но ограничит совместимость. Компиляция с использованием Py_LIMITED_API приведет к получению расширения, которое может быть распространено там, где оно недоступно для конкретной версии - например, для предварительных выпусков новой версии Python.

Ограниченные требования к API

Обратите внимание, что компиляция с использованием Py_LIMITED_API не является полной гарантией того, что код соответствует Limited API или Stable ABI. Py_LIMITED_API охватывает только определения, но API также включает в себя другие проблемы, такие как ожидаемая семантика.

Одна из проблем, от которой Py_LIMITED_API не защищает, - это вызов функции с аргументами, которые недопустимы в более ранней версии Python. Например, рассмотрим функцию, которая начинает принимать NULL в качестве аргумента. В Python 3.9 NULL теперь выбирает поведение по умолчанию, но в Python 3.8 аргумент будет использоваться напрямую, что приведет к разыменованию NULL и сбою. Аналогичный аргумент работает для полей структур.

Другая проблема заключается в том, что некоторые структурные поля в настоящее время не скрыты при определении Py_LIMITED_API, даже если они являются частью ограниченного API.

По этим причинам мы рекомендуем протестировать расширение со всеми второстепенными версиями Python, которые оно поддерживает, и предпочтительно создавать его с самой низкой версией.

Мы также рекомендуем ознакомиться с документацией по всем используемым API, чтобы проверить, является ли он явной частью API с ограниченным доступом. Даже если определено Py_LIMITED_API, некоторые частные объявления отображаются по техническим причинам (или даже непреднамеренно, как ошибки).

Также обратите внимание, что ограниченный API не обязательно стабилен: компиляция с Py_LIMITED_API с Python 3.8 означает, что расширение будет работать с Python 3.12, но оно не обязательно будет компилироваться с Python 3.12. В частности, некоторые части ограниченного API могут быть признаны устаревшими и удалены при условии, что стабильный ABI останется стабильным.

Соображения, касающиеся платформы

Стабильность ABI зависит не только от Python, но и от используемого компилятора, библиотек более низкого уровня и опций компилятора. Для целей Stable ABI эти детали определяют “платформу”. Обычно они зависят от типа операционной системы и архитектуры процессора

Каждый конкретный распространитель Python несет ответственность за то, чтобы все версии Python на конкретной платформе были созданы таким образом, чтобы не нарушать стабильный ABI. Это относится к версиям Windows и Mac OS от python.org и многих сторонних распространителей.

Содержимое ограниченного API

В настоящее время Limited API включает в себя следующие элементы:

Вернуться на верх