This document is for an old version of Python that is no longer supported. You should upgrade, and read the Python documentation for the current stable release.

# Що нового в Python 3.8

Редактор

  Raymond Hettinger

This article explains the new features in Python 3.8, compared to 3.7. For full details, see the changelog.

## Підсумок – основні моменти випуску

## Нові можливості

### Вирази присвоєння

Існує новий синтаксис `:=`, який призначає значення змінним як частину більшого виразу. Його ласкаво називають «оператором моржа» через його схожість з очима та бивнями моржа.

У цьому прикладі вираз присвоєння допомагає уникнути виклику `len()` двічі:

    if (n := len(a)) > 10:
        print(f"List is too long ({n} elements, expected <= 10)")

Подібна перевага виникає під час зіставлення регулярних виразів, коли об’єкти збігу потрібні двічі: один раз, щоб перевірити, чи відбувся збіг, а другий – щоб отримати підгрупу:

    discount = 0.0
    if (mo := re.search(r'(\d+)% discount', advertisement)):
        discount = float(mo.group(1)) / 100.0

Оператор також корисний у циклах while, які обчислюють значення для перевірки завершення циклу, а потім знову потребують того самого значення в тілі циклу:

    # Loop over fixed length blocks
    while (block := f.read(256)) != '':
        process(block)

Інший спонукальний випадок використання виникає під час розуміння списку, де значення, обчислене в умові фільтрації, також потрібне в тілі виразу:

    [clean_name.title() for name in names
     if (clean_name := normalize('NFC', name)) in allowed_names]

Спробуйте обмежити використання оператора Walrus для очищення випадків, що зменшує складність і покращує читабельність.

Дивіться PEP 572 для повного опису.

(Надано Емілі Морхаус у bpo-35224.)

### Лише позиційні параметри

There is a new function parameter syntax `/` to indicate that some function parameters must be specified positionally and cannot be used as keyword arguments. This is the same notation shown by `help()` for C functions annotated with Larry Hastings“ Argument Clinic tool.

У наступному прикладі параметри a і b є лише позиційними, тоді як c або d можуть бути позиційними або ключовими словами, а e або f мають бути ключовими словами:

    def f(a, b, /, c, d, *, e, f):
        print(a, b, c, d, e, f)

Нижче наведено дійсний виклик:

    f(10, 20, 30, d=40, e=50, f=60)

Однак це недійсні виклики:

    f(10, b=20, c=30, d=40, e=50, f=60)   # b cannot be a keyword argument
    f(10, 20, 30, 40, 50, f=60)           # e must be a keyword argument

Одним із випадків використання цієї нотації є те, що вона дозволяє чистим функціям Python повністю емулювати поведінку існуючих функцій, закодованих на C. Наприклад, вбудована функція `divmod()` не приймає ключові аргументи:

    def divmod(a, b, /):
        "Emulate the built in divmod() function"
        return (a // b, a % b)

Іншим випадком використання є виключення аргументів ключового слова, коли назва параметра не є корисною. Наприклад, вбудована функція `len()` має підпис `len(obj, /)`. Це виключає незручні виклики, такі як:

    len(obj='hello')  # The "obj" keyword argument impairs readability

Додаткова перевага позначення параметра як лише позиційного полягає в тому, що це дозволяє змінювати ім’я параметра в майбутньому без ризику зламати код клієнта. Наприклад, у модулі `statistic` назва параметра dist може бути змінена в майбутньому. Це стало можливим завдяки наступній специфікації функції:

    def quantiles(dist, /, *, n=4, method='exclusive')
        ...

Оскільки параметри ліворуч від `/` не представлені як можливі ключові слова, назви параметрів залишаються доступними для використання в `**kwargs`:

    >>> def f(a, b, /, **kwargs):
    ...     print(a, b, kwargs)
    ...
    >>> f(10, 20, a=1, b=2, c=3)         # a and b are used in two ways
    10 20 {'a': 1, 'b': 2, 'c': 3}

Це значно спрощує реалізацію функцій і методів, які повинні приймати довільні аргументи ключового слова. Наприклад, ось фрагмент коду в модулі `collections`:

    class Counter(dict):

        def __init__(self, iterable=None, /, **kwds):
            # Note "iterable" is a possible keyword argument

Дивіться PEP 570 для повного опису.

(Надав Pablo Galindo в bpo-36540.)

### Паралельний кеш файлової системи для скомпільованих файлів байт-коду

Нове налаштування `PYTHONPYCACHEPREFIX` (також доступне як `-X` `pycache_prefix`) налаштовує неявний кеш байт-коду на використання окремого паралельного дерева файлової системи, а не стандартних підкаталогів `__pycache__` всередині кожен вихідний каталог.

Розташування кешу повідомляється в `sys.pycache_prefix` (`None` вказує на розташування за умовчанням у підкаталогах `__pycache__`).

(Надано Карлом Майєром у bpo-33499.)

### Збірка налагодження використовує той самий ABI, що й збірка випуску

Тепер Python використовує той самий ABI, незалежно від того, чи створено його в режимі випуску чи налагодження. У Unix, коли Python створено в режимі налагодження, тепер можна завантажувати розширення C, створені в режимі випуску, і розширення C, створені за допомогою стабільного ABI.

Release builds and debug builds are now ABI compatible: defining the `Py_DEBUG` macro no longer implies the `Py_TRACE_REFS` macro, which introduces the only ABI incompatibility. The `Py_TRACE_REFS` macro, which adds the `sys.getobjects()` function and the `PYTHONDUMPREFS` environment variable, can be set using the new `./configure --with-trace-refs` build option. (Contributed by Victor Stinner in bpo-36465.)

В Unix розширення C більше не пов’язані з libpython, за винятком Android і Cygwin. Статично зв’язаний Python тепер може завантажувати розширення C, створене за допомогою спільної бібліотеки Python. (Надав Віктор Стіннер у bpo-21536.)

У Unix, коли Python створено в режимі налагодження, імпорт тепер також шукає розширення C, скомпільовані в режимі випуску, і розширення C, скомпільовані зі стабільним ABI. (Надав Віктор Стіннер у bpo-36722.)

Щоб вставити Python у програму, нову опцію `--embed` потрібно передати в `python3-config --libs --embed`, щоб отримати `-lpython3.8` (пов’язати програму з libpython ). Щоб підтримувати як 3.8, так і старіші, спробуйте спочатку `python3-config --libs --embed` і поверніться до `python3-config --libs` (без `--embed`), якщо попередня команда не вдається .

Додайте модуль pkg-config `python-3.8-embed`, щоб вставити Python у програму: `pkg-config python-3.8-embed --libs` включає `-lpython3.8`. Щоб підтримувати версії 3.8 і старіші, спочатку спробуйте `pkg-config python-X.Y-embed --libs` і поверніться до `pkg-config python-X.Y --libs` (без `--embed`). якщо попередня команда не виконується (замініть `X.Y` версією Python).

З іншого боку, `pkg-config python3.8 --libs` більше не містить `-lpython3.8`. Розширення C не повинні бути пов’язані з libpython (за винятком Android і Cygwin, випадки яких обробляються скриптом); ця зміна навмисно зворотно несумісна. (Надав Віктор Стіннер у bpo-36721.)

### f-рядки підтримують `=` для самодокументованих виразів і налагодження

Додано специфікатор `=` до f-strings. Рядок f, такий як `f'{expr=}''` розгорнеться до тексту виразу, знака рівності, а потім представлення обчисленого виразу. Наприклад:

    >>> user = 'eric_idle'
    >>> member_since = date(1975, 7, 31)
    >>> f'{user=} {member_since=}'
    "user='eric_idle' member_since=datetime.date(1975, 7, 31)"

Звичайні специфікатори формату f-string дозволяють краще контролювати відображення результату виразу:

    >>> delta = date.today() - member_since
    >>> f'{user=!s}  {delta.days=:,d}'
    'user=eric_idle  delta.days=16,075'

Специфікатор `=` відобразить весь вираз, щоб можна було показати обчислення:

    >>> print(f'{theta=}  {cos(radians(theta))=:.3f}')
    theta=30  cos(radians(theta))=0.866

(Надано Еріком В. Смітом і Ларрі Гастінгсом у bpo-36817.)

### PEP 578: Перехоплювачі аудиту виконання Python

PEP додає Audit Hook і Verified Open Hook. Обидва доступні з Python і рідного коду, що дозволяє програмам і фреймворкам, написаним на чистому коді Python, використовувати додаткові сповіщення, а також дозволяючи розробникам і системним адміністраторам розгортати збірки Python, де аудит завжди ввімкнено.

Дивіться PEP 578 для повної інформації.

### PEP 587: Конфігурація ініціалізації Python

PEP 587 додає новий C API для налаштування ініціалізації Python, забезпечуючи точніший контроль над усією конфігурацією та кращі звіти про помилки.

Нові структури:

- `PyConfig`

- `PyPreConfig`

- `PyStatus`

- `PyWideStringList`

Нові функції:

- `PyConfig_Clear()`

- `PyConfig_InitIsolatedConfig()`

- `PyConfig_InitPythonConfig()`

- `PyConfig_Read()`

- `PyConfig_SetArgv()`

- `PyConfig_SetBytesArgv()`

- `PyConfig_SetBytesString()`

- `PyConfig_SetString()`

- `PyPreConfig_InitIsolatedConfig()`

- `PyPreConfig_InitPythonConfig()`

- `PyStatus_Error()`

- `PyStatus_Exception()`

- `PyStatus_Exit()`

- `PyStatus_IsError()`

- `PyStatus_IsExit()`

- `PyStatus_NoMemory()`

- `PyStatus_Ok()`

- `PyWideStringList_Append()`

- `PyWideStringList_Insert()`

- `Py_BytesMain()`

- `Py_ExitStatusException()`

- `Py_InitializeFromConfig()`

- `Py_PreInitialize()`

- `Py_PreInitializeFromArgs()`

- `Py_PreInitializeFromBytesArgs()`

- `Py_RunMain()`

Цей PEP також додає до цих внутрішніх структур поля `_PyRuntimeState.preconfig` (`PyPreConfig` тип) і `PyInterpreterState.config` (`PyConfig` тип). `PyInterpreterState.config` стає новою еталонною конфігурацією, замінюючи глобальні змінні конфігурації та інші приватні змінні.

Перегляньте Налаштування ініціалізації Python для документації.

Дивіться PEP 587 для повного опису.

(Надав Віктор Стіннер у bpo-36763.)

### PEP 590: Vectorcall: швидкий протокол виклику для CPython

Протокол Vectorcall is added to the Python/C API. It is meant to formalize existing optimizations which were already done for various classes. Any static type implementing a callable can use this protocol.

Наразі це тимчасово. Мета полягає в тому, щоб зробити його повністю публічним у Python 3.9.

Дивіться PEP 590 для повного опису.

(Надано Йероном Демейєром, Марком Шенноном і Петром Вікторіном у bpo-36974.)

### Протокол Pickle 5 із позасмуговими буферами даних

Коли `pickle` використовується для передачі великих даних між процесами Python, щоб скористатися перевагами багатоядерної або багатомашинної обробки, важливо оптимізувати передачу, зменшивши копії в пам’яті та, можливо, застосувавши спеціальні методи, наприклад як залежне від даних стиснення.

Протокол `pickle` 5 вводить підтримку позасмугових буферів, де PEP 3118-сумісні дані можуть передаватись окремо від основного потоку pickle, на розсуд рівня зв’язку.

Дивіться PEP 574 для повного опису.

(Надав Антуан Пітру в bpo-36785.)

## Інші зміни мови

- Оператор `continue` був незаконним у пункті `finally` через проблему з реалізацією. У Python 3.8 це обмеження було знято. (Надав Сергій Сторчака в bpo-32489.)

- Типи `bool`, `int` і `fractions.Fraction` тепер мають метод `as_integer_ratio()`, подібний до того, що є в `float` і `decimal.Decimal`. Це другорядне розширення API дає змогу написати `чисельник, знаменник = x.as_integer_ratio()` і налаштувати його роботу з кількома числовими типами. (Надано Лізою Роуч у bpo-33073 та Реймондом Геттінгером у bpo-37819.)

- Конструктори `int`, `float` і `complex` тепер використовуватимуть спеціальний метод `__index__()`, якщо він доступний, і відповідний метод `__int__()`, `__float__()` або `__complex__()` недоступні. (Надав Сергій Сторчака у bpo-20092.)

- Added support of `\N{name}` escapes in `regular expressions`:

      >>> notice = 'Copyright © 2019'
      >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})')
      >>> int(copyright_year_pattern.search(notice).group(1))
      2019

  (Надано Джонатаном Юнісом і Сергієм Сторчакою в bpo-30688.)

- Dict і dictviews тепер можна повторювати у зворотному порядку вставки за допомогою `reversed()`. (Надав Ремі Лапейр у bpo-33462.)

- Синтаксис, дозволений для імен ключових слів у викликах функцій, був додатково обмежений. Зокрема, `f((keyword)=arg)` більше не дозволяється. Він ніколи не мав на меті дозволити більше, ніж голе ім’я в лівій частині терміна призначення аргументу ключового слова. (Надав Бенджамін Петерсон у bpo-34641.)

- Узагальнене ітераційне розпакування в операторах `yield` і `return` більше не потребує включення дужок. Завдяки цьому синтаксис yield і return краще узгоджується зі звичайним синтаксисом призначення:

      >>> def parse(family):
              lastname, *members = family.split()
              return lastname.upper(), *members

      >>> parse('simpsons homer marge bart lisa maggie')
      ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')

  (Надано Девідом Катбертом і Джорданом Чепменом у bpo-32117.)

- Якщо в коді пропущена кома, як-от `[(10, 20) (30, 40)]`, компілятор відображає `SyntaxWarning` з корисною пропозицією. Це покращує наявність лише `TypeError`, яка вказує, що перший кортеж не можна викликати. (Надав Сергій Сторчака в bpo-15248.)

- Арифметичні операції між підкласами об’єктів `datetime.date` або `datetime.datetime` і `datetime.timedelta` тепер повертають екземпляр підкласу, а не базового класу. Це також впливає на тип повернення операцій, реалізація яких (прямо чи опосередковано) використовує арифметику `datetime.timedelta`, наприклад `astimezone()`. (Надав Пол Ганссле в bpo-32417.)

- Коли інтерпретатор Python переривається Ctrl-C (SIGINT) і результуючий виняток `KeyboardInterrupt` не перехоплюється, процес Python тепер завершує роботу через сигнал SIGINT або з правильним кодом виходу, щоб процес виклику міг виявити це він помер через Ctrl-C. Оболонки в POSIX і Windows використовують це для належного завершення сценаріїв під час інтерактивних сеансів. (Надано Google через Грегорі П. Сміта в bpo-1054041.)

- Деякі просунуті стилі програмування вимагають оновлення об’єкта `types.CodeType` для наявної функції. Оскільки кодові об’єкти є незмінними, необхідно створити новий кодовий об’єкт, змодельований на основі існуючого кодового об’єкта. З 19 параметрами це було дещо втомливо. Тепер новий метод `replace()` дозволяє створити клон із декількома зміненими параметрами.

  Ось приклад, який змінює функцію `statistics.mean()`, щоб запобігти використанню параметра data як аргументу ключового слова:

      >>> from statistics import mean
      >>> mean(data=[10, 20, 90])
      40
      >>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1)
      >>> mean(data=[10, 20, 90])
      Traceback (most recent call last):
        ...
      TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'

  (Надав Віктор Стіннер у bpo-37032.)

- Для цілих чисел форма функції `pow()` із трьома аргументами тепер дозволяє показнику степеня бути від’ємним у випадку, коли основа взаємно проста до модуля. Потім він обчислює модульну величину, обернену до основи, коли експонента дорівнює `-1`, і відповідний ступінь цієї оберненої величини для інших від’ємних показників степеня. Наприклад, щоб обчислити модульний мультиплікативний обернений 38 за модулем 137, напишіть:

      >>> pow(38, -1, 137)
      119
      >>> 119 * 38 % 137
      1

  Модульні обернені виникають при розв’язуванні «лінійних діофантових рівнянь <https://en.wikipedia.org/wiki/Diophantine_equation>» _. Наприклад, щоб знайти цілочисельні розв’язки для `4258𝑥 + 147𝑦 = 369`, спочатку перепишіть як `4258𝑥 ≡ 369 (mod 147)`, а потім розв’яжіть:

      >>> x = 369 * pow(4258, -1, 147) % 147
      >>> y = (4258 * x - 369) // -147
      >>> 4258 * x + 147 * y
      369

  (Надав Марк Дікінсон у bpo-36027.)

- Розуміння Dict було синхронізовано з літералами Dict, так що спочатку обчислюється ключ, а потім значення:

      >>> # Dict comprehension
      >>> cast = {input('role? '): input('actor? ') for i in range(2)}
      role? King Arthur
      actor? Chapman
      role? Black Knight
      actor? Cleese

      >>> # Dict literal
      >>> cast = {input('role? '): input('actor? ')}
      role? Sir Robin
      actor? Eric Idle

  Гарантований порядок виконання корисний у виразах призначення, оскільки змінні, призначені у ключовому виразі, будуть доступні у виразі значення:

      >>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald']
      >>> {(n := normalize('NFC', name)).casefold() : n for name in names}
      {'martin von löwis': 'Martin von Löwis',
       'łukasz langa': 'Łukasz Langa',
       'walter dörwald': 'Walter Dörwald'}

  (Надав Йорн Гайслер у bpo-35224.)

- Метод `object.__reduce__()` тепер може повертати кортеж довжиною від двох до шести елементів. Раніше обмеженням було п’ять. Новий необов’язковий шостий елемент – це виклик із сигнатурою `(obj, state)`. Це дозволяє безпосередньо контролювати поведінку певного об’єкта при оновленні стану. Якщо не None, цей виклик матиме пріоритет над методом `__setstate__()` об’єкта. (Надано П’єром Глейзером і Олів’є Грізелем у bpo-35900.)

## Нові модулі

- Новий модуль `importlib.metadata` забезпечує (тимчасову) підтримку читання метаданих зі сторонніх пакетів. Наприклад, він може отримати номер версії встановленого пакета, список точок входу тощо:

      >>> # Note following example requires that the popular "requests"
      >>> # package has been installed.
      >>>
      >>> from importlib.metadata import version, requires, files
      >>> version('requests')
      '2.22.0'
      >>> list(requires('requests'))
      ['chardet (<3.1.0,>=3.0.2)']
      >>> list(files('requests'))[:5]
      [PackagePath('requests-2.22.0.dist-info/INSTALLER'),
       PackagePath('requests-2.22.0.dist-info/LICENSE'),
       PackagePath('requests-2.22.0.dist-info/METADATA'),
       PackagePath('requests-2.22.0.dist-info/RECORD'),
       PackagePath('requests-2.22.0.dist-info/WHEEL')]

  (Надано Баррі Варшау та Джейсоном Р. Кумбсом у bpo-34632.)

## Покращені модулі

### аст

Вузли AST тепер мають атрибути `end_lineno` і `end_col_offset`, які дають точне розташування кінця вузла. (Це стосується лише вузлів, які мають атрибути `lineno` і `col_offset`.)

Нова функція `ast.get_source_segment()` повертає вихідний код для певного вузла AST.

(Надав Іван Левківський у bpo-33416.)

Функція `ast.parse()` має кілька нових позначок:

- `type_comments=True` змушує повертати текст коментарів типу PEP 484 і PEP 526, пов’язаних із певними вузлами AST;

- `mode='func_type'` можна використовувати для аналізу PEP 484 «коментарів типу підпису» (повертається для вузлів AST визначення функції);

- `feature_version=(3, N)` дозволяє вказати попередню версію Python 3. Наприклад, `feature_version=(3, 4)` розглядатиме `async` і `await` як незарезервовані слова.

(Надав Гвідо ван Россум у bpo-35766.)

### asyncio

`asyncio.run()` перейшов від попереднього до стабільного API. Цю функцію можна використовувати для виконання coroutine і повернення результату під час автоматичного керування циклом подій. Наприклад:

    import asyncio

    async def main():
        await asyncio.sleep(0)
        return 42

    asyncio.run(main())

Це приблизно еквівалентно:

    import asyncio

    async def main():
        await asyncio.sleep(0)
        return 42

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        loop.run_until_complete(main())
    finally:
        asyncio.set_event_loop(None)
        loop.close()

Фактична реалізація значно складніша. Таким чином, `asyncio.run()` має бути кращим способом запуску асинхронних програм.

(Надав Юрій Селіванов у bpo-32314.)

Запуск `python -m asyncio` запускає нативний асинхронний REPL. Це дозволяє швидко експериментувати з кодом, який має `await` верхнього рівня. Більше немає потреби безпосередньо викликати `asyncio.run()`, який породжував би новий цикл подій під час кожного виклику:

    $ python -m asyncio
    asyncio REPL 3.8.0
    Use "await" directly instead of "asyncio.run()".
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> await asyncio.sleep(10, result='hello')
    hello

(Надав Юрій Селіванов у bpo-37028.)

Виняток `asyncio.CancelledError` тепер успадковується від `BaseException`, а не від `Exception` і більше не успадковується від `concurrent.futures.CancelledError`. (Надав Юрій Селіванов у bpo-32528.)

У Windows типовим циклом подій тепер є `ProactorEventLoop`. (Надав Віктор Стіннер у bpo-34687.)

`ProactorEventLoop` тепер також підтримує UDP. (Надано Адамом Мейлі та Ендрю Свєтловим у bpo-29883.)

`ProactorEventLoop` тепер можна переривати `KeyboardInterrupt` («CTRL+C»). (Надав Володимир Матвєєв у bpo-23057.)

Додано `asyncio.Task.get_coro()` для отримання загорнутої співпрограми в `asyncio.Task`. (Надав Алекс Грьонхольм у bpo-36999.)

Асинхронним завданням тепер можна присвоювати назви, передавши аргумент ключового слова `name` до `asyncio.create_task()` або методу циклу подій `create_task()`, або викликавши `set_name()` метод об’єкта завдання. Ім’я завдання відображається у виведенні `repr()` `asyncio.Task` і також може бути отримано за допомогою методу `get_name()`. (Надав Алекс Грьонхольм у bpo-34270.)

Додано підтримку Happy Eyeballs до `asyncio.loop.create_connection()`. Щоб визначити поведінку, було додано два нові параметри: happy_eyeballs_delay і interleave. Алгоритм Happy Eyeballs покращує швидкість реагування в програмах, які підтримують IPv4 та IPv6, намагаючись одночасно підключитися за допомогою обох. (Надано twisteroid ambassador у bpo-33530.)

### вбудовані елементи

Вбудований `compile()` був покращений, щоб приймати прапорець `ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`. Після передачі цього нового прапора `compile()` дозволить використовувати конструкції верхнього рівня `await`, `async for` і `async with`, які зазвичай вважаються недійсними синтаксисом. Після цього можна повернути об’єкт асинхронного коду, позначений прапором `CO_COROUTINE`. (Надав Матіас Бюссонньє в bpo-34616)

### колекції

Метод `_asdict()` для `collections.namedtuple()` тепер повертає `dict` замість `collections.OrderedDict`. Це працює, оскільки звичайні dicts мають гарантоване впорядкування, починаючи з Python 3.7. Якщо потрібні додаткові функції `OrderedDict`, запропонованим виправленням є приведення результату до потрібного типу: `OrderedDict(nt._asdict())`. (Надав Реймонд Геттінгер у bpo-35864.)

### cProfile

Клас `cProfile.Profile` тепер можна використовувати як контекстний менеджер. Профілюйте блок коду, виконавши:

    import cProfile

    with cProfile.Profile() as profiler:
          # code to be profiled
          ...

(Надав Скотт Сандерсон у bpo-29235.)

### csv

`csv.DictReader` тепер повертає екземпляри `dict` замість `collections.OrderedDict`. Інструмент тепер працює швидше та використовує менше пам’яті, але зберігає порядок полів. (Надав Майкл Селік у bpo-34003.)

### прокльони

Додано нову змінну, яка містить структуровану інформацію про версію базової бібліотеки ncurses: `ncurses_version`. (Надав Сергій Сторчака в bpo-31680.)

### ctypes

У Windows `CDLL` і підкласи тепер приймають параметр winmode для визначення прапорів для основного виклику `LoadLibraryEx`. Прапорці за замовчуванням встановлено лише для завантаження залежностей DLL із надійних місць, включаючи шлях, де зберігається DLL (якщо повний або частковий шлях використовується для завантаження початкової DLL), і шляхи, додані `add_dll_directory()` . (Надав Стів Дауер у bpo-36085.)

### дата, час

Added new alternate constructors `datetime.date.fromisocalendar()` and `datetime.datetime.fromisocalendar()`, which construct `date` and `datetime` objects respectively from ISO year, week number, and weekday; these are the inverse of each class’s `isocalendar` method. (Contributed by Paul Ganssle in bpo-36004.)

### functools

`functools.lru_cache()` тепер можна використовувати як прямий декоратор, а не як функцію, що повертає декоратор. Тож тепер підтримуються обидва:

    @lru_cache
    def f(x):
        ...

    @lru_cache(maxsize=256)
    def f(x):
        ...

(Надав Реймонд Геттінгер у bpo-36772.)

Додано новий декоратор `functools.cached_property()` для обчислених властивостей, кешованих протягом життя примірника.

    import functools
    import statistics

    class Dataset:
       def __init__(self, sequence_of_numbers):
          self.data = sequence_of_numbers

       @functools.cached_property
       def variance(self):
          return statistics.variance(self.data)

(Надано Карлом Майєром у bpo-21145)

Додано новий декоратор `functools.singledispatchmethod()`, який перетворює методи на загальні функції за допомогою single dispatch:

    from functools import singledispatchmethod
    from contextlib import suppress

    class TaskManager:

        def __init__(self, tasks):
            self.tasks = list(tasks)

        @singledispatchmethod
        def discard(self, value):
            with suppress(ValueError):
                self.tasks.remove(value)

        @discard.register(list)
        def _(self, tasks):
            targets = set(tasks)
            self.tasks = [x for x in self.tasks if x not in targets]

(Надав Ітан Сміт у bpo-32380)

### gc

`get_objects()` тепер може отримувати додатковий параметр generation, що вказує на покоління, з якого потрібно отримати об’єкти. (Надав Пабло Галіндо в bpo-36016.)

### gettext

Додано `pgettext()` та його варіанти. (Надано Францом Гласнером, Еріком Араужо та Шеріл Сабеллою в bpo-2504.)

### gzip

Додано параметр mtime до `gzip.compress()` для відтворюваного виведення. (Надав Guo Ci Teo в bpo-34898.)

Виняток `BadGzipFile` тепер викликається замість `OSError` для певних типів недійсних або пошкоджених файлів gzip. (Надано Філіпом Грущинським, Мікеле Орру та Закері Шпітцем у bpo-6584.)

### IDLE і idlelib

Виведення в N рядків (50 за замовчуванням) стиснуто до кнопки. N можна змінити в розділі PyShell на сторінці «Загальні» діалогового вікна «Параметри». Менше, але, можливо, наддовгих рядків можна стиснути, клацнувши правою кнопкою миші на виводі. Стиснутий вихід можна розгорнути на місці, подвійним клацанням кнопки або в буфер обміну чи окреме вікно, клацнувши кнопку правою кнопкою миші. (Надав Тал Ейнат у bpo-1529353.)

Додайте «Run Customized» до меню «Run», щоб запустити модуль із налаштованими налаштуваннями. Будь-які введені аргументи командного рядка додаються до sys.argv. Вони також знову з’являються в полі для наступного налаштованого запуску. Можна також придушити звичайний перезапуск основного модуля Shell. (Надано Шеріл Сабелла, Террі Ян Ріді та іншими в bpo-5680 і bpo-37627.)

Додано додаткові номери рядків для вікон редактора IDLE. Вікна відкриваються без номерів рядків, якщо не встановлено інше на вкладці «Загальні» діалогового вікна налаштування. Номери рядків для існуючого вікна відображаються та ховаються в меню «Параметри». (Надано Тал Ейнат і Саймадхав Геблікар у bpo-17535.)

Власне кодування ОС тепер використовується для перетворення між рядками Python і об’єктами Tcl. Це дозволяє IDLE працювати з емодзі та іншими символами, відмінними від BMP. Ці символи можна відобразити або скопіювати та вставити в буфер обміну або з нього. Перетворення рядків із Tcl на Python і назад тепер ніколи не дає збою. (Багато людей працювали над цим вісім років, але нарешті проблему вирішив Сергій Сторчака в bpo-13153.)

Нове в 3.8.1:

Додайте опцію для вимкнення блимання курсору. (Надав Закері Шпітц у bpo-4603.)

Клавіша Escape тепер закриває вікна завершення IDLE. (Надав Джонні Наджера в bpo-38944.)

Зазначені вище зміни було перенесено до випусків обслуговування 3.7.

Додайте ключові слова до списку завершення імен модуля. (Надано Террі Дж. Ріді в bpo-37765.)

### оглядати

Функція `inspect.getdoc()` тепер може знаходити рядки документів для `__slots__`, якщо цей атрибут є `dict`, де значення є рядками документів. Це надає параметри документації, подібні до тих, які ми вже маємо для `property()`, `classmethod()` і `staticmethod()`:

    class AudioClip:
        __slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place',
                     'duration': 'in seconds, rounded up to an integer'}
        def __init__(self, bit_rate, duration):
            self.bit_rate = round(bit_rate / 1000.0, 1)
            self.duration = ceil(duration)

(Надав Реймонд Геттінгер у bpo-36326.)

### io

In development mode (`-X` `env`) and in debug build, the `io.IOBase` finalizer now logs the exception if the `close()` method fails. The exception is ignored silently by default in release build. (Contributed by Victor Stinner in bpo-18748.)

### itertools

Функція `itertools.accumulate()` додала опцію initial аргумент ключового слова для визначення початкового значення:

    >>> from itertools import accumulate
    >>> list(accumulate([10, 5, 30, 15], initial=1000))
    [1000, 1010, 1015, 1045, 1060]

(Надано Лізою Роуч у bpo-34659.)

### json.tool

Додайте опцію `--json-lines`, щоб аналізувати кожен рядок введення як окремий об’єкт JSON. (Надано Weipeng Hong у bpo-31553.)

### лісозаготівля

Added a force keyword argument to `logging.basicConfig()` When set to true, any existing handlers attached to the root logger are removed and closed before carrying out the configuration specified by the other arguments.

Це вирішує давню проблему. Після виклику реєстратора або basicConfig() наступні виклики basicConfig() мовчки ігнорувалися. Через це було складно оновлювати, експериментувати з різними параметрами конфігурації журналу або навчати їх за допомогою інтерактивної підказки або блокнота Jupyter.

(Suggested by Raymond Hettinger, implemented by Dong-hee Na, and reviewed by Vinay Sajip in bpo-33897.)

### математика

Додано нову функцію `math.dist()` для обчислення евклідової відстані між двома точками. (Надав Реймонд Геттінгер у bpo-33089.)

Розширено функцію `math.hypot()` для обробки кількох вимірів. Раніше він підтримував лише двовимірний випадок. (Надав Реймонд Геттінгер у bpo-33089.)

Додано нову функцію, `math.prod()`, як функцію, аналогічну функції `sum()`, яка повертає добуток початкового значення (за замовчуванням: 1), помноженого на ітерацію чисел:

    >>> prior = 0.8
    >>> likelihoods = [0.625, 0.84, 0.30]
    >>> math.prod(likelihoods, start=prior)
    0.126

(Надав Пабло Галіндо в bpo-35606.)

Додано дві нові комбінаторні функції `math.perm()` і `math.comb()`:

    >>> math.perm(10, 3)    # Permutations of 10 things taken 3 at a time
    720
    >>> math.comb(10, 3)    # Combinations of 10 things taken 3 at a time
    120

(Надано Yash Aggarwal, Keller Fuchs, Serhiy Storchaka та Raymond Hettinger у bpo-37128, bpo-37178 та bpo-35431.)

Додано нову функцію `math.isqrt()` для обчислення точних цілих квадратних коренів без перетворення до числа з плаваючою комою. Нова функція підтримує довільні цілі числа. Це швидше, ніж `floor(sqrt(n))`, але повільніше, ніж `math.sqrt()`:

    >>> r = 650320427
    >>> s = r ** 2
    >>> isqrt(s - 1)         # correct
    650320426
    >>> floor(sqrt(s - 1))   # incorrect
    650320427

(Надав Марк Дікінсон у bpo-36887.)

Функція `math.factorial()` більше не приймає аргументи, які не є int-подібними. (Надав Пабло Галіндо в bpo-33083.)

### mmap

Клас `mmap.mmap` тепер має метод `madvise()` для доступу до системного виклику `madvise()`. (Надав Закері Шпітц у bpo-32941.)

### багатопроцесорність

Додано новий модуль `multiprocessing.shared_memory`. (Надав Девін Поттс у bpo-35813.)

У macOS метод запуску spawn тепер використовується за замовчуванням. (Надав Віктор Стіннер у bpo-33725.)

### ос

Додано нову функцію `add_dll_directory()` у Windows для надання додаткових шляхів пошуку для власних залежностей під час імпорту модулів розширення або завантаження DLL за допомогою `ctypes`. (Надав Стів Дауер у bpo-36085.)

Було додано нову функцію `os.memfd_create()` для обгортання системного виклику `memfd_create()`. (Надано Zackery Spytz і Christian Heimes у bpo-26836.)

У Windows велика частина ручної логіки для обробки точок повторного аналізу (включаючи символічні посилання та з’єднання каталогів) була делегована операційній системі. Зокрема, `os.stat()` тепер переглядатиме все, що підтримується операційною системою, тоді як `os.lstat()` відкриватиме лише точки повторного аналізу, які ідентифікуються як «сурогати імен», тоді як інші відкриваються як для `os.stat()`. У всіх випадках у `stat_result.st_mode` буде встановлено лише `S_IFLNK` для символічних посилань, а не для інших типів точок повторного аналізу. Щоб визначити інші типи точок повторного аналізу, перевірте новий атрибут `stat_result.st_reparse_tag`.

У Windows `os.readlink()` тепер може читати з’єднання каталогів. Зауважте, що `islink()` поверне `False` для з’єднань каталогів, тому код, який спочатку перевіряє `islink`, продовжуватиме розглядати з’єднання як каталоги, тоді як код, який обробляє помилки з `os.readlink()` тепер може розглядати перехрестя як посилання.

(Надав Стів Дауер у bpo-37834.)

### os.path

`os.path` функції, які повертають логічний результат, наприклад `exists()`, `lexists()`, `isdir()` , `isfile()`, `islink()` і `ismount()` тепер повертають `False` замість підвищення `ValueError` або його підкласи `UnicodeEncodeError` і `UnicodeDecodeError` для шляхів, які містять символи або байти, які неможливо відобразити на рівні ОС. (Надав Сергій Сторчака в bpo-33721.)

`expanduser()` у Windows тепер надає перевагу змінній середовища `USERPROFILE` і не використовує `HOME`, яка зазвичай не встановлюється для звичайних облікових записів користувачів. (Надав Ентоні Соттіле в bpo-36264.)

`isdir()` у Windows більше не повертає `True` для посилання на неіснуючий каталог.

`realpath()` у Windows тепер розпізнає точки повторного аналізу, включаючи символічні посилання та з’єднання каталогів.

(Надав Стів Дауер у bpo-37834.)

### pathlib

`pathlib.Path` methods that return a boolean result like `exists()`, `is_dir()`, `is_file()`, `is_mount()`, `is_symlink()`, `is_block_device()`, `is_char_device()`, `is_fifo()`, `is_socket()` now return `False` instead of raising `ValueError` or its subclass `UnicodeEncodeError` for paths that contain characters unrepresentable at the OS level. (Contributed by Serhiy Storchaka in bpo-33721.)

Added `pathlib.Path.link_to()` which creates a hard link pointing to a path. (Contributed by Joannah Nanjekye in bpo-26978)

### маринований огірок

Розширення `pickle`, що створюють субкласи оптимізованого для C `Pickler`, тепер можуть перевизначати логіку маринування функцій і класів, визначаючи спеціальний метод `reducer_override()`. (Надано П’єром Глейзером і Олів’є Грізелем у bpo-35900.)

### plistlib

Додано новий `plistlib.UID` і ввімкнено підтримку для читання та запису бінарних списків у кодуванні NSKeyedArchiver. (Надав Джон Янзен у bpo-26707.)

### pprint

Модуль `pprint` додав параметр sort_dicts до кількох функцій. За замовчуванням ці функції продовжують сортувати словники перед рендерингом або друком. Однак якщо sort_dicts має значення false, словники зберігають порядок вставлення ключів. Це може бути корисним для порівняння з вхідними даними JSON під час налагодження.

Крім того, є нова зручна функція `pprint.pp()`, яка схожа на `pprint.pprint()`, але з sort_dicts за замовчуванням `False`:

    >>> from pprint import pprint, pp
    >>> d = dict(source='input.txt', operation='filter', destination='output.txt')
    >>> pp(d, width=40)                  # Original order
    {'source': 'input.txt',
     'operation': 'filter',
     'destination': 'output.txt'}
    >>> pprint(d, width=40)              # Keys sorted alphabetically
    {'destination': 'output.txt',
     'operation': 'filter',
     'source': 'input.txt'}

(Надав Ремі Лапейр у bpo-30670.)

### py_compile

`py_compile.compile()` тепер підтримує тихий режим. (Надано Joannah Nanjekye у bpo-22640.)

### шлекс

Нова функція `shlex.join()` діє як зворотна функція `shlex.split()`. (Надав Бо Бейлс у bpo-32102.)

### шутил

`shutil.copytree()` тепер приймає новий аргумент ключового слова `dirs_exist_ok`. (Надав Джош Бронсон у bpo-20849.)

`shutil.make_archive()` тепер за замовчуванням використовує сучасний формат pax (POSIX.1-2001) для нових архівів для покращення переносимості та відповідності стандартам, успадкованому від відповідних змін у модулі `tarfile`. (Надано C.A.M. Gerlach у bpo-30661.)

`shutil.rmtree()` у Windows тепер видаляє з’єднання каталогів без попереднього рекурсивного видалення їх вмісту. (Надав Стів Дауер у bpo-37834.)

### гніздо

Added `create_server()` and `has_dualstack_ipv6()` convenience functions to automate the necessary tasks usually involved when creating a server socket, including accepting both IPv4 and IPv6 connections on the same socket. (Contributed by Giampaolo Rodolà in bpo-17561.)

The `socket.if_nameindex()`, `socket.if_nametoindex()`, and `socket.if_indextoname()` functions have been implemented on Windows. (Contributed by Zackery Spytz in bpo-37007.)

### ssl

Додано `post_handshake_auth` для ввімкнення та `verify_client_post_handshake()` для ініціювання автентифікації TLS 1.3 після рукостискання. (Надав Крістіан Хеймс у bpo-34670.)

### статистика

Added `statistics.fmean()` as a faster, floating point variant of `statistics.mean()`. (Contributed by Raymond Hettinger and Steven D’Aprano in bpo-35904.)

Added `statistics.geometric_mean()` (Contributed by Raymond Hettinger in bpo-27181.)

Додано `statistics.multimode()`, який повертає список найпоширеніших значень. (Надав Реймонд Геттінгер у bpo-35892.)

Додано `statistics.quantiles()`, який ділить дані або розподіл на рівноімовірні інтервали (наприклад, квартилі, децилі або процентилі). (Надав Реймонд Геттінгер у bpo-36546.)

Додано `statistics.NormalDist`, інструмент для створення та керування нормальним розподілом випадкової величини. (Надав Реймонд Геттінгер у bpo-36018.)

    >>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14])
    >>> temperature_feb.mean
    6.0
    >>> temperature_feb.stdev
    6.356099432828281

    >>> temperature_feb.cdf(3)            # Chance of being under 3 degrees
    0.3184678262814532
    >>> # Relative chance of being 7 degrees versus 10 degrees
    >>> temperature_feb.pdf(7) / temperature_feb.pdf(10)
    1.2039930378537762

    >>> el_niño = NormalDist(4, 2.5)
    >>> temperature_feb += el_niño        # Add in a climate effect
    >>> temperature_feb
    NormalDist(mu=10.0, sigma=6.830080526611674)

    >>> temperature_feb * (9/5) + 32      # Convert to Fahrenheit
    NormalDist(mu=50.0, sigma=12.294144947901014)
    >>> temperature_feb.samples(3)        # Generate random samples
    [7.672102882379219, 12.000027119750287, 4.647488369766392]

### система

Додайте нову функцію `sys.unraisablehook()`, яку можна перевизначати, щоб керувати обробкою «виключних ситуацій, які не можна викликати». Він викликається, коли сталася виняткова ситуація, але Python не може її впоратися. Наприклад, коли деструктор викликає виняток або під час збирання сміття (`gc.collect()`). (Надав Віктор Стіннер у bpo-36829.)

### tarfile

Модуль `tarfile` тепер за замовчуванням використовує сучасний формат pax (POSIX.1-2001) для нових архівів замість попереднього, специфічного для GNU. Це покращує міжплатформенну переносимість завдяки узгодженому кодуванню (UTF-8) у стандартизованому та розширюваному форматі та пропонує кілька інших переваг. (Надано C.A.M. Gerlach у bpo-36268.)

### різьблення

Додайте нову функцію `threading.excepthook()`, яка обробляє неперехоплені винятки `threading.Thread.run()`. Його можна змінити, щоб керувати обробкою неперехоплених винятків `threading.Thread.run()`. (Надав Віктор Стіннер у bpo-1230540.)

Додайте нову функцію `threading.get_native_id()` і атрибут `native_id` до класу `threading.Thread`. Вони повертають власний інтегральний ідентифікатор потоку поточного потоку, призначений ядром. Ця функція доступна лише на певних платформах, див. `get_native_id` для отримання додаткової інформації. (Надав Джейк Теслер у bpo-36084.)

### токенізувати

Модуль `tokenize` тепер неявно випромінює маркер `NEWLINE`, якщо надається вхідні дані, які не мають кінцевого нового рядка. Ця поведінка тепер відповідає внутрішнім функціям C tokenizer. (Надав Аммар Аскар у bpo-33899.)

### tkinter

Додано методи `selection_from()`, `selection_present()`, `selection_range()` та `selection_to()` у клас `tkinter.Spinbox`. (Надано Juliette Monsel у bpo-34829.)

Додано метод `moveto()` в клас `tkinter.Canvas`. (Надано Джульєтт Монсел у bpo-23831.)

Клас `tkinter.PhotoImage` тепер має методи `transparency_get()` і `transparency_set()`. (Надав Закері Шпітц у bpo-25451.)

### час

Added new clock `CLOCK_UPTIME_RAW` for macOS 10.12. (Contributed by Joannah Nanjekye in bpo-35702.)

### введення тексту

Модуль `typing` містить кілька нових функцій:

- Тип словника з типами по ключу. Перегляньте PEP 589 і `typing.TypedDict`. TypedDict використовує лише рядкові ключі. За замовчуванням кожен ключ повинен бути присутнім. Укажіть «total=False», щоб дозволити ключам бути необов’язковими:

      class Location(TypedDict, total=False):
          lat_long: tuple
          grid_square: str
          xy_coordinate: tuple

- Літеральні типи. Перегляньте PEP 586 і `typing.Literal`. Літеральні типи вказують на те, що параметр або значення, що повертається, обмежено одним або кількома конкретними літеральними значеннями:

      def get_status(port: int) -> Literal['connected', 'disconnected']:
          ...

- «Кінцеві» змінні, функції, методи та класи. Перегляньте PEP 591, `typing.Final` і `typing.final()`. Остаточний кваліфікатор наказує статичному засобу перевірки типів обмежити створення підкласів, перевизначення чи перепризначення:

      pi: Final[float] = 3.1415926536

- Визначення протоколу. Перегляньте PEP 544, `typing.Protocol` і `typing.runtime_checkable()`. Прості азбуки, такі як `typing.SupportsInt` тепер є підкласами `Protocol`.

- Новий клас протоколу `typing.SupportsIndex`.

- Нові функції `typing.get_origin()` і `typing.get_args()`.

### unicodedata

The `unicodedata` module has been upgraded to use the Unicode 12.1.0 release.

Нова функція `is_normalized()` може бути використана для перевірки того, що рядок знаходиться в певній нормальній формі, часто набагато швидше, ніж шляхом фактичної нормалізації рядка. (Надано Максом Беланджером, Девідом Юресті та Грегом Прайсом у bpo-32285 та bpo-37966).

### unittest

Додано `AsyncMock` для підтримки асинхронної версії `Mock`. Також додано відповідні нові функції assert для тестування. (Надано Лізою Роуч у bpo-26467).

Added `addModuleCleanup()` and `addClassCleanup()` to unittest to support cleanups for `setUpModule()` and `setUpClass()`. (Contributed by Lisa Roach in bpo-24412.)

Кілька імітаційних функцій підтвердження тепер також друкують список фактичних викликів у разі невдачі. (Надано Петтером Страндмарком у bpo-35047.)

Модуль `unittest` отримав підтримку співпрограм для використання як тестових випадків із `unittest.IsolatedAsyncioTestCase`. (Надав Ендрю Свєтлов у bpo-32972.)

Приклад:

    import unittest

    class TestRequest(unittest.IsolatedAsyncioTestCase):

        async def asyncSetUp(self):
            self.connection = await AsyncConnection()

        async def test_get(self):
            response = await self.connection.get("https://example.com")
            self.assertEqual(response.status_code, 200)

        async def asyncTearDown(self):
            await self.connection.close()

    if __name__ == "__main__":
        unittest.main()

### venv

`venv` тепер містить сценарій `Activate.ps1` на всіх платформах для активації віртуальних середовищ у PowerShell Core 6.1. (Надано Бреттом Кенноном у bpo-32718.)

### слабкий реф

Проксі-об’єкти, які повертає `weakref.proxy()`, тепер підтримують оператори множення матриці `@` і `@=` на додаток до інших числових операторів. (Надав Марк Дікінсон у bpo-36669.)

### xml

Щоб пом’якшити DTD і пошук зовнішніх об’єктів, модулі `xml.dom.minidom` і `xml.sax` більше не обробляють зовнішні об’єкти за замовчуванням. (Надав Крістіан Хеймс у bpo-17239.)

Методи `.find*()` у модулі `xml.etree.ElementTree` підтримують пошук за символами узагальнення, наприклад `{*}tag`, який ігнорує простір імен, і `{namespace}*`, який повертає всі теги у вказаному просторі імен. (Надав Стефан Бенель у bpo-28238.)

The `xml.etree.ElementTree` module provides a new function `–xml.etree.ElementTree.canonicalize()` that implements C14N 2.0. (Contributed by Stefan Behnel in bpo-13611.)

Цільовий об’єкт `xml.etree.ElementTree.XMLParser` може отримувати події оголошення простору імен через нові методи зворотного виклику `start_ns()` і `end_ns()`. Крім того, ціль `xml.etree.ElementTree.TreeBuilder` можна налаштувати на обробку подій щодо коментарів та інструкцій з обробки, щоб включити їх у згенероване дерево. (Надав Стефан Бенель у bpo-36676 і bpo-36673.)

### xmlrpc

`xmlrpc.client.ServerProxy` тепер підтримує необов’язковий аргумент ключового слова headers для послідовності заголовків HTTP, які надсилаються з кожним запитом. Серед іншого, це дає змогу оновити стандартну базову автентифікацію до швидшої сеансової автентифікації. (Надав Седрик Крієр у bpo-35153.)

## Оптимізації

- Модуль `subprocess` тепер може використовувати функцію `os.posix_spawn()` у деяких випадках для кращої продуктивності. Наразі він використовується лише в macOS і Linux (з використанням glibc 2.24 або новішої версії), якщо виконуються всі ці умови:

  - close_fds є помилковим;

  - Параметри preexec_fn, pass_fds, cwd і start_new_session не встановлені;

  - виконуваний шлях містить каталог.

  (Надано Джоанною Нанджекі та Віктором Стіннером у bpo-35537.)

- `shutil.copyfile()`, `shutil.copy()`, `shutil.copy2()`, `shutil.copytree()` і `shutil.move()` використовують спеціальну для платформи «швидку -copy» системні виклики в Linux і macOS для більш ефективного копіювання файлу. «швидке копіювання» означає, що операція копіювання відбувається всередині ядра, уникаючи використання буферів простору користувача в Python, як у «`outfd.write(infd.read())`». У Windows `shutil.copyfile()` використовує більший розмір буфера за замовчуванням (1 МіБ замість 16 КіБ) і використовується варіант `memoryview()` на основі `shutil.copyfileobj()`. Прискорення копіювання файлу розміром 512 МіБ в межах одного розділу становить приблизно +26% у Linux, +50% у macOS і +40% у Windows. Крім того, споживається набагато менше циклів ЦП. Перегляньте розділ Залежні від платформи ефективні операції копіювання. (Надав Джампаоло Родола в bpo-33671.)

- `shutil.copytree()` використовує функцію `os.scandir()`, а всі залежні від неї функції копіювання використовують кешовані значення `os.stat()`. Прискорення для копіювання каталогу з 8000 файлами становить приблизно +9% у Linux, +20% у Windows і +30% у Windows SMB. Також кількість системних викликів `os.stat()` зменшено на 38%, що робить `shutil.copytree()` особливо швидшим у мережевих файлових системах. (Надав Джампаоло Родола в bpo-33695.)

- Протоколом за замовчуванням у модулі `pickle` тепер є протокол 4, вперше представлений у Python 3.4. Він пропонує кращу продуктивність і менший розмір порівняно з протоколом 3, доступним з Python 3.0.

- Видалено один член `Py_ssize_t` з `PyGC_Head`. Розмір усіх об’єктів, що відстежуються GC (наприклад, кортеж, список, dict), зменшено на 4 або 8 байт. (Надано Інадою Наокі в bpo-33597.)

- `uuid.UUID` тепер використовує `__slots__`, щоб зменшити обсяг пам’яті. (Надано Wouter Bolsterlee і Tal Einat у bpo-30977)

- Покращена продуктивність `operator.itemgetter()` на 33%. Оптимізовано обробку аргументів і додано швидкий шлях для звичайного випадку одного невід’ємного цілого індексу в кортежі (що є типовим випадком використання в стандартній бібліотеці). (Надав Реймонд Геттінгер у bpo-35664.)

- Прискорений пошук полів у `collections.namedtuple()`. Тепер вони більш ніж у два рази швидші, що робить їх найшвидшою формою пошуку змінних екземплярів у Python. (Надано Реймондом Геттінгером, Пабло Галіндо та Джо Джевником, Сергієм Сторчакою в bpo-32492.)

- Конструктор `list` не розподіляє внутрішній буфер елементів, якщо ітерація введення має відому довжину (введення реалізує `__len__`). Це робить створений список у середньому на 12% меншим. (Надано Реймондом Геттінгером і Пабло Галіндо в bpo-33234.)

- Подвоєна швидкість запису змінних класу. Коли атрибут не-dunder оновлювався, виникав непотрібний виклик для оновлення слотів. (Надано Стефаном Бенелем, Пабло Галіндо Сальгадо, Раймондом Геттінгером, Нілом Шеменауером і Сергієм Сторчакою в bpo-36012.)

- Зменшено накладні витрати на перетворення аргументів, які передаються багатьом вбудованим функціям і методам. Це прискорило виклик деяких простих вбудованих функцій і методів на 20–50%. (Надав Сергій Сторчака в bpo-23867, bpo-35582 та bpo-36127.)

- Інструкція `LOAD_GLOBAL` тепер використовує новий механізм «кешу кожного коду операції». Зараз це приблизно на 40% швидше. (Надано Юрієм Селівановим та Інадою Наокі в bpo-26219.)

## Зміни збірки та C API

- За замовчуванням `sys.abiflags` став порожнім рядком: прапорець `m` для pymalloc став марним (збірки з pymalloc і без нього сумісні з ABI), тому його було видалено. (Надав Віктор Стіннер у bpo-36707.)

  Приклад змін:

  - Встановлено лише програму `python3.8`, програми `python3.8m` немає.

  - Встановлено лише сценарій `python3.8-config`, сценарій `python3.8m-config` зник.

  - Прапор `m` було видалено з суфікса назв файлів динамічної бібліотеки: модулі розширення в стандартній бібліотеці, а також модулі, створені та встановлені пакетами сторонніх розробників, як-от завантажені з PyPI. У Linux, наприклад, суфікс Python 3.7 `.cpython-37m-x86_64-linux-gnu.so` став `.cpython-38-x86_64-linux-gnu.so` у Python 3.8.

- Файли заголовків реорганізовано, щоб краще розділити різні типи API:

  - `Include/*.h` має бути портативним загальнодоступним стабільним C API.

  - `Include/cpython/*.h` має бути нестабільним C API, специфічним для CPython; публічний API, з деякими приватними API з префіксом `_Py` або `_PY`.

  - `Include/internal/*.h` — це приватний внутрішній API C, специфічний для CPython. Цей API не має гарантії зворотної сумісності, тому його не слід використовувати поза CPython. Він доступний лише для дуже специфічних потреб, таких як налагоджувачі та профілі, які мають доступ до внутрішніх елементів CPython без виклику функцій. Цей API тепер встановлено за допомогою `make install`.

  (Надано Віктором Стіннером у bpo-35134 та bpo-35081, робота, розпочата Еріком Сноу над Python 3.7.)

- Деякі макроси було перетворено на статичні вбудовані функції: типи параметрів і тип повернення добре визначені, вони не мають проблем, характерних для макросів, змінні мають локальні області видимості. приклади:

  - `Py_INCREF()`, `Py_DECREF()`

  - `Py_XINCREF()`, `Py_XDECREF()`

  - `PyObject_INIT()`, `PyObject_INIT_VAR()`

  - Private functions: `_PyObject_GC_TRACK()`, `_PyObject_GC_UNTRACK()`, `_Py_Dealloc()`

  (Надав Віктор Стіннер у bpo-35059.)

- The `PyByteArray_Init()` and `PyByteArray_Fini()` functions have been removed. They did nothing since Python 2.7.4 and Python 3.2.0, were excluded from the limited API (stable ABI), and were not documented. (Contributed by Victor Stinner in bpo-35713.)

- Результат `PyExceptionClass_Name()` тепер має тип `const char *`, а не `char *`. (Надав Сергій Сторчака в bpo-33818.)

- Подвійність `Modules/Setup.dist` і `Modules/Setup` було видалено. Раніше, оновлюючи дерево вихідних кодів CPython, потрібно було вручну скопіювати `Modules/Setup.dist` (усередині дерева вихідних кодів) до `Modules/Setup` (усередині дерева збірки), щоб відобразити будь-які зміни вгорі . Це було невеликою перевагою для пакувальників за рахунок частого роздратування розробників після розробки CPython, оскільки забуття скопіювати файл могло призвести до помилок збірки.

  Тепер система збирання завжди читає з `Modules/Setup` у дереві вихідних кодів. Людям, які хочуть налаштувати цей файл, рекомендується зберігати свої зміни в git-форку CPython або як файли виправлень, як вони робили б для будь-яких інших змін у вихідному дереві.

  (Надав Антуан Пітру в bpo-32430.)

- Функції, які перетворюють число Python на ціле число C, як-от `PyLong_AsLong()`, і функції аналізу аргументів, як-от `PyArg_ParseTuple()` з одиницями формату перетворення цілих чисел, як-от `'i'` тепер використовуватимуть Спеціальний метод `__index__()` замість `__int__()`, якщо доступний. Попередження про припинення використання буде випущено для об’єктів із методом `__int__()`, але без `__index__()` (наприклад, `Decimal` і `Fraction` ). `PyNumber_Check()` тепер повертатиме `1` для об’єктів, що реалізують `__index__()`. `PyNumber_Long()`, `PyNumber_Float()` і `PyFloat_AsDouble()` тепер також використовують метод `__index__()`, якщо він доступний. (Надав Сергій Сторчака в bpo-36048 і bpo-20092.)

- Об’єкти типу, розподіленого за допомогою динамічної пам’яті, тепер збільшуватимуть кількість посилань у `PyObject_Init()` (і його паралельному макросі `PyObject_INIT`), а не в `PyType_GenericAlloc()`. Типи, які змінюють виділення або звільнення екземплярів, можливо, потребують коригування. (Надав Едді Елізондо в bpo-35810.)

- The new function `PyCode_NewWithPosOnlyArgs()` allows to create code objects like `PyCode_New()`, but with an extra posonlyargcount parameter for indicating the number of positional-only arguments. (Contributed by Pablo Galindo in bpo-37221.)

- `Py_SetPath()` now sets `sys.executable` to the program full path (`Py_GetProgramFullPath()`) rather than to the program name (`Py_GetProgramName()`). (Contributed by Victor Stinner in bpo-38234.)

## Застаріле

- Команда distutils `bdist_wininst` тепер застаріла, замість неї використовуйте `bdist_wheel` (пакети колеса). (Надав Віктор Стіннер у bpo-37481.)

- Застарілі методи `getchildren()` і `getiterator()` у модулі `ElementTree` тепер видають `DeprecationWarning` замість `PendingDeprecationWarning`. Їх буде видалено в Python 3.9. (Надав Сергій Сторчака в bpo-29209.)

- Передача об’єкта, який не є екземпляром `concurrent.futures.ThreadPoolExecutor`, у `loop.set_default_executor()` застаріла та буде заборонена в Python 3.9. (Надав Елвіс Пранскявічус у bpo-34075.)

- The `__getitem__()` methods of `xml.dom.pulldom.DOMEventStream`, `wsgiref.util.FileWrapper` and `fileinput.FileInput` have been deprecated.

  Реалізації цих методів ігнорували параметр index і замість нього повертали наступний елемент. (Надано Berker Peksag у bpo-9372.)

- Клас `typing.NamedTuple` відмовився від атрибута `_field_types` на користь атрибута `__annotations__`, який містить ту саму інформацію. (Надав Реймонд Геттінгер у bpo-36320.)

- `ast` класи `Num`, `Str`, `Bytes`, `NameConstant` і `Ellipsis` вважаються застарілими та будуть видалені в майбутніх версіях Python. Замість цього слід використовувати `Constant`. (Надав Сергій Сторчака в bpo-32892.)

- `ast.NodeVisitor` методи `visit_Num()`, `visit_Str()`, `visit_Bytes()`, `visit_NameConstant()` та `visit_Ellipsis()` застаріли тепер і не буде викликатися в майбутніх версіях Python. Додайте метод `visit_Constant()` для обробки всіх постійних вузлів. (Надав Сергій Сторчака в bpo-36917.)

- `asyncio.coroutine()` decorator застаріло та буде видалено у версії 3.10. Замість `@asyncio.coroutine` використовуйте `async def`. (Надав Ендрю Свєтлов у bpo-36921.)

- У `asyncio` явна передача аргументу loop застаріла та буде видалена у версії 3.10 для наступних: `asyncio.sleep()`, `asyncio.gather()`, `asyncio.shield()`, `asyncio.wait_for()`, `asyncio.wait()`, `asyncio.as_completed()`, `asyncio.Task`, `asyncio. Lock`, `asyncio.Event`, `asyncio.Condition`, `asyncio.Semaphore`, `asyncio.BoundedSemaphore`, `asyncio.Queue`, `asyncio.create_subprocess_exec()` і `asyncio.create_subprocess_shell()`.

- Явне передавання об’єктів співпрограми до `asyncio.wait()` застаріло та буде видалено у версії 3.11. (Надав Юрій Селіванов у bpo-34790.)

- Наступні функції та методи застаріли в модулі `gettext`: `lgettext()`, `ldgettext()`, `lngettext()` і `ldngettext()`. Вони повертають закодовані байти, і можливо, ви отримаєте несподівані винятки, пов’язані з Unicode, якщо є проблеми з кодуванням перекладених рядків. Набагато краще використовувати альтернативи, які повертають рядки Unicode в Python 3. Ці функції давно не працюють.

  Функція `bind_textdomain_codeset()`, методи `output_charset()` і `set_output_charset()`, а також параметр codeset функцій `translation()` і `install()` також застаріли, оскільки вони використовуються лише для функцій `l*gettext()`. (Надав Сергій Сторчака в bpo-33710.)

- The `isAlive()` method of `threading.Thread` has been deprecated. (Contributed by Dong-hee Na in bpo-35283.)

- Багато вбудованих функцій і функцій розширення, які приймають цілі аргументи, тепер видаватимуть попередження про застаріленість для `Decimal`s, `Fraction`s та будь-яких інших об’єктів, які можна перетворити лише на цілі числа із втратою (наприклад, які мають метод `__int__()`, але не мають методу `__index__()`). У наступній версії вони будуть помилками. (Надав Сергій Сторчака в bpo-36048.)

- Застаріло передавати такі аргументи як аргументи ключового слова:

  - func у `functools.partialmethod()`, `weakref.finalize()`, `profile.Profile.runcall()`, `cProfile.Profile.runcall()`, `bdb. Bdb.runcall()`, `trace.Trace.runfunc()` і `curses.wrapper()`.

  - функція в `unittest.TestCase.addCleanup()`.

  - fn у методі `submit()` `concurrent.futures.ThreadPoolExecutor` і `concurrent.futures.ProcessPoolExecutor`.

  - зворотний виклик у `contextlib.ExitStack.callback()`, `contextlib.AsyncExitStack.callback()` і `contextlib.AsyncExitStack.push_async_callback()`.

  - c і typeid у методі `create()` `multiprocessing.managers.Server` і `multiprocessing.managers.SharedMemoryServer`.

  - obj у `weakref.finalize()`.

  У майбутніх випусках Python вони будуть позиційними лише. (Надав Сергій Сторчака в bpo-36492.)

## Видалення API та функцій

З Python 3.8 видалено наступні функції та API:

- Starting with Python 3.3, importing ABCs from `collections` was deprecated, and importing should be done from `collections.abc`. Being able to import from collections was marked for removal in 3.8, but has been delayed to 3.9. (See bpo-36952.)

- Модуль `macpath`, застарілий у Python 3.7, було видалено. (Надав Віктор Стіннер у bpo-35471.)

- Функцію `platform.popen()` було видалено після того, як вона була застарілою з Python 3.3: замість неї використовуйте `os.popen()`. (Надав Віктор Стіннер у bpo-35345.)

- Функцію `time.clock()` було видалено після того, як вона була застарілою з Python 3.3: використовуйте замість неї `time.perf_counter()` або `time.process_time()`, залежно від ваших вимог, щоб добре працювати - визначена поведінка. (Надано Матіасом Бюссонньєром у bpo-36895.)

- Сценарій `pyvenv` було видалено на користь `python3.8 -m venv`, щоб допомогти усунути плутанину щодо того, до якого інтерпретатора Python прив’язаний сценарій `pyvenv`. (Надав Бретт Кеннон у bpo-25427.)

- `parse_qs`, `parse_qsl`, and `escape` are removed from the `cgi` module. They are deprecated in Python 3.2 or older. They should be imported from the `urllib.parse` and `html` modules instead.

- Функцію `filemode` видалено з модуля `tarfile`. Він не задокументований і не підтримується, починаючи з Python 3.3.

- Конструктор `XMLParser` більше не приймає аргумент html. Це ніколи не мало ефекту та було застарілим у Python 3.4. Усі інші параметри тепер лише для ключових слів. (Надав Сергій Сторчака в bpo-29209.)

- Видалено метод `doctype()` `XMLParser`. (Надав Сергій Сторчака в bpo-29209.)

- Кодек «unicode_internal» видалено. (Надано Інадою Наокі в bpo-36297.)

- Об’єкти `Cache` і `Statement` модуля `sqlite3` не доступні для користувача. (Надав Авів Паливода в bpo-30262.)

- Аргумент ключового слова `bufsize` `fileinput.input()` і `fileinput.FileInput()`, який ігнорувався та не підтримувався з Python 3.6, було видалено. bpo-36952 (Надав Матіас Бюссонньє.)

- Функції `sys.set_coroutine_wrapper()` і `sys.get_coroutine_wrapper()`, які застаріли в Python 3.7, видалено; bpo-36933 (Надав Матіас Бюссонньє.)

## Перенесення на Python 3.8

У цьому розділі наведено описані раніше зміни та інші виправлення помилок, які можуть потребувати змін у вашому коді.

### Зміни в поведінці Python

- Вирази yield (як `yield`, так і `yield from` пункти тепер заборонені у виразах розуміння та генераторі (окрім ітераційного виразу в крайньому лівому пункті `for`). (Надав Сергій Сторчака в bpo-10544.)

- Тепер компілятор створює `SyntaxWarning`, коли перевірки ідентичності (`is` і `is not`) використовуються з певними типами літералів (наприклад, рядки, числа). Вони часто можуть працювати випадково в CPython, але не гарантуються специфікацією мови. Застереження рекомендує користувачам замість цього використовувати тести рівності (`==` і `!=`). (Надав Сергій Сторчака в bpo-34850.)

- Інтерпретатор CPython може ковтати винятки за деяких обставин. У Python 3.8 це відбувається в меншій кількості випадків. Зокрема, винятки, викликані під час отримання атрибута зі словника типів, більше не ігноруються. (Надав Сергій Сторчака в bpo-35459.)

- Видалено реалізації `__str__` із вбудованих типів `bool`, `int`, `float`, `complex` і кількох класів зі стандартної бібліотеки. Тепер вони успадковують `__str__()` від `object`. Як наслідок, визначення методу `__repr__()` у підкласі цих класів вплине на їхнє представлення рядків. (Надав Сергій Сторчака в bpo-36793.)

- On AIX, `sys.platform` doesn’t contain the major version anymore. It is always `'aix'`, instead of `'aix3'` .. `'aix7'`. Since older Python versions include the version number, so it is recommended to always use `sys.platform.startswith('aix')`. (Contributed by M. Felt in bpo-36588.)

- `PyEval_AcquireLock()` and `PyEval_AcquireThread()` now terminate the current thread if called while the interpreter is finalizing, making them consistent with `PyEval_RestoreThread()`, `Py_END_ALLOW_THREADS()`, and `PyGILState_Ensure()`. If this behavior is not desired, guard the call by checking `_Py_IsFinalizing()` or `sys.is_finalizing()`. (Contributed by Joannah Nanjekye in bpo-36475.)

### Зміни в API Python

- Функція `os.getcwdb()` тепер використовує кодування UTF-8 у Windows, а не кодову сторінку ANSI: див. PEP 529 для обґрунтування. Ця функція більше не підтримується в Windows. (Надав Віктор Стіннер у bpo-37412.)

- `subprocess.Popen` тепер може використовувати `os.posix_spawn()` у деяких випадках для кращої продуктивності. У підсистемі Windows для Linux і емуляції користувача QEMU конструктор `Popen`, що використовує `os.posix_spawn()`, більше не створює виняток для таких помилок, як «відсутня програма». Натомість дочірній процес завершується помилкою з ненульовим `returncode`. (Надано Джоанною Нанджекі та Віктором Стіннером у bpo-35537.)

- Аргумент preexec_fn * `subprocess.Popen` більше не сумісний із субінтерпретаторами. Використання параметра у субінтерпретаторі тепер викликає `RuntimeError`. (Надано Еріком Сноу у bpo-34651, змінено Крістіаном Хаймсом у bpo-37951.)

- Метод `imap.IMAP4.logout()` більше не ігнорує довільні винятки. (Надав Віктор Стіннер у bpo-36348.)

- Функцію `platform.popen()` було видалено після того, як вона була застарілою з Python 3.3: замість неї використовуйте `os.popen()`. (Надав Віктор Стіннер у bpo-35345.)

- Функція `statistics.mode()` більше не створює виняток, коли їй надаються мультимодальні дані. Натомість він повертає перший режим, який зустрічається у вхідних даних. (Надав Реймонд Геттінгер у bpo-35892.)

- Метод `selection()` класу `tkinter.ttk.Treeview` більше не приймає аргументи. Його використання з аргументами для зміни вибору було застарілим у Python 3.6. Використовуйте спеціалізовані методи, такі як `selection_set()` для зміни вибору. (Надав Сергій Сторчака в bpo-31508.)

- Методи `writexml()`, `toxml()` і `toprettyxml()` `xml.dom.minidom` і метод `write()` `xml. etree`, тепер збереже порядок атрибутів, указаний користувачем. (Надано Дієго Рохасом і Раймондом Геттінгером у bpo-34160.)

- База даних `dbm.dumb`, відкрита з прапорцями `'r'` тепер доступна лише для читання. `dbm.dumb.open()` з прапорцями `'r'` і `'w'` більше не створює базу даних, якщо вона не існує. (Надав Сергій Сторчака в bpo-32749.)

- Метод `doctype()`, визначений у підкласі `XMLParser` більше не буде викликатися та видасть `RuntimeWarning` замість `DeprecationWarning`. Визначте метод `doctype()` на цільовому об’єкті для обробки XML-декларації doctype. (Надав Сергій Сторчака в bpo-29209.)

- Помилка `RuntimeError` тепер виникає, коли спеціальний метаклас не надає запис `__classcell__` у просторі імен, переданому в `type.__new__`. `DeprecationWarning` було видано в Python 3.6–3.7. (Надав Сергій Сторчака в bpo-23722.)

- Клас `cProfile.Profile` тепер можна використовувати як контекстний менеджер. (Надав Скотт Сандерсон у bpo-29235.)

- `shutil.copyfile()`, `shutil.copy()`, `shutil.copy2()`, `shutil.copytree()` і `shutil.move()` використовують спеціальну для платформи «швидку -copy» системні виклики (див. розділ Залежні від платформи ефективні операції копіювання).

- `shutil.copyfile()` розмір буфера за замовчуванням у Windows змінено з 16 KiB на 1 MiB.

- Структура `PyGC_Head` повністю змінилася. Весь код, який торкався члена структури, слід переписати. (Див. bpo-33597.)

- Структуру `PyInterpreterState` було переміщено у «внутрішні» файли заголовків (зокрема, Include/internal/pycore_pystate.h). Непрозорий `PyInterpreterState` все ще доступний як частина публічного API (і стабільного ABI). У документах зазначено, що жодне з полів структури не є відкритим, тому ми сподіваємось, що ніхто ними не користувався. Однак, якщо ви покладаєтеся на одне або кілька з цих приватних полів і не маєте альтернативи, будь ласка, відкрийте проблему BPO. Ми допоможемо вам налаштувати (можливо, включаючи додавання функцій доступу до публічного API). (Див. bpo-35886.)

- Метод `mmap.flush()` тепер повертає `None` у разі успіху та викликає виняток у разі помилки на всіх платформах. Раніше його поведінка залежала від платформи: ненульове значення поверталося в разі успіху; нуль було повернуто через помилку під Windows. У разі успіху було повернуто нульове значення; виняток було викликано помилкою під Unix. (Надано Berker Peksag у bpo-2122.)

- Модулі `xml.dom.minidom` і `xml.sax` більше не обробляють зовнішні сутності за замовчуванням. (Надав Крістіан Хеймс у bpo-17239.)

- Видалення ключа з доступної лише для читання бази даних `dbm` (`dbm.dumb`, `dbm.gnu` або `dbm.ndbm`) викликає `error` (`dbm.dumb.error`, `dbm.gnu.error` або `dbm.ndbm.error`) замість `KeyError`. (Надав Xiang Zhang у bpo-33106.)

- Спрощений AST для літералів. Усі константи будуть представлені як екземпляри `ast.Constant`. Створення екземплярів старих класів `Num`, `Str`, `Bytes`, `NameConstant` і `Ellipsis` поверне екземпляр `Constant`. (Надав Сергій Сторчака в bpo-32892.)

- `expanduser()` у Windows тепер надає перевагу змінній середовища `USERPROFILE` і не використовує `HOME`, яка зазвичай не встановлюється для звичайних облікових записів користувачів. (Надав Ентоні Соттіле в bpo-36264.)

- Виняток `asyncio.CancelledError` тепер успадковується від `BaseException`, а не від `Exception` і більше не успадковується від `concurrent.futures.CancelledError`. (Надав Юрій Селіванов у bpo-32528.)

- Функція `asyncio.wait_for()` тепер правильно очікує на скасування під час використання екземпляра `asyncio.Task`. Раніше, після досягнення тайм-ауту, він скасовувався та негайно повертався. (Надав Елвіс Пранскявічус у bpo-32751.)

- Функція `asyncio.BaseTransport.get_extra_info()` тепер повертає безпечний для використання об’єкт socket, коли „socket“ передається в параметр name. (Надав Юрій Селіванов у bpo-37027.)

- `asyncio.BufferedProtocol` перейшов на стабільний API.

- Залежності DLL для модулів розширення та DLL, завантажених за допомогою `ctypes` у Windows, тепер вирішуються більш безпечно. На наявність залежностей під час завантаження шукаються лише системні шляхи, каталог, що містить файл DLL або PYD, і каталоги, додані за допомогою `add_dll_directory()`. Зокрема, `PATH` і поточний робочий каталог більше не використовуються, і їх зміни більше не впливатимуть на нормальну роздільну здатність DLL. Якщо ваша програма покладається на ці механізми, вам слід перевірити `add_dll_directory()` і, якщо вона існує, використати її для додавання каталогу DLLs під час завантаження бібліотеки. Зауважте, що користувачам Windows 7 потрібно буде переконатися, що Windows Update KB2533623 інстальовано (це також перевіряє інсталятор). (Надав Стів Дауер у bpo-36085.)

- Файли заголовків і функції, пов’язані з pgen, були видалені після заміни на чисту реалізацію Python. (Надав Пабло Галіндо в bpo-36623.)

- `types.CodeType` має новий параметр у другій позиції конструктора (posonlyargcount) для підтримки лише позиційних аргументів, визначених у PEP 570. Перший аргумент (argcount) тепер представляє загальну кількість позиційних аргументів (включаючи лише позиційні аргументи). Новий метод `replace()` `types.CodeType` можна використовувати, щоб зробити код готовим до майбутнього.

- Параметр `digestmod` для `hmac.new()` більше не використовує дайджест MD5 за замовчуванням.

### Зміни в C API

- The `PyCompilerFlags` structure got a new cf_feature_version field. It should be initialized to `PY_MINOR_VERSION`. The field is ignored by default, and is used if and only if `PyCF_ONLY_AST` flag is set in cf_flags. (Contributed by Guido van Rossum in bpo-35766.)

- The `PyEval_ReInitThreads()` function has been removed from the C API. It should not be called explicitly: use `PyOS_AfterFork_Child()` instead. (Contributed by Victor Stinner in bpo-36728.)

- В Unix розширення C більше не пов’язані з libpython, за винятком Android і Cygwin. Коли Python вбудовано, `libpython` має завантажуватися не з `RTLD_LOCAL`, а `RTLD_GLOBAL`. Раніше за допомогою `RTLD_LOCAL` було неможливо завантажити розширення C, які не були пов’язані з `libpython`, як-от розширення C стандартної бібліотеки, створеної розділом `*shared*` `Modules/Setup`. (Надав Віктор Стіннер у bpo-21536.)

- Використання варіантів форматів `#` під час аналізу чи побудови значення (наприклад, `PyArg_ParseTuple()`, `Py_BuildValue()`, `PyObject_CallFunction()` тощо) без Визначений `PY_SSIZE_T_CLEAN` тепер викликає `DeprecationWarning`. Його буде видалено в 3.10 або 4.0. Прочитайте Розбір аргументів і створення значень для деталей. (Надано Інадою Наокі в bpo-36381.)

- Екземпляри типів, виділених у купі (наприклад, створених за допомогою `PyType_FromSpec()`) містять посилання на свій об’єкт типу. Збільшення кількості посилань на ці типи об’єктів було переміщено з `PyType_GenericAlloc()` до функцій більш низького рівня, `PyObject_Init()` і `PyObject_INIT()`. Це змушує типи, створені через `PyType_FromSpec()`, поводитися як інші класи в керованому коді.

  Statically allocated types are not affected.

  У переважній більшості випадків побічних ефектів бути не повинно. Однак типи, які вручну збільшують кількість посилань після виділення екземпляра (можливо, щоб обійти помилку), тепер можуть стати безсмертними. Щоб уникнути цього, ці класи повинні викликати Py_DECREF для об’єкта типу під час звільнення примірника.

  Щоб правильно перенести ці типи в 3.8, застосуйте такі зміни:

  - Remove `Py_INCREF` on the type object after allocating an instance - if any. This may happen after calling `PyObject_New()`, `PyObject_NewVar()`, `PyObject_GC_New()`, `PyObject_GC_NewVar()`, or any other custom allocator that uses `PyObject_Init()` or `PyObject_INIT()`.

    приклад:

        static foo_struct *
        foo_new(PyObject *type) {
            foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type);
            if (foo == NULL)
                return NULL;
        #if PY_VERSION_HEX < 0x03080000
            // Workaround for Python issue 35810; no longer necessary in Python 3.8
            PY_INCREF(type)
        #endif
            return foo;
        }

  - Переконайтеся, що всі спеціальні функції `tp_dealloc` типів, виділених у купі, зменшують кількість посилань на тип.

    приклад:

        static void
        foo_dealloc(foo_struct *instance) {
            PyObject *type = Py_TYPE(instance);
            PyObject_GC_Del(instance);
        #if PY_VERSION_HEX >= 0x03080000
            // This was not needed before Python 3.8 (Python issue 35810)
            Py_DECREF(type);
        #endif
        }

  (Надав Едді Елізондо в bpo-35810.)

- Для MSVC реалізовано макрос `Py_DEPRECATED()`. Тепер макрос потрібно розмістити перед назвою символу.

  приклад:

      Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);

  (Надав Закері Шпітц у bpo-33407.)

- The interpreter does not pretend to support binary compatibility of extension types across feature releases, anymore. A `PyTypeObject` exported by a third-party extension module is supposed to have all the slots expected in the current Python version, including `tp_finalize` (`Py_TPFLAGS_HAVE_FINALIZE` is not checked anymore before reading `tp_finalize`).

  (Надав Антуан Пітру в bpo-32388.)

- The functions `PyNode_AddChild()` and `PyParser_AddToken()` now accept two additional `int` arguments end_lineno and end_col_offset.

- Файл `libpython38.a`, який дозволяє інструментам MinGW зв’язуватися безпосередньо з `python38.dll`, більше не входить до звичайного дистрибутива Windows. Якщо вам потрібен цей файл, його можна створити за допомогою інструментів `gendef` і `dlltool`, які є частиною пакету MinGW binutils:

      gendef - python38.dll > tmp.def
      dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a

  Розташування встановленого `pythonXY.dll` залежатиме від параметрів встановлення, версії та мови Windows. Перегляньте Використання Python у Windows для отримання додаткової інформації. Отриману бібліотеку слід розмістити в тому самому каталозі, що й `pythonXY.lib`, який зазвичай є каталогом `libs` у вашій установці Python.

  (Надав Стів Дауер у bpo-37351.)

### Зміни байт-коду CPython

- Цикл інтерпретатора було спрощено шляхом переміщення логіки розгортання стека блоків у компілятор. Тепер компілятор видає чіткі інструкції для налаштування стека значень і виклику коду очищення для `break`, `continue` і `return`.

  Removed opcodes `BREAK_LOOP`, `CONTINUE_LOOP`, `SETUP_LOOP` and `SETUP_EXCEPT`. Added new opcodes `ROT_FOUR`, `BEGIN_FINALLY`, `CALL_FINALLY` and `POP_FINALLY`. Changed the behavior of `END_FINALLY` and `WITH_CLEANUP_START`.

  (Надано Марком Шенноном, Антуаном Пітру та Сергієм Сторчакою в bpo-17611.)

- Додано новий код операції `END_ASYNC_FOR` для обробки винятків, які виникають під час очікування наступного елемента в `async for` циклі. (Надав Сергій Сторчака в bpo-33041.)

- `MAP_ADD` тепер очікує значення як перший елемент у стеку та ключ як другий елемент. Цю зміну було внесено, щоб ключ завжди оцінювався перед значенням у словнику, як запропоновано PEP 572. (Надав Йорн Гайслер у bpo-35224.)

### Демонстрації та інструменти

Додано тестовий сценарій для визначення часу різними способами доступу до змінних: `Tools/scripts/var_access_benchmark.py`. (Надав Реймонд Геттінгер у bpo-35884.)

Ось підсумок покращень продуктивності з Python 3.3:

    Python version                       3.3     3.4     3.5     3.6     3.7     3.8
    --------------                       ---     ---     ---     ---     ---     ---

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

    Variable and attribute write access:
        write_local                      4.6     8.7     9.3     5.5     5.3     4.3
        write_nonlocal                   7.3    10.5    11.1     5.6     5.5     4.7
        write_global                    15.9    19.7    21.2    18.0    18.0    15.8
        write_classvar                  81.9    92.9    96.0   104.6   102.1    39.2
        write_instancevar               36.4    44.6    45.8    40.0    38.9    35.5
        write_instancevar_slots         28.7    35.6    36.1    27.3    26.6    25.7

    Data structure read access:
        read_list                       19.2    24.2    24.5    20.8    20.8    19.0
        read_deque                      19.9    24.7    25.5    20.2    20.6    19.8
        read_dict                       19.7    24.3    25.7    22.3    23.0    21.0
        read_strdict                    17.9    22.6    24.3    19.5    21.2    18.9

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

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

    Timing loop:
        loop_overhead                    0.3     0.5     0.6     0.4     0.3     0.3

The benchmarks were measured on an Intel® Core™ i7-4960HQ processor running the macOS 64-bit builds found at python.org. The benchmark script displays timings in nanoseconds.

## Помітні зміни в Python 3.8.1

Через серйозні проблеми безпеки параметр reuse_address `asyncio.loop.create_datagram_endpoint()` більше не підтримується. Це через поведінку опції сокета `SO_REUSEADDR` в UDP. Для отримання додаткової інформації див. документацію для `loop.create_datagram_endpoint()`. (Надано Кайлом Стенлі, Антуаном Пітру та Юрієм Селівановим у bpo-37228.)

## Помітні зміни в Python 3.8.8

Earlier Python versions allowed using both `;` and `&` as query parameter separators in `urllib.parse.parse_qs()` and `urllib.parse.parse_qsl()`. Due to security concerns, and to conform with newer W3C recommendations, this has been changed to allow only a single separator key, with `&` as the default. This change also affects `cgi.parse()` and `cgi.parse_multipart()` as they use the affected functions internally. For more details, please see their respective documentation. (Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in bpo-42967.)

## Помітні зміни в Python 3.8.12

Починаючи з Python 3.8.12, модуль `ipaddress` більше не приймає жодних початкових нулів у рядках адрес IPv4. Початкові нулі є неоднозначними та інтерпретуються деякими бібліотеками як вісімкове позначення. Наприклад, застаріла функція `socket.inet_aton()` розглядає початкові нулі як вісімкове позначення. glibc реалізація сучасного `inet_pton()` не приймає жодних початкових нулів.

(Спочатку надано Крістіаном Хеймсом у bpo-36384, а також перенесено до 3.8 Ахрафом Мерзукі.)