CPython ABI: что означают теги в именах wheel-файлов и почему это важно
Когда pip устанавливает пакет, он выбирает нужный wheel по имени файла. Разобраться в этих тегах — значит понять почему одни пакеты устанавливаются, а другие нет.
📦 Анатомия имени wheel-файла
cryptography-48.0.0-cp311-abi3-macosx_10_9_universal2.whl
↑ ↑ ↑ ↑
версия python abi платформа
· py3-none-any — чистый Python, работает везде
· cp314-cp314 — только CPython 3.14, версия-специфичный ABI
· cp311-abi3 — CPython 3.11+, стабильный ABI (работает на 3.11 и новее)
🔤 API vs ABI — в чём разница
API — что написано в заголовочном файле (`Python.h`): сигнатуры функций, макросы, типы.
ABI — что реально в скомпилированном бинарнике: имена символов, смещения полей в структурах, размеры. Две библиотеки с разными ABI несовместимы — и падение может быть молчаливым.
🔑 Три уровня ABI в Python
· cp3XY — версия-специфичный ABI. Один wheel на каждый Python. Нужно выпускать новый каждый год.
· abi3 — стабильный ABI. Один wheel для Python 3.X и всех новых версий. Но не работает на free-threaded Python.
· cp3XYt — ABI free-threaded Python (без GIL). Отдельные теги: cp313t, cp314t.
⚡ Почему free-threaded Python сломал abi3
В GIL-версии структура PyObject выглядела так:
struct PyObject {
Py_ssize_t ob_refcnt; // байт 0
PyTypeObject *ob_type; // байт 8
};
В free-threaded версии (Python 3.14+):
struct PyObject {
uintptr_t ob_tid; // id потока-владельца
uint16_t ob_flags;
PyMutex ob_mutex; // per-object lock
uint8_t ob_gc_bits;
uint32_t ob_ref_local; // локальный счётчик ссылок
Py_ssize_t ob_ref_shared; // атомарный счётчик
PyTypeObject *ob_type; // теперь на другом смещении!
};
ob_type переехал — wheel скомпилированный под старую раскладку прочитает не те байты. Crash или тихая порча памяти.
🆕 Python 3.15: новый стабильный ABI abi3t
PyObject стал непрозрачным (opaque struct) — нельзя обращаться к полям напрямую, только через функции API. Это скрывает детали реализации и делает возможным один wheel для обеих сборок.
Стратегия для мейнтейнеров:
Python 3.12-3.13 → cp312-abi3 (один wheel)
Python 3.14 → + cp314t (free-threaded)
Python 3.15+ → cp315-abi3.abi3t (оба в одном)
Итого: тег в имени wheel = гарантия совместимости на уровне бинарного кода.
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека питониста
#буст
1.6K ·