Новую версию Python многие разработчики ожидали с нетерпением. Кто-то и не ждал, поскольку вполне достаточно было возможностей прежней версии. Но Python 3.12 таки выпустили, сейчас стало известно, что эту ветку будут поддерживать полтора года, а потом для нее станут формировать исправления для устранения уязвимостей — в течение еще трех с половиной лет.
Кроме того, запущен процесс альфа-тестирования Python 3.13, где заявлен режим сборки CPython без глобальной блокировки интерпретатора (GIL, Global Interpreter Lock). Тестировать ветку будут в течение семи месяцев, исправляя ошибки и добавляя новые возможности. Затем еще три месяца — тестирование бета-версий и еще через два месяца появится пред-финальная версия. Но будет потом, а сейчас поговорим о том, что уже есть в руках — о Python 3.12.
Так что мы получили?
Понятно, что в течение года никто не сидел, сложа руки — в новой версии появилось много нового и интересного. Вот список наиболее заметных изменений:
- Улучшена эффективность использования ресурсов многоядерных систем за счет добавления поддержки изолированных субинтерпретаторов и отдельных глобальных блокировок (GIL, Global Interpreter Lock) для разных интерпретаторов внутри процесса (CPython позволяет в одном процессе выполнять запускать сразу несколько интерпретаторов). Правда, сейчас эта новинка доступна посредством C-API, а поддержка Python API будет добавлена в следующей ветке.
- Также добавлена поддержка подсистемы ядра Linux perf в интерпретаторе. Она дает возможность определять имена Python-функций при профилировании при помощи утилиты perf (ранее в трассировках определялись только имена Си-функций).
- Еще одно важное изменение — повышение информативности сообщений об обшибках. Кроме того теперь спектр исключений с предложением рекомендации по устранению опечаток расширен. Вот пример:
sys.version_info
NameError: name 'sys' is not defined. Did you forget to import 'sys'?
somethin = blech
NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
import a.y.z from b.y.z
SyntaxError: Did you mean to use 'from ... import ...' instead?
from collections import chainmap
ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
- Также продолжается активная работа по оптимизации производительности. Она понемногу движется и есть первые результаты — согласно анонсу производительность стала на 5% выше. Не бог весть что, но тоже неплохо. Повышения удалось добиться благодаря:
- Добавлении поддержки бинарного оптимизатора BOLT, который и повышает производительность на 1-5%.
- Добавлено inline-развёртывание списковых включений (comprehensions). Это нововведение дало возможность ускорить работу со списковыми включениями.
- Размер Unicode-объектов снизили на 8-16 байт.
- Увеличена скорсть операций с регулярными выражениями re.sub(), re.subn() и re.Pattern.
- Ускорено выполнение проверок isinstance() для некоторых протоколов — от 2 до 20 раз.
- Также ускорены функции tokenize.tokenize() и tokenize.generate_tokens().
- Предложен более компактный синтаксис аннотирования типов для обобщенных классов и функций. Вот пример:
def max[T](args: Iterable[T]) -> T:
...
class list[T]:
def __getitem__(self, index: int, /) -> T:
...
def append(self, element: T) -> None:
- Появился новый способ определения псевдонимов типов при помощи выражения type. Еще пример:
type Point = tuple[float, float]
type Point[T] = tuple[T, T]
- Также в модуле typing добавлен новый декоратор override. Он информирует системы проверки типов о том, что метод в подклассе предназначен для переопределения метода или атрибута в суперклассе. И еще один пример:
class Base:
def log_status(self) -> None:
...
class Sub(Base):
@override
def log_status(self) -> None: # Ok, переопределяет Base.log_status
...
@override
def done(self) -> None: # Система проверки типов выявит ошибку
…
- В новой версии увеличена гибкость разбора f-строк (форматируемые литералы с префиксом 'f'), что открыло новые возможности, включая возможность указаний любых допустимых для Python выражений, включая многострочные выражения, комментарии, обратные слэши и escape-последовательности для Unicode. Во внутренней строке можно повторно использовать двойные кавычки, не применяя одинарные. А еще увеличена информативность сообщений в f-строках, в которых теперь указывается точное место в строке, вызвавшее ошибку. Вот пример:
print(f"This is the playlist: {"n".join(songs)}")
print(f"This is the playlist: {"N{BLACK HEART SUIT}".join(songs)}")
print(f"This is the playlist: {", ".join([
... 'Take me back to Eden', # My, my, those eyes like fire
... 'Alkaline', # Not acid nor alkaline
... 'Ascensionism' # Take to the broken skies at last
... ])}")
- Улучшена и безопасность. Так, встроенные реализации алгоритмов SHA1, SHA3, SHA2-384, SHA2-512 и MD5 в hashlib заменены на формально верифицированные варианты от проекта HACL* (встроенные реализации применяются только если отсутствует OpenSSL).
- Добавлена защита от переполнения стека в Cpython.
- В модуле pathlib.Path реализована поддержка подклассов, а в модуле os теперь расширена поддержка Windows. В частности, для этой ОС добавлена поддержка методов os.listdrives(), os.listvolumes() и os.listmounts(), а также повышена точность os.stat() и os.lstat().
- Кром того, в модули sqlite3 и uuid добавлены интерфейсы командной строки («python -m sqlite3» и «python -m uuid»).
- Кроме новых возможностей разработчики решили почистить некоторые старые, которые уже не нужны. В частности, убраны модули asynchat, asyncore, smtpd, imp и distutils (модуль distutils можно использовать из пакета setuptools). Убраны устаревшие методы в unittest. Избавились и от устаревших и некорректно работающих функций, классов и методов. В первую очередь, это locale.format(), io.OpenWrapper, ssl.RAND_pseudo_bytes(), ElementTree.Element.copy(), hashlib.pbkdf2_hmac(), gzip.GzipFile.
- Удалена поддержка таких браузеров, как Grail, Mosaic, Netscape, Galeon, Skipstone, Iceape, Firebird, и Firefox до версии 36.
Другие полезные материалы
Автор: Aleksandr