
Python 3.15 — революция или эволюция?
Мне нравится, куда движется Python. Команда CPython в последнее время выкатывает очень много крутых вещей.
Пробежав на ходу релиз-ноуты 3.15, я сначала подумал, что разрабы, как обычно, добавили изменений ради изменений. Но нет, я глубоко заблуждался.
Changelog
Основные улучшения и изменения в Python 3.15:
- улучшения интерпретатора:
- добавлен встроенный тип sentinel;
- Python теперь использует UTF-8 в качестве кодировки по умолчанию;
- распаковка в генераторах (comprehensions);
- явный отложенный импорт для ускорения запуска;
- добавлен встроенный тип frozendict;
- файлы конфигурации запуска пакетов ;
- JIT-компилятор Python всё ещё находится на экспериментальной стадии, однако в версии 3.15 он стал значительно быстрее. Ожидается, что в среде Linux (x86-64) JIT-компилятор обеспечит прирост производительности в среднем (по геометрическому среднему) на 7–8% по сравнению со стандартным интерпретатором Python. Сообщается, что на системах macOS с архитектурой AArch64 JIT-компилятор работает на 11–12% быстрее интерпретатора с поддержкой tail-calling.
- значительные улучшения стандартной библиотеки:
- специализированный пакет для организации инструментов профилирования в Python;
- Tachyon — высокочастотный статистический сэмплирующий профилировщик.
- новые возможности системы типов:
- TypedDict с типизированными дополнительными элементами;
- аннотирование форм типов с помощью TypeForm;
- непересекающиеся базовые классы в системе типов.
- улучшения C API:
- новый C API PyBytesWriter для создания объектов bytes в Python;
- защита от финализации в C API;
- стабильный ABI для сборок с поддержкой free-threading и соответствующий C API.
- изменения в процессе сборки: указатели на кадры (frame pointers) включены по умолчанию, что улучшает возможности системного мониторинга и отладки;
- изменения в выпуске:
- официальные 64-битные бинарные файлы для Windows теперь используют интерпретатор с поддержкой tail-calling;
- официальные бинарные файлы для macOS теперь по умолчанию включают поддержку free-threading.
- текстовый квест от разработчика Barry Warsaw, посвященный новинкам Python 3.15
Источник: Хабр
Вряд ли кто-то зайдёт в этот блог ради скопированного ченджлога, поэтому пройдусь по пунктам, которые показались мне самыми важными.
JIT
Если отбросить неинтересную рядовому быдлокодеру системщину, первое, за что цепляется глаз, это JIT. Он всё ещё экспериментальный, но видно, что core-разрабы потихоньку доводят его до ума: +7–8% на Linux x86-64 и +11–12% на маках с AArch64 уже не спишешь на погрешность. Насколько финальная реализация ускорит питон в целом, думаю, объяснять не надо.
Free-threading
Но весомее JIT только новости про free-threading. Официальный установщик для macOS теперь по умолчанию ставит free-threaded-сборку рядом с обычной, а у C-расширений появился стабильный ABI под неё. GIL пока никуда не делся: дефолтный интерпретатор по-прежнему с ним. Но, по-моему, это уже точка невозврата: сборка без GIL перестала быть галочкой для энтузиастов и едет к людям из коробки.
Python всё больше превращается во «взрослый» язык (хотя он вроде всегда им был). В том смысле, что спустя столько лет фактически однопоточный ЯП (привет, GIL) почти закончил превращаться в полноценно многопоточный. Ещё немного, и для CPU-bound нагрузки не придётся изгаляться: писать отдельные воркеры с очередями, плодить тяжёлые процессы и через какое-то время ловить OOM kill. Весь этот ужас потихоньку уходит на задворки истории. В общем, этот релиз -эволюция с точкой невозврата. Сил и компетенции команде CPython, они делают очень крутые вещи.
Профайлер
Нечестно было бы пройти мимо нового профайлера. cProfile в стандартной библиотеке был всегда, но теперь рядом с ним появился Tachyon: сэмплирующий профайлер, который цепляется к уже запущенному процессу по PID, почти его не тормозит и сам рисует flame graph. Раньше за таким ходили к py-spy. QoL разработчика растёт ощутимо. Спасибо, что завезли (через 20 лет).
UTF-8 по умолчанию
open() без encoding больше не подставляет системную кодировку. Гудбай, кракозябры на винде)
sentinel
Глянул, прикольная вещь. Из кода уйдёт тонна костылей вроде NOT_GIVEN из OpenAI SDK. Удивляет только, что на согласование такой, казалось бы, мелочи ушло пять лет: PEP 661 предложили ещё в 2021-м (!).
Lazy imports
Крутейшая вещь. Импорт модуля откладывается до первого обращения к нему: запуск ускоряется, а цена импорта переезжает в момент первого использования. Туда же переезжают и ошибки: если модуля нет, упадёт не на старте, а там, где до него впервые дотронулись.
lazy import json # модуль ещё не загружен, json пока прокси-объект
data = json.loads('{"key": "value"}') # а вот здесь происходит реальный импортfrozendict
И последняя из приятностей. Наконец-то хешируемые словари (если ключи и значения сами хешируемые). Аллилуйя!
На этом всё. Разбирать каждую строчку ченджлога не хочу, да и многое там не особо интересно.
Спасибо за прочтение!
