Випуск мови програмування Python 3.9

Після року розробки представлений значний випуск мови програмування Python 3.9. Python 3.9 став першим випуском після переходу проекту на новий цикл підготовки та супроводу релізів. Нові значні випуски тепер формуватимуться щорічно, а коригувальні оновлення випускатимуться раз на два місяці. Кожна значна гілка підтримуватиметься протягом півтора року, після чого ще три з половиною роки для неї формуватимуться виправлення з усуненням уразливостей.

p align="justify"> Робота над новою гілкою тепер починається за п'ять місяців до релізу чергової гілки, тобто. одночасно з випуском Python 3.9 почалося альфа-тестування гілки Python 3.10. Гілка Python 3.10 перебуватиме на стадії альфа-випусків протягом семи місяців, під час яких будуть додаватися нові можливості та виправлятися помилки. Після цього протягом трьох місяців буде проводитися тестування бета-версій, під час якого додавання нових можливостей буде заборонено і вся увага приділятиметься виправленню помилок. Останні два місяці перед релізом гілка буде на стадії кандидата в релізи, на якій буде виконано фінальну стабілізацію.

Серед доданих нововведень в Python 3.9:

  • У словниках, визначених за допомогою вбудованого класу 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.

    charType = Annotated[int, ctype(«char»)] UnsignedShort = Annotated[int, struct2.ctype('H')]

  • Пом'якшені граматичні вимоги до декораторів - будь-який вираз, який підходить для використання в блоках if і while, тепер може бути використаний як декоратор. Зміна дозволила помітно покращити читання коду PyQt5 та спростити супровід даного модуля:

    було:
    button_0 = buttons[0] @button_0.clicked.connect

    Тепер можна писати:
    @buttons[0].clicked.connect

  • У стандартну бібліотеку доданий модуль зонаінфо, Що включає інформацію з бази часових поясів IANA

    >>> від zoneinfo import ZoneInfo
    >>> з datetime import datetime, timedelta
    >>> # Літній час
    >>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo(«America/Los_Angeles»))
    >>> print(dt)
    2020-10-31 12:00:00-07:00

    >>> dt.tzname()
    'PDT'

    >>> # Стандартний час
    >>> dt += timedelta(days=7)
    >>> print(dt)
    2020-11-07 12:00:00-08:00

    >>> print(dt.tzname())
    PST

  • Доданий модуль 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 3.4 3.5 3.6 3.7 3.8 3.9
    ————— — — — — —

    Variable and attribute read access:
    read_local 7.1 7.1 5.4 5.1 3.9 4.0
    read_nonlocal 7.1 8.1 5.8 5.4 4.4 4.8
    read_global 15.5 19.0 14.3 13.6 7.6 7.7
    read_builtin 21.1 21.6 18.5 19.0 7.5 7.7
    read_classvar_from_class 25.6 26.5 20.7 19.5 18.4 18.6
    read_classvar_from_instance 22.8 23.5 18.8 17.1 16.4 20.1
    read_instancevar 32.4 33.1 28.0 26.3 25.4 27.7
    read_instancevar_slots 27.8 31.3 20.8 20.8 20.2 24.5
    read_namedtuple 73.8 57.5 45.0 46.8 18.4 23.2
    read_boundmethod 37.6 37.9 29.6 26.9 27.7 45.9

    Variable and attribute write access:
    write_local 8.7 9.3 5.5 5.3 4.3 4.2
    write_nonlocal 10.5 11.1 5.6 5.5 4.7 4.9
    write_global 19.7 21.2 18.0 18.0 15.8 17.2
    write_classvar 92.9 96.0 104.6 102.1 39.2 43.2
    write_instancevar 44.6 45.8 40.0 38.9 35.5 40.7
    write_instancevar_slots 35.6 36.1 27.3 26.6 25.7 27.7

    Data structure read access:
    read_list 24.2 24.5 20.8 20.8 19.0 21.1
    read_deque 24.7 25.5 20.2 20.6 19.8 21.6
    read_dict 24.3 25.7 22.3 23.0 21.0 22.5
    read_strdict 22.6 24.3 19.5 21.2 18.9 21.6

    Data structure write access:
    write_list 27.1 28.5 22.5 21.6 20.0 21.6
    write_deque 28.7 30.1 22.7 21.8 23.5 23.2
    write_dict 31.4 33.3 29.3 29.2 24.7 27.8
    write_strdict 28.4 29.9 27.5 25.2 23.1 29.8

    Stack (or queue) operations:
    list_append_pop 93.4 112.7 75.4 74.2 50.8 53.9
    deque_append_pop 43.5 57.0 49.4 49.2 42.5 45.5
    deque_append_popleft 43.7 57.3 49.7 49.7 42.8 45.5

    Timing loop:
    loop_overhead 0.5 0.6 0.4 0.3 0.3 0.3

  • вилучені багато функцій та методів 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().

Джерело: opennet.ru

Додати коментар або відгук