Після року розробки представлений значний випуск мови програмування Python 3.9. Python 3.9 став першим випуском після переходу проекту на новий цикл підготовки та супроводу релізів. Нові значні випуски тепер формуватимуться щорічно, а коригувальні оновлення випускатимуться раз на два місяці. Кожна значна гілка підтримуватиметься протягом півтора року, після чого ще три з половиною роки для неї формуватимуться виправлення з усуненням уразливостей.
p align="justify"> Робота над новою гілкою тепер починається за п'ять місяців до релізу чергової гілки, тобто. одночасно з випуском Python 3.9 почалося альфа-тестування гілки Python 3.10. Гілка Python 3.10 перебуватиме на стадії альфа-випусків протягом семи місяців, під час яких будуть додаватися нові можливості та виправлятися помилки. Після цього протягом трьох місяців буде проводитися тестування бета-версій, під час якого додавання нових можливостей буде заборонено і вся увага приділятиметься виправленню помилок. Останні два місяці перед релізом гілка буде на стадії кандидата в релізи, на якій буде виконано фінальну стабілізацію.
У словниках, визначених за допомогою вбудованого класу dict, з'явилася підтримка операторів злиття "|" та оновлення «|=», які доповнюють методи {**d1, **d2} та dict.update, які раніше пропонувалися для об'єднання словників.
>>> x = {"key1": "value1 from x", "key2": "value2 from x"}
>>> y = {"key2": "value2 from y", "key3": "value3 from y"}
>>> x | y
{'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}
>>> y | x
{'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}
До вбудованої колекції типів включено list, dict і tuple, які можна використовувати як базові типи без імпорту з модуля typing. Тобто. замість typing.List, typing.Dict та typing.Tuple тепер можна вказувати
просто list, dict і tuple:
def greet_all(names: list[str]) -> None:
for name in names:
print(«Hello», name)
Надані гнучкі засоби для анотування функцій та змінних. Для прикріплення анотацій до модуля typing додано новий тип Annotated, що розширює існуючі типи додатковими метаданими, які можуть використовуватися при статичному аналізі або для оптимізації під час виконання. Для доступу до метаданих з коду метод typing.get_type_hints() доданий параметр include_extras.
Пом'якшені граматичні вимоги до декораторів - будь-який вираз, який підходить для використання в блоках if і while, тепер може бути використаний як декоратор. Зміна дозволила помітно покращити читання коду PyQt5 та спростити супровід даного модуля:
Доданий модуль graphlib, у якому реалізована підтримка топологічного сортування графів.
Запропоновано нові методи видалення префіксів і закінчень рядків — str.removeprefix(prefix) і str.removesuffix(suffix). Методи додані до об'єктів str, bytes, bytearray та collections.UserString.
>>> s = "FooBar"
>>> s.removeprefix(«Foo»)
'Bar'
Задіяний новий парсер PEG (Parsing Expression Grammar), який прийшов на зміну парсеру LL(1). Застосування нового парсера дозволило позбавитися деяких «хаков», використовуваних для обходу обмежень в LL(1), і значно знизило трудовитрати на супровід парсера. За продуктивністю новий парсер знаходиться приблизно на одному рівні з минулим, але значно випереджає його в плані гнучкості, що дозволяє вільно почуватися при проектуванні нових можливостей мови. Код старого парсера поки збережений і може бути повернутий за допомогою прапора -X oldparser або змінної оточення PYTHONOLDPARSER=1, але буде видалений у випуску 3.10.
Надано можливість доступу методів Сі-розширень до стану модулів, у яких визначено, із застосуванням прямого розіменування покажчиків замість пошуку стану модуля з допомогою функції PyState_FindModule. Зміна дозволяє підвищити продуктивність модулів Сі за рахунок зниження або повного виключення накладних витрат на перевірку стану модуля. Для асоціювання модуля з класом запропонована Си-функція PyType_FromModuleAndSpec(), для отримання модуля та його стану Си-функції PyType_GetModule() і PyType_GetModuleState(), а для надання методу доступу до класу, в якому він визначений, Си-функція PME .
Складальник сміття позбавлений від блокування колекцій, що включають реанімовані об'єкти, які залишаються доступними ззовні після запуску фіналізатора.
Доданий метод os.pidfd_open, що дозволяє використовувати підсистему ядра Linux «pidfd» для обробки ситуації з повторним використанням PID (pidfd зв'язується з конкретним процесом і не змінюється, тоді як PID може бути прив'язаний до іншого процесу після завершення поточного процесу, асоційованого з цим PID).
Підтримку специфікації Unicode оновлено до версії 13.0.0.
Усунена витік памяті при повторній ініціалізації інтерпретатора Python в одному процесі.
Проведено оптимізацію продуктивності вбудованих типів range, tuple, set, frozenset, list та dict, реалізована за рахунок застосування протоколу швидкого виклику Vectorcall для швидшого звернення до об'єктів, написаних мовою Сі.
Модулі _abc, audioop, _bz2, _codecs, _contextvars, _crypt, _functools, _json, _locale, operator, resource, time і _weakref перекладені на завантаження з ініціалізацією у кілька стадій.
Модулі стандартної бібліотеки audioop, ast, grp, _hashlib, pwd, _posixsubprocess, random, select, struct, termios та zlib переведені на використання обмеженого стабільного ABI, який вирішує проблему працездатності збирання модулів-розширень для різних версій Python (при оновленні версії не потрібно перезбирати модулі-розширення, і модулі зібрані для 3.9, зможуть працювати у гілці 3.10).
У модулі asyncio через потенційні проблеми з безпекою припинено підтримку параметра reuse_address (використання SO_REUSEADDR для UDP в Linux дозволяє різним процесам прикріплювати слухаючі сокети до UDP-порту).
Додано нові оптимізації, наприклад, підвищено продуктивність обробників сигналів у багатопотокових додатках, підвищено швидкість роботи модуля subprocess в оточенні FreeBSD та прискорено присвоєння тимчасових змінних (призначення змінної у виразі «for y in [expr]» тепер не поступається за продуктивністю виразу «y = expr »). Загалом більшість тестів показують зниження продуктивності порівняно з гілкою 3.8 (прискорення спостерігається лише у тестах write_local та write_deque):
вилучені багато функцій та методів Python 2.7, які раніше були відзначені застарілими і в минулому випуску приводили до висновку попередження DeprecationWarning, включаючи метод unescape() в html.parser.HTMLParser,
tostring() і fromstring() в array.array, isAlive() в threading.Thread, getchildren() і getiterator() в ElementTree, sys.getcheckinterval(), sys.setcheckinterval(), asyncio.Task.current_task(), asyncio.Task.all_tasks(), base64.encodestring() та base64.decodestring().