PyPy 8.0 приносит поддержку Python 3.12, но настоящая проверка — экосистема расширений
PyPy 8.0 делает важный шаг к совместимости: получает бета-поддержку Python 3.12, переходит на glibc 2.28 и готовится работать с колесами CPython `cp312-abi3`. Но это еще не означает, что любой пакет можно без изменений перенести на PyPy.
PyPy 8.0 стоит внимательно рассмотреть по причине, которую легко не заметить в номере версии. Проект выпускает не просто еще один быстрый интерпретатор Python. Он пытается сократить одну из давних издержек выбора PyPy: разрыв между совместимой языковой средой выполнения и огромным миром пакетов, зависящих от C API CPython.

Выпуск опубликован 19 сентября 2026 года. Он добавляет интерпретатор Python 3.12 бета-качества, продолжает поставлять варианты для Python 3.11 и Python 2.7, а также меняет базовую версию Linux-сборок на glibc 2.28. Еще важнее то, что команда PyPy считает: новая модель объектов Python 3.12 содержит необходимые компоненты для использования колес cp312-abi3, собранных для ограниченного API CPython. Оставшаяся работа касается не только самого PyPy: механизм импорта, установщики и системы сборки пакетов должны согласовать, что такие колеса действительно подходят.
Поэтому PyPy 8.0 удобен для экспериментов и целевых производственных испытаний. Это не универсальная инструкция заменить CPython. Практический вопрос звучит уже и полезнее: сможет ли набор зависимостей вашего приложения работать на PyPy 8.0 без сборки из исходников, неподдерживаемых нативных расширений и предположений о среде выполнения, которые верны только для CPython?
Что изменилось в PyPy 8.0
PyPy называет версию 8.0.0 крупным выпуском с тремя линиями интерпретатора: PyPy2.7, PyPy3.11 и PyPy3.12. Реализация Python 3.12 прямо помечена как бета, поэтому ее стоит воспринимать как платформу для проверки совместимости, а не как автоматическую замену зрелого развертывания CPython. Линия Python 3.11 остается доступной, однако проект сообщает, что при отсутствии проблем безопасности это, вероятно, последний его выпуск с поддержкой Python 3.11.
В официальной заметке о выпуске названы две инфраструктурные причины смены мажорной версии. Во-первых, Linux-билдботы теперь используют образы manylinux 2.28 на базе AlmaLinux 8 и glibc 2.28, а GCC 14 заменяет старую цепочку инструментов GCC 5. Получившиеся скомпилированные архивы требуют glibc 2.28 или новее. Для многих современных дистрибутивов это разумная граница, но все же ограничение развертывания: старые корпоративные образы, устаревшие устройства и тщательно зафиксированные базы контейнеров нужно проверять, а не считать совместимыми по умолчанию.
Во-вторых, PyPy изменил способ представления своего внутреннего объекта для C-расширений. В более ранних версиях специфичное для PyPy расширение структуры PyObject показывалось таким образом, что она отличалась от раскладки CPython. В версии 8.0 поле PyPy скрыто в префиксе перед указателем, который передается модулям C-расширений. Заявленная цель — дать PyPy возможность использовать колеса cp312-abi3, созданные для CPython 3.12 и последующих версий, если эти колеса действительно остаются внутри ограниченного API.
Обновлена и генерация кода RPython. Теперь PyPy использует вычисляемые переходы и более агрессивное встраивание в сгенерированном коде интерпретатора. Команда откровенно признает, что прирост производительности оказался не таким большим, как ожидалось. Это существенно: ценность выпуска нельзя свести к одному заголовку с результатами бенчмарка. Более важная работа ведется в упаковке, совместимости и снижении стоимости поддержки еще одного интерпретатора.
PyPy также отказался от внутреннего бэкенда HPy. В заметке о выпуске сказано, что дескрипторный подход проекта HPy был полезным прототипом, но не получил достаточной поддержки, чтобы стать новым стандартом. Код HPy остается в дереве PyPy и может быть включен параметром сборки, однако больше не является направлением по умолчанию. Для авторов расширений это означает, что непосредственный путь к совместимости по-прежнему проходит через существующую границу C API, CFFI или логику сборки, специфичную для интерпретатора, а не через широкую миграцию на HPy, которая устранила бы прежние компромиссы.
Почему важен cp312-abi3
Python-пакеты распространяются по-разному. Пакет, написанный только на Python, часто может использовать колесо py3-none-any и работать в CPython, PyPy или другой реализации Python 3. Пакет с кодом на C, C++ или Rust устроен иначе. Его колесо может быть привязано к конкретному интерпретатору, ABI, операционной системе и архитектуре процессора. Имя файла кодирует эти заявления о совместимости.
Python Packaging User Guide описывает abi3 как тег для расширений, собранных с использованием стабильного ABI CPython. Стабильный ABI — ограниченное подмножество C API, рассчитанное на сохранение работоспособности между версиями Python 3. В привычном сценарии пакет может распространять по одному колесу cp39-abi3 для каждой комбинации операционной системы и архитектуры вместо отдельной пересборки расширения для каждой минорной версии CPython.
Эта выгода автоматически не распространяется на PyPy. Метка cp312-abi3 заявляет о совместимости со стабильным ABI CPython. PyPy должен предоставить совместимую реализацию нужного интерфейса, а инструменты упаковки должны учитывать колесо во время разрешения зависимостей. В выпуске PyPy 8.0 сказано, что заголовки C и экспортируемые функции теперь согласованы с ограниченным API CPython для Python 3.12, но также названы два важных недостающих элемента: механизм импорта должен принимать общие библиотеки abi3.so как допустимые для PyPy, а инструменты вроде pip и uv должны распознавать такие колеса как кандидатов.
Именно здесь находится центр выпуска. Изменение на уровне среды выполнения может быть технически корректным, но почти ничего не дать пользователям, если индекс пакетов, установщик, бэкенд сборки и проект расширения не приняли одинаковую трактовку. Цепочка совместимости выглядит примерно так:
Заголовки C и загрузчик PyPy
↓
проект расширения собирается внутри ограниченного API
↓
метаданные колеса заявляют совместимый ABI
↓
установщик рассматривает колесо для PyPy
↓
приложение проходит проверки среды выполнения и поведения
Сбой на любом этапе возвращает пользователя к сборке из исходников, колесу для конкретной версии PyPy, чисто Python-реализации или несовместимому бинарному файлу. PyPy 8.0 продвигает первую часть этой цепочки. Остальные по-прежнему нужно проверять.
Оговорка о совместимости остается существенной
Самая опасная ошибка — прочитать «поддерживает колеса CPython 3.12 abi3» как «поддерживает все популярные пакеты Python». Многие пакеты не используют ограниченный API. Они могут обращаться к внутренним деталям CPython, зависеть от поведения подсчета ссылок, предполагать определенную раскладку объектов или поставлять сгенерированный код, проверенный только на CPython. Колесо может иметь метку, похожую на переносимую, но его код все равно опираться на предположения, которые PyPy не способен воспроизвести точно.
PyPy давно предоставляет слой совместимости cpyext, эмулирующий значительную часть C API CPython. Благодаря этому возможен большой объем кода расширений, но эмуляция имеет цену. PyPy использует трассирующий сборщик мусора, а не реализацию CPython на подсчете ссылок. Счетчики ссылок, видимые через слой совместимости, не обязательно отражают то же состояние, которое C-расширение увидело бы в CPython. К коду, использующему счетчики ссылок как сигнал времени жизни объекта, выполняющему тонкую работу при освобождении памяти или зависящему от внутренних деталей объектов CPython, нужно относиться особенно осторожно.
Документация Cython указывает на близкую проблему: Cython способен адаптировать сгенерированный код для PyPy, но различия в эмулируемом C API сохраняются. Авторам расширений рекомендуется по возможности полагаться на сгенерированную Cython-обработку, а не напрямую использовать низкоуровневое поведение C API без ясной причины. Это не обвинение именно PyPy. Скорее напоминание: стабильная поверхность языка и стабильная поверхность нативных расширений — разные инженерные задачи.
CFFI остается важной альтернативой для проектов, которым нужно поддерживать несколько реализаций Python. Команда PyPy отдельно просит сопровождающих библиотек, использующих C-расширения, рассмотреть вариант CFFI, который хорошо работает на PyPy. CFFI не делает каждую нативную зависимость переносимой автоматически, но способен убрать часть предположений, из-за которых расширение CPython трудно запустить в другом интерпретаторе.
Перед авторами расширений на Rust стоит похожий выбор. PyO3 поддерживает сборки для PyPy и предоставляет настройки для обнаружения реализации PyPy, однако его документация и комментарии в исходном коде по-прежнему рассматривают стабильный ABI прежде всего как путь, ориентированный на CPython. Поэтому Rust-проекту, которому нужны CPython и PyPy, следует явно собирать и тестировать обе цели. Нельзя выводить совместимость с PyPy только из того, что сборка CPython использует abi3.
Кому стоит попробовать PyPy 8.0 уже сейчас
Лучшие кандидаты — приложения с долгими циклами на Python, заметным объемом вычислений в чистом Python или сервисы, которым помогает трассирующий JIT PyPy после прогрева кода. Потенциальная выгода выглядит убедительнее, когда приложение много времени проводит на уровне Python и меньше ждет внутри нативных библиотек, уже выполняющих тяжелую работу.
PyPy также разумно использовать как тестовую платформу сопровождающим библиотек на чистом Python. Если пакет заявляет широкую совместимость с реализациями Python, добавление PyPy 8.0 в матрицу CI способно выявить предположения, незаметные при тестировании только на CPython. Особенно полезно это для библиотек, косвенно управляющих временем жизни объектов, активно использующих динамическую диспетчеризацию или обещающих поддержку альтернативных интерпретаторов.
Выпуск важен и для сопровождающих расширения. Проект, уже использующий Cython, CFFI или PyO3, может проверить на PyPy 8.0, действительно ли его граница абстракции переносима. Работа над cp312-abi3 дает конкретную цель для сотрудничества PyPy, авторов расширений и инструментов упаковки. Общий запрос «сделать PyPy лучше поддерживаемым» превращается в проверяемую последовательность: компилируется ли расширение, устанавливается ли колесо, импортируется ли оно и корректно ли ведет себя при сборке мусора и JIT-выполнении?
Командам, сопровождающим Python-сервисы, стоит действовать выборочно. Сервис с небольшим деревом зависимостей, сильными интеграционными тестами и нагрузкой, в которой преобладает код Python, подходит для пилота. Стек для анализа данных с несколькими крупными бинарными зависимостями, нативными драйверами баз данных, собственными модулями Cython и колесами от поставщиков — гораздо более рискованная первая цель. Такой стек со временем может заработать, но ожидаемая польза должна оправдывать поддержку еще одного пути интерпретатора.
Наименее убедительная причина попробовать PyPy 8.0 — сам номер версии, который больше номера версии CPython. Версия PyPy относится к собственной последовательности выпусков проекта; она не означает, что среда выполнения реализует Python 8. В этом выпуске релевантны Python 3.12 бета, Python 3.11 и Python 2.7.
Практический план оценки
Разумный тест начинается с инвентаризации, а не с бенчмарка. Зафиксируйте полный lock-файл и классифицируйте каждую зависимость как чисто Python-пакет, C-расширение, Rust-расширение, внешнюю общую библиотеку или пакет с известным путем, специфичным для интерпретатора. Результат покажет, где находится настоящая работа. Списка зависимостей верхнего уровня недостаточно: хрупкий пакет может находиться на несколько уровней ниже в графе.
Затем создайте отдельное окружение для PyPy 8.0 и установите зависимости обычным для проекта резолвером. Не устанавливайте заранее набор колес CPython и не считайте полученную среду показательной. Зафиксируйте, какие пакеты установились из колес, какие пришлось собирать из исходников, а какие были отвергнуты. Успешная установка — полезное свидетельство, но не вердикт о совместимости.
После этого тестовый набор должен выполняться как минимум в четырех режимах: чистый запуск, короткий функциональный прогон, длительная нагрузка и сценарий перезапуска или обновления. Длительный режим важен потому, что JIT PyPy нужно время для прогрева, а поведение сборщика мусора может не проявиться в небольшом запуске модульных тестов. Измеряйте время старта, пропускную способность после стабилизации, рост памяти, хвостовые задержки и момент, когда сервис становится полезным. Более быстрый внутренний цикл не обязательно означает лучшее развертывание, если основную стоимость определяют запуск или память.
Нативные границы требуют отдельных проверок. Протестируйте сериализацию, драйверы баз данных, обработку изображений или звука, криптографию, сжатие, численные ядра и любой код, передающий объекты Python через C или Rust. Запускайте тесты, принуждающие приложение к выделению памяти и сборке, а не только счастливые пути. Если приложение использует обратные вызовы, финализаторы, буферный протокол или координацию потоков, эти сценарии нужно включить явно. Именно здесь различия интерпретаторов чаще превращаются в эксплуатационные сбои, а не в простые предупреждения при установке.
Сохраняйте CPython как сравнительную базу. Цель не в том, чтобы доказать преимущество PyPy в каждом бенчмарке. Сравнивайте общий инженерный результат: надежность сборки, поведение холодного старта, память, пропускную способность, наблюдаемость, отладку, доступность колес и время, необходимое для поддержания двух путей интерпретатора. Для пакетной задачи, работающей часами, цена прогрева может быть несущественной. Для утилиты командной строки, запускаемой сотни раз в минуту, та же цена способна уничтожить выгоду.
Пользователям Linux нужно проверить границу glibc
Переход на glibc 2.28 легко пропустить, потому что его описывают как изменение инфраструктуры сборки. На деле это часть контракта поставки среды выполнения. На странице загрузки PyPy сказано, что текущие Linux-бинарники совместимы с manylinux 2.28 и новее, а Linux-сборки требуют glibc 2.28 или более свежую версию. Пользователей современных Ubuntu, Debian, Fedora и сопоставимых систем это вряд ли удивит. Тем, кто поддерживает старые дистрибутивы или минимальные образы, следует проверить условие напрямую.
Проще всего поймать проблему при сборке контейнера. Проверяйте ровно тот базовый образ, который используется в продакшене, а не более новый образ разработчика. Проверьте требования интерпретатора к общим библиотекам и запустите дымовые тесты приложения внутри этого образа. Если развертывание охватывает разные машины, проверяйте самый старый поддерживаемый узел. Бинарник PyPy, работающий на хосте сборки, но не на старом производственном хосте, нельзя считать успешным обновлением.
Проект также предупреждает, что его Linux-бинарники содержат OpenSSL, но не хранилище сертификатов. Документация по загрузке советует использовать хранилище сертификатов платформы или настроить SSL_CERT_FILE, например через пакет certifi. Это не уникальная особенность PyPy, однако именно такие операционные детали теряются, когда интерпретатор скачивается как самодостаточный архив. HTTPS-тесты должны входить в начальную проверку, особенно для инструментов, обращающихся к индексам пакетов, API или внутренним сервисам.
Скачайте, проверьте и изолируйте эксперимент
PyPy предоставляет предварительно скомпилированные архивы для нескольких платформ, включая Linux x86-64, Linux ARM64, Windows 64-bit и macOS на Apple Silicon и процессорах Intel. Проект публикует контрольные суммы архивов 8.0.0. Считайте эти суммы частью процесса установки: скачайте архив с официальных страниц проекта, проверьте его и запишите точную сборку интерпретатора в заметках эксперимента.
Не заменяйте системную команду python во время оценки выпуска. Используйте отдельное виртуальное окружение или явный путь к интерпретатору, сохраните существующее окружение CPython и сделайте выбор видимым в CI. Небольшой обертке или записи в матрице проще исчезнуть, чем машинной замене интерпретатора, которая незаметно изменит скрипты, задания сборки или конфигурации сервисов.
Проект сообщает, что сборка PyPy из исходников занимает много времени и требует значительных вычислительных ресурсов, поэтому большинству пользователей следует начинать с официальных бинарников. Сборка из исходников имеет смысл для сопровождающих дистрибутивов, участников разработки PyPy или команд с контролируемыми требованиями к цепочке инструментов. Для обычной оценки приложения это не самый короткий маршрут.
Что выпуск означает для инструментов упаковки
PyPy 8.0 показывает проблему координации, которую экосистема Python откладывала годами. Поддержку интерпретатора часто обсуждают так, будто это свойство одной среды выполнения, но выбор колеса — результат согласования между метаданными пакета, тегами установщика, бэкендом сборки, политикой индекса и реализацией, которая в итоге загружает бинарник. Формулировки самой команды PyPy ясно показывают: работа над механизмом импорта и такими инструментами, как pip и uv, еще продолжается.
Это дает сопровождающим пакеты конкретный способ помочь. Можно проверить расширение проекта на PyPy 3.12, выяснить, использует ли оно только ограниченный API, добавить задание PyPy в CI, опубликовать совместимое колесо при необходимости и сообщить о сбое с минимальным воспроизводимым примером. Сообщение «PyPy сломан» дает мало сигнала. Отчет «колесо cp312-abi3 устанавливается, но завершается с ошибкой, когда буфер освобождается после сборки мусора» уже содержит материал для исправления.
Это также напоминание о точности метаданных пакета. Чисто Python-дистрибутив должен использовать самый широкий правдивый тег. Скомпилированное расширение должно заявлять только тот ABI и те платформы, которые действительно проверены. Проект, собирающийся со стабильным ABI, но импортирующий приватные символы CPython, не достиг переносимости, которую обещает имя файла. Работа вокруг PyPy 8.0 принесет пользу только в том случае, если заявления пакетов станут точнее, а не просто оптимистичнее.
Альтернативы и дополнения
CPython остается выбором по умолчанию для максимальной совместимости пакетов, наиболее предсказуемого поведения нативных расширений и крупнейшего набора колес от поставщиков. Для многих приложений это правильное решение. Выбор PyPy — не моральное заявление о разнообразии реализаций Python, а решение о нагрузке и стоимости сопровождения.
Если цель — уменьшить трение зависимостей, сохранив привычную среду выполнения, полезнее может оказаться улучшение C-границы пакета, а не смена интерпретатора. CFFI, четко определенный ограниченный API, сгенерированные привязки и меньшее число зависимостей от деталей реализации способны повысить переносимость между CPython, PyPy и будущими средами выполнения. Для расширений Rust явные сборки под PyPy и условная компиляция могут быть надежнее, чем ожидание, что один артефакт, ориентированный на CPython, будет работать повсюду.
Если цель — максимальная скорость, сравнивайте реальное приложение с доступными вариантами. JIT PyPy может помочь долгим нагрузкам с большим объемом кода Python, но доминировать могут нативные библиотеки, ввод-вывод, сериализация, запуск и память. Тщательно оптимизированное развертывание CPython, другой алгоритм, скомпилированное расширение или изменение архитектуры процессов способны дать больший эффект. Сравнивать нужно всю программу, а не искусственный цикл.
Итог
PyPy 8.0 — заметный выпуск открытого ПО, потому что он атакует реальный барьер внедрения. Бета-поддержка Python 3.12 приближает проект к актуальной языковой экосистеме. Переход на glibc 2.28 дает Linux-бинарникам современную базу распространения. Новая модель объектов и запланированная поддержка cp312-abi3 могут уменьшить число пакетов, которым нужны отдельные сборки для PyPy.
Оговорка столь же важна: совместимость не завершена, пока установщики не выбирают эти колеса, загрузчик не принимает их, а приложения не выдерживают реальные нагрузки. Старые проблемы C-расширений, специфичных для CPython, предположений о подсчете ссылок, бинарных зависимостей и неравномерного покрытия тестами никуда не исчезли. PyPy 8.0 улучшает исходную позицию, но не устраняет граф зависимостей.
Разработчикам стоит испытать PyPy 8.0 на одной ограниченной нагрузке с фиксированным lock-файлом и сравнением с CPython. Если библиотека заявляет поддержку альтернативных интерпретаторов, добавьте PyPy в CI. Проверьте базовую версию glibc, контрольные суммы архивов, сертификаты HTTPS и каждую нативную зависимость. Поддержку Python 3.12 воспринимайте как бета-версию, а совместимость cp312-abi3 — как проект всей экосистемы, который еще продолжается.
Этого достаточно, чтобы выпуск стоило попробовать. Сильнейший аргумент в пользу PyPy никогда не заключался в том, что на него должна перейти каждая программа на Python. Он в том, что экосистеме Python нужна не одна серьезная реализация, а выбор реализации не должен превращать обычную упаковку в отдельный инженерный проект. PyPy 8.0 приближает эту цель, но следующий шаг зависит от сопровождающих библиотек и инструментов упаковки не меньше, чем от команды интерпретатора.
Источники
Фактическая основа материала — официальная заметка PyPy о выпуске v8.0.0, документация PyPy по загрузке и установке, опубликованные контрольные суммы и репозиторий pypy/pypy. Контекст по колесам и бинарным расширениям взят из Python Packaging User Guide, а сведения о переносе расширений — из документации Cython и руководства PyO3. Обсуждение выпуска на Hacker News приведено как дискуссионный материал, а не как самостоятельное подтверждение фактов.
Основные страницы: PyPy v8.0.0 release, Download and Install, Checksums, репозиторий PyPy, Platform compatibility tags, Packaging binary extensions, Porting Cython code to PyPy, Building and distribution в PyO3 и обсуждение выпуска.
Comments
Sign in to comment.
No comments yet.