Выпуск языка программирования Python 3.15
- Python 3.15 опубликован после года разработки; ветка будет поддерживаться полтора года, затем ещё три с половиной года получит исправления уязвимостей.
- UTF-8 стал кодировкой по умолчанию, а ключевое слово lazy позволяет откладывать загрузку модулей до первого обращения к ним.
- Экспериментальный JIT ускорил тесты pyperformance в среднем на 11–12% на macOS AArch64 и на 7–8% на Linux x86_64.
Почему это важно: Файлы .start решают проблему отслеживания скрытого выполнения кода, возможного при использовании .pth-файлов.
После года разработки опубликован значительный выпуск языка программирования Python 3.15. Среди изменений: включение по умолчанию UTF-8, отложенная загрузка модулей, оптимизация экспериментального JIT-компилятора, типы frozendict и sentinel, файлы конфигурации для инициализации при запуске, расширение возможностей для профилирования, сборка в режиме »-fno-omit-frame-pointer» и встроенная текстовая игра «whatsnewt». Новая ветка будет поддерживаться в течение полутора лет, после чего ещё три с половиной года для неё будут формироваться исправления с устранением уязвимостей.
Среди новшеств, добавленных в Python 3.15 (1, 2, 3):
Модернизирован экспериментальный JIT-компилятор, который теперь позволяет добиться в среднем ускорения на 11–12% на платформе macOS AArch64 и на 7–8% на платформе x86_64 Linux в тестах pyperformance по сравнению со стандартным интерпретатором. При этом в отдельных тестах при включении JIT изменение производительности варьируется от ускорения на более чем 100%, до замедления на 15%. Помимо оптимизации производительности и улучшения генерации машинного кода в новой версии в JIT переработан механизм трассировки, который теперь учитывает реальные последовательности выполнения кода, а не только их прогнозирует, что позволило значительно расширить поддержку операций на уровне байткода. Осуществлён переход на ветку LLVM 21. В генерируемом коде некоторые операции со стеком заменены на работу с использованием регистров CPU. Добавлена поддержка раскрутки стека (unwinding) для GDB и GNU backtrace ().
В качестве кодировки по умолчанию задействована UTF-8, независимо от системы в которой выполняется код. Все операции ввода/вывода теперь обрабатывают текстовые данные как последовательности UTF-8, если явно не указана кодировка. Для использования параметров текущей локали или иной кодировки следует указывать аргумент «encoding» (например, «open ('test.txt', encoding='locale')»). Отключить режим UTF-8 на уровне интерпретатора можно через опцию командной строки »-X utf8=0» или переменную окружения «PYTHONUTF8=0».
- Добавлено ключевое слово «lazy» для отложенной загрузки модулей, при помощи которой можно ускорить запуск приложений с большим числом зависимостей. При отложенной загрузке модули загружаются непосредственно перед первым обращением к импортируемым именам в коде. До фактической загрузки для модулей создаётся легковесный прокси-объект «types.LazyImportType», отслеживающий обращение к модулям. В случае проблем с загрузкой модуля, например, если модуль не найден, исключение генерируется в момент попытки первого использования, а не во время импорта. Для принудительного отключения отложенной загрузки предусмотрена опция командной строки »-X lazy_imports» и переменная окружения PYTHON_LAZY_IMPORTS, а также функции sys.set_lazy_imports () и sys.get_lazy_imports (). Для выборочной фильтрации модулей, к которым применяется отложенная загрузка, добавлена функция sys.set_lazy_imports_filter ().
lazy import json lazy from pathlib import Path print("Starting up...") # будет запущено не дожидаясь импорта json и pathlib. data = json.loads('{"key": "value"}') # перед вызовом будет импортирован модуль json p = Path(".") # перед вызовом будет импортирован модуль pathlib Добавлен встроенный тип sentinel для создания уникальных строковых объектов, значения которых не повторяются, при копировании сохраняют идентичность и поддерживают сериализацию.
Добавлен встроенный тип frozendict, позволяющий создавать неизменяемые словари, которые можно инициализировать набором значений в момент создания объектов, но нельзя дополнять и изменять в процессе работы. Объекты с типом frozendict сохраняют порядок вставки элементов и могут хэшироваться для использования в качестве ключей в словарях.
- Добавлена возможность распаковки списочных включений (comprehensions) для списков, множеств, словарей и выражений-генераторов, используя операторы »*» и »**» для совмещения произвольного числа словарей или итерируемых объектов в одну плоскую структуру.
››› lists = [[1, 2], [3, 4], [5]] ››› [*L for L in lists] # эквивалентно указанию "[x for L in lists for x in L]" [1, 2, 3, 4, 5] ››› sets = [{1, 2}, {2, 3}, {3, 4}] ››› {*s for s in sets} # эквивалентно "{x for s in sets for x in s}" {1, 2, 3, 4} ››› dicts = [{'a': 1}, {'b': 2}, {'a': 3}] ››› {**d for d in dicts} # эквивалентно "{k: v for d in dicts for k,v in d.items()}" {'a': 3, 'b': 2} ››› gen = (*L for L in lists) # эквивалентно "(x for L in lists for x in L)" ››› list(gen) [1, 2, 3, 4, 5] Добавлена возможность определения файлов конфигурации для безопасной инициализации пакетов при запуске интерпретатора Python, позволяющих использовать .start-файлы вместо .pth-файлов для выполнения кода на стадии до выполнения запускаемого содержимого. В .start-файлах указываются лишь точки входа в формате pkg.mod: callable, на основе которых Python находит и вызывает указанные функции без аргументов. Подобный подход решает проблему с отслеживанием скрытого выполнения кода при использовании файлов .pth, допускающих выполнение произвольного кода при запуске.
- Улучшен вывод сообщений об ошибках. Реализован вывод рекомендаций при попытке обратиться к несуществующему атрибуту или удалить его. Например, интерпретатор даст знать, если атрибут отсутствует в объекте, но имеется во вложенном объекте или свойстве.
При обнаружении несуществующего типа, имеющегося в JavaScript, Java, Ruby или C#, интерпретатор предложит эквивалент для Python.
››› print(container.area) ... AttributeError: 'Container' object has no attribute 'area'. Did you mean '.inner.area' instead of '.area'? ››› 'hello'.toUpperCase() ... AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper'?
Добавлен отдельный модуль profiling для доступа ко всем встроенным возможностям профилирования кода в одном пространстве имён (profiling.tracing и profiling.sampling). Реализован новый статистический профилировщик Tachyon (profiling.sampling), позволяющий анализировать производительность с практически нулевыми накладными расходами и поддерживающий профилирование на уровнях байткода и сопрограмм (async/await). В отличие от профилировщика profiling.tracing, в profiling.sampling периодически оценивается состояние стека вызовов, а не анализируется каждый вызов функции.
- В модуле typing расширены возможности аннотирования типов при помощи классов TypedDict и TypeForm. В TypedDict добавлена поддержка аргументов closed и extra_items для более строгого контроля над структурой словаря. В TypeForm предложена новая форма аннотирования значений, связанных с типами (например, «int», «str | None», классы TypedDict и «list[int]»).
from typing import Any, TypeForm def cast[T](typ: TypeForm[T], value: Any) -> T: ...
В C API добавлен набор функций PyBytesWriter_* для создания бинарных объектов при разработке расширений на языке Си. Новый API позволяет добавлять данные в уже созданный байтовый буфер и обеспечивает автоматическое выделение памяти и изменение размера буфера. В C API также стабилизирован ABI для сборок без глобальной блокировки интерпретатора (GIL) и реализована защита от проблем, возникающих при завершении работы интерпретатора во время работы многопоточных C-расширений.
При сборке активированы флаги »-fno-omit-frame-pointer» и »-mno-omit-leaf-frame-pointer», включающие использование процессорного регистра %rbp в качестве базового указателя на кадр стека, содержащий адреса возврата и переменные функции (frame pointer). Использование указателя на кадры стека позволяет использовать дополнительные возможности для трассировки и профилирования системы.
Добавлена встроенная игра с текстовым интерфейсом, знакомящая разработчика с новыми возможностями Python 3.15. В игре предложено 18 головоломок, связанных с новшествами Python 3.15, для решения которых требуется написать и запустить код, использующий эти новшества. Для запуска игры следует выполнить команду «uvx --python 3.15 whatsnewt».
Дополнительно можно отметить начало альфа-тестирования ветки Python 3.16, которая будет находиться на стадии альфа-выпусков в течение семи месяцев, во время которых будут добавляться новые возможности и производиться исправление ошибок (в соответствии с новым графиком разработки работа над новой веткой начинается за пять месяцев до релиза предыдущей ветки и к моменту очередного релиза достигает стадии альфа-тестирования). После этого в течение трёх месяцев будет проводиться тестирование бета-версий, во время которого добавление новых возможностей будет запрещено и всё внимание будет уделяться исправлению ошибок. Последние два месяца перед релизом ветка будет находиться на стадии кандидата в релизы, на которой будет выполнена финальная стабилизация.
Источник: http://www.opennet.ru/opennews/art.shtml? num=66438
© OpenNet
