Эта статья — мой разбор официальных заметок о релизе. Для тех, кто любит копаться в первоисточниках и не боится простыней текста на английском — вот ссылка на официальный changelog.
Выход Python 3.14 запланирован на октябрь 2025. Python активно качает мускулы в сторону производительности и настоящего параллелизма.
Давайте разберемся, что же такого важного планируют в этой версии.
Главное событие: Производительность и конец эпохи GIL?
C версии 3.14 удаление GIL стало официальной стратегией. Несколько ключевых PEP направлены именно на то, чтобы Python мог эффективно работать на многоядерных процессорах.
PEP 779: Free-threaded Python — это официально
Самая громкая новость: сборка Python без GIL (free-threaded) теперь официально поддерживается. Это больше не экспериментальная фича. Что это значит на практике?
- Начало конца GIL: Мы вступаем в фазу, где free-threaded сборка — это поддерживаемая, но все еще опциональная возможность. Переход к ней как к сборке по умолчанию — вопрос будущего, но вектор движения задан четко.
- Цена свободы: За настоящий параллелизм приходится платить. В однопоточных сценариях производительность free-threaded сборки пока что на 5-10% ниже, чем у классической сборки с GIL. Но это та цена, которую многие готовы заплатить за возможность распараллеливать задачи без костылей в виде
multiprocessing
.
Разработчики ядра уверены в выбранном пути, а сообщество активно работает над адаптацией библиотек.
PEP 734: Множественные интерпретаторы в стандартной библиотеке
Еще один мощный удар по ограничениям GIL. Возможность запускать несколько изолированных интерпретаторов в одном процессе существует в C-API уже лет 20, но только сейчас она стала доступна напрямую из Python через новый модуль concurrent.interpreters
.
[!NOTE] Думайте об этом так: изоляция как у
multiprocessing
, но эффективность как уthreading
.
Это открывает дорогу к двум вещам:
- Настоящий многоядерный параллелизм: Интерпретаторы достаточно изолированы, чтобы работать параллельно, не упираясь в один GIL.
- Новые модели конкурентности: Можно реализовывать подходы вроде модели акторов или CSP, популярные в Go или Erlang, где потоки общаются через передачу данных, а не через общую память.
Конечно, есть и ограничения:
- Запуск интерпретаторов пока не оптимизирован.
- Потребление памяти выше необходимого.
- Мало опций для "честного" шаринга данных между интерпретаторами (кроме
memoryview
). - Многие сторонние C-расширения еще не готовы к такому режиму.
Тем не менее, для CPU-емких задач это революционная возможность. В комплекте идет и новый concurrent.futures.InterpreterPoolExecutor
.
Новый интерпретатор с хвостовыми вызовами
В CPython добавили новый тип внутреннего интерпретатора. Вместо гигантского switch-case
для опкодов он использует хвостовые вызовы между небольшими C-функциями. На новых компиляторах (пока что Clang 19+) это дает заметный прирост производительности — в среднем 3-5% на стандартных бенчмарках.
[!WARNING] Это не оптимизация хвостовых вызовов в вашем Python-коде (рекурсия по-прежнему не оптимизируется). Это внутреннее изменение CPython.
Экспериментальный JIT-компилятор
Официальные сборки для macOS и Windows теперь включают экспериментальный JIT-компилятор. Включается он переменной окружения PYTHON_JIT=1
. Пока это очень ранняя стадия, и прирост производительности нестабилен (от -10% до +20%), но это явный знак, куда движется CPython.
Ключевые изменения в языке и синтаксисе
Кроме производительности, есть и несколько очень интересных нововведений, с которыми столкнется каждый.
PEP 750: Template Strings (t-строки)
Это обобщение f-строк. Если f-строка сразу вычисляется в str
, то t-строка, с префиксом t
, вычисляется в специальный объект string.templatelib.Template
.
from string.templatelib import Template, Interpolation
name = "World"
template: Template = t"Hello {name}"
Зачем это нужно? Этот Template
объект хранит структуру строки: где статические части, а где подстановки. Это позволяет писать "умные" обработчики шаблонов. Самый очевидный пример — безопасная генерация HTML.
# Представим, что у нас есть такая функция
def html(template: Template) -> str:
# ... логика экранирования ...
...
evil = "<script>alert('evil')</script>"
template = t"<p>{evil}</p>"
# html() видит, что evil - это подстановка, и экранирует ее
assert html(template) == "<p><script>alert('evil')</script></p>"
Сравните с f-строкой, которая бы просто подставила вредоносный код. T-строки открывают двери для безопасных SQL-запросов, генерации CSS, легковесных DSL и многого другого прямо "из коробки".
PEP 649 и 749: Отложенное вычисление аннотаций
Аннотации типов теперь не вычисляются в момент определения функции или класса. Они сохраняются в специальном виде и вычисляются только по требованию (например, при вызове get_annotations
).
Что это дает?
- Производительность: Определение функций с аннотациями становится быстрее.
- Больше не нужны кавычки для forward-ссылок: Наконец-то можно писать
def func(arg: Node) -> Node:
без оборачиванияNode
в строки, даже если классNode
определен ниже. - Конец
from __future__ import annotations
: Этот импорт теперь считается устаревшим и в будущем будет удален.
Для интроспекции аннотаций появился новый модуль annotationlib
с функцией get_annotations()
, которая позволяет получать аннотации в разных форматах (вычисленные значения, строковые представления и т.д.).
PEP 758: except и except* без скобок
Небольшое, но приятное улучшение. Если вы ловите несколько исключений и не используете as
, скобки теперь можно опустить.
# Раньше было обязательно
try:
...
except (TimeoutError, ConnectionRefusedError):
...
# Теперь можно так
try:
...
except TimeoutError, ConnectionRefusedError:
...
Это работает и для except*
.
Новые инструменты и модули
PEP 784: Zstandard в стандартной библиотеке
В Python добавили поддержку высокоэффективного и быстрого алгоритма сжатия Zstandard. Появился новый пакет compression
, который объединяет модули для работы со сжатием, и внутри него — compression.zstd
.
from compression import zstd
import math
data = str(math.pi).encode() * 20
compressed = zstd.compress(data)
Поддержка zstd также добавлена в tarfile
, zipfile
и shutil
.
PEP 768: Безопасный внешний отладчик и удаленный PDB
Появился новый интерфейс, который позволяет отладчикам и профилировщикам безопасно подключаться к уже запущенному Python-процессу без лишних накладных расходов.
Практическое применение, которое оценят многие: теперь pdb
можно подключить к работающему процессу по его PID.
python -m pdb -p 12345
Это невероятно мощный инструмент для отладки "зависших" или ведущих себя странно приложений в продакшене или на стейджинге.
Улучшенные сообщения об ошибках
Интерпретатор стал еще умнее и теперь подсказывает при опечатках в ключевых словах.
whille True:
pass
# SyntaxError: invalid syntax. Did you mean 'while'?
async def foo():
awaid fetch_data()
# SyntaxError: invalid syntax. Did you mean 'await'?
Другие заметные изменения
map(strict=True)
: Встроенная функцияmap()
получила флагstrict
(как уzip()
), который проверяет, что все итерируемые объекты имеют одинаковую длину.- Новые методы
pathlib.Path
: Добавлены методыcopy()
,copy_into()
,move()
иmove_into()
для рекурсивного копирования и перемещения файлов/директорий. - UUID v6, v7, v8: Добавлена поддержка новых версий UUID, как указано в RFC 9562.
- Подсветка синтаксиса в REPL: Интерактивная консоль Python теперь по умолчанию подсвечивает синтаксис.
os.path.realpath(strict=os.path.ALLOW_MISSING)
: Новый режим дляrealpath
, который разрешает отсутствующие компоненты в пути, но все равно разрешает симлинки.
Что пора перестать использовать: Депрекейты и удаления
from __future__ import annotations
: Официально устарел.asyncio
полиси: Вся система политик (get_event_loop_policy
,set_event_loop_policy
) устарела в пользуasyncio.run(loop_factory=...)
.asyncio.get_event_loop()
: Неявное создание цикла событий удалено. Если цикл не запущен, вызов этой функции теперь вызоветRuntimeError
.- Удалены старые узлы
ast
:ast.Num
,ast.Str
,ast.Bytes
иast.NameConstant
окончательно удалены. Используйтеast.Constant
. Если вы писали свои визиторы AST, вам придется их обновить. codecs.open()
: Устарел. Используйте встроенныйopen()
.
Выводы
Язык делает решительный шаг в мир высокопроизводительных вычислений и настоящего параллелизма. Официальная поддержка free-threaded режима, множественные интерпретаторы и экспериментальный JIT — все это кирпичики в фундаменте будущего Python, где он сможет на равных конкурировать с другими языками в CPU-bound задачах.