Что нового в Python 3.8

Редактор:Raymond Hettinger

Эта статья объясняет новые возможности в Python 3.8, по сравнению с 3.7. Подробную информацию см. в разделе changelog.

Python 3.8 вышел 14 октября 2019 года.

Резюме - основные моменты выпуска

Новые функции

Выражения назначения

Существует новый синтаксис :=, который присваивает значения переменным как части большего выражения. Он ласково известен как «оператор моржей» благодаря своему сходству с глазами и бивнями моржа.

В этом примере выражение назначения помогает постараться не называть 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-loops, которые вычисляют значение для проверки завершения цикла и затем снова нуждаются в том же самом значении в теле цикла:

# 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]

Постарайтесь ограничить использование оператора моржей чисткой случаев, которые уменьшают сложность и улучшают удобочитаемость.

Полное описание см. в разделе PEP 572.

(Предоставлено Emily Morehouse в bpo-35224.)

Только позиционные параметры

Существует новый синтаксис параметра функции /, указывающий, что некоторые параметры функции должны быть указаны позиционно и не могут использоваться в качестве ключевых аргументов. Это то же обозначение, которое показывает help() для функций C, аннотированных с помощью инструмента Клиники споров Ларри Хастингса.

В следующем примере параметры 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 не должен быть ключевым аргументом
f(10, 20, 30, 40, 50, f=60)           # e должен быть ключевым аргументом

Один из вариантов использования этой нотации заключается в том, что она позволяет чистым Python функциям полностью эмулировать поведение существующих C-кодированных функций. Например, встроенная функция divmod() не принимает аргументы ключевой:

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

Другой вариант использования - исключить аргументы ключевой, если имя параметра не полезно. Например, у встроенной функции len() есть сигнатура len(obj, /). Это исключает неудобные вызовы, такие как:

len(obj='hello')  # Ключевой аргумент "obj" ухудшает читабельность

Еще одним преимуществом маркировки параметра как позиционного является то, что он позволяет изменять имя параметра в будущем без риска нарушения клиентского код. Например, в модуле statistics имя параметра 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 и b используются двумя способами
10 20 {'a': 1, 'b': 2, 'c': 3}

Это значительно упрощает внедрение функций и методы, который должен принять произвольные аргументы ключевой. Например, вот выдержка из код в модуле collections:

class Counter(dict):

    def __init__(self, iterable=None, /, **kwds):
        # Примечание "iterable" является возможным ключевым аргументом

Полное описание см. в разделе PEP 570.

(Представлен Pablo Galindo в bpo-36540.)

Параллельный кэш файловой системы для скомпилированных файлов байт-кодов

Новая настройка PYTHONPYCACHEPREFIX (также доступный как -X pycache_prefix) настраивает неявный bytecode кэш, чтобы использовать отдельное параллельное дерево файловой системы, а не дефолт подкаталоги __pycache__ в рамках каждого исходного справочника.

О местоположении кэша сообщают в sys.pycache_prefix (None указывает на местоположение по умолчанию в подкаталогах __pycache__).

(Вклад Carl Meyer в bpo-33499.)

В отладочной сборке используется тот же ABI, что и в версии build

Теперь Python использует тот же ABI, независимо от того, встроен ли он в режиме выпуска или отладки. В Unix, когда Python построен в режиме отладки, теперь можно загружать расширения C, построенные в режиме выпуска, и расширения C, построенные с использованием стабильного ABI.

Сборки версий и отладки теперь совместимы с ABI: определение макроса Py_DEBUG больше не подразумевает макрос Py_TRACE_REFS, который вводит единственную несовместимость ABI. Макрос Py_TRACE_REFS, который добавляет функцию sys.getobjects() и переменную окружения PYTHONDUMPREFS, может быть установлен, используя новый ./configure --with-trace-refs, строят выбор. (Представлен Victor Stinner в bpo-36465.)

В Unix расширения C больше не связаны с libpython, кроме Android и Cygwin. Для статически связанного Python теперь возможно загрузить построенное использование расширения C общей библиотеки Python. (Представлен Victor Stinner в bpo-21536.)

На Unix, когда Python построен в режиме отладки, импорт теперь также ищет расширения C, собранные в режиме выпуска и для расширений C, собранных со стабильным ABI. (Представлен Victor Stinner в bpo-36722.)

Чтобы встроить Python в приложение, необходимо передать python3-config --libs --embed новый параметр --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, случаи которых обрабатываются сценарием); это изменение не совместимо по назначению. (Представлен Victor Stinner в bpo-36721.)

Поддержка f-строки = для самостоятельного документирования выражений и отладки

Добавлен спецификатор = к f-строка. Такая 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-строк позволяют больше управлять отображением результата выражения:

>>> 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

(Представлен Eric V. Smith и Larry Hastings в bpo-36817.)

PEP 578: Python хуки аудита времени выполнения

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

Полную информацию см. в разделе PEP 578.

PEP 587: Инициализация конфигурации Python

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

Новые структуры:

Новый функции:

Этот PEP также добавляет поля _PyRuntimeState.preconfig (тип PyPreConfig) и PyInterpreterState.config (тип PyConfig) к этим внутренним структурам. PyInterpreterState.config становится новой ссылочной конфигурацией, заменяя глобальные переменные конфигурации и другие частные переменные.

Документацию см. в разделе Конфигурация инициализации Python.

Полное описание см. в разделе PEP 587.

(Представлен Victor Stinner в bpo-36763.)

Vectorcall: протокол быстрого вызова для CPython

Протокол «vectorcall» добавляется в API Python/C. Предполагается формализовать существующие оптимизации, которые уже были сделаны для различных классы. Этот протокол может использоваться любым типом внутренней линии, реализующим вызываемый абонент.

В настоящее время этот документ носит предварительный характер. Цель состоит в том, чтобы сделать его полностью public в Python 3.9.

Полное описание см. в разделе PEP 590.

(Предоставлено Jeroen Demeyer и Mark Shannon в bpo-36974.)

Pickle протокол 5 с внеполосными буферами данных

Когда pickle - используемый, чтобы передать большие данные между процессами Python, чтобы использовать в своих интересах многоядерный или мультимашинная обработка, важно оптимизировать передачу, уменьшая копии памяти, и возможно применяя пользовательские методы, такие как зависимое от данных сжатие.

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

Полное описание см. в разделе PEP 574.

(Представлен Antoine Pitrou в bpo-36785.)

Другие языковые изменения

  • A continue инструкция был незаконным в finally клаузуле из-за проблемы с реализацией. В Python 3.8 это ограничение было снято. (Представлен Serhiy Storchaka в bpo-32489.)

  • Типы bool, int и fractions.Fraction теперь имеют as_integer_ratio() метод, как в float и decimal.Decimal. Это дополнительное расширение API позволяет записывать numerator, denominator = x.as_integer_ratio() и работать в нескольких числовых типах. (Вклад Lisa Roach в bpo-33073 и Raymond Hettinger в bpo-37819.)

  • Конструкторы int, float и complex теперь будут использовать специальный метод __index__(), если он доступен и соответствующие метод __int__(), __float__() или __complex__() недоступны. (Представлен Serhiy Storchaka в bpo-20092.)

  • Добавлена поддержка \N{name} побегов в 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
    

    (Предоставлено Jonathan Eunice и Serhiy Storchaka в bpo-30688.)

  • Dict и dictviews теперь могут повторяться в обратном порядке вставки с использованием reversed(). (Предоставлено Rémi Lapeyre в bpo-33462.

  • Синтаксис, разрешенный для имен ключевой в вызовах функций, был дополнительно ограничен. В частности, f((keyword)=arg) больше не допускается. Она никогда не предназначалась для того, чтобы разрешить более чем голое имя в левой части термина уступки аргумента ключевой. (Представлен Benjamin Peterson в bpo-34641.)

  • Обобщенная повторяемая распаковка в yield и return инструкции больше не требует круглых скобок приложения. Это приводит синтаксис yield и return в лучшее соответствие с обычным синтаксисом назначения:

    >>> def parse(family):
            lastname, *members = family.split()
            return lastname.upper(), *members
    
    >>> parse('simpsons homer marge bart lisa sally')
    ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'sally')
    

    (Вклад David Cuthbert и Jordan Chapman в bpo-32117.)

  • Если запятая пропущена в код, например [(10, 20) (30, 40)], компилятор отображает SyntaxWarning с полезным предложением. Это улучшает наличие TypeError, указывающего на то, что первый кортеж не был вызываемым. (Представлен Serhiy Storchaka в bpo-15248.)

  • Арифметические операции между подклассы datetime.date или datetime.datetime и datetime.timedelta объектами теперь возвращают сущность подкласса, а не базовой класс. Это также затрагивает тип возвращения операций, внедрение которых (прямо или косвенно) использует арифметику datetime.timedelta, такую как astimezone(). (Предоставлено Paul Ganssle в bpo-32417.)

  • Когда Python интерпретатор прерван Ctrl-C (SIGINT), и получающееся исключение KeyboardInterrupt не поймано, процесс Python теперь выходит через сигнал SIGINT или с правильным выходом код, таким образом, что процесс запроса может обнаружить, что это умерло из-за Ctrl-C. Оболочки POSIX и Windows используют это для правильного завершения сценариев в интерактивных сеансах. (Вклад Google через Gregory P. Smith в 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'
    

    (Представлен Victor Stinner в bpo-37032.)

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

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

    Модульные обратные возникают в решении linear Diophantine equations. Например, чтобы найти целочисленные решения для 4258𝑥 + 147𝑦 = 369, сначала переписать как 4258𝑥 369 (mod 147) затем решить:

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

    (Представлен Mark Dickinson в 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'}
    

    (Представлен Jörn Heissler в bpo-35224.)

  • Теперь object.__reduce__() метод может вернуть кортеж длиной от двух до шести элементов. Раньше предельным было пять. Новый опциональный шестой элемент является вызываемым с (obj, state) сигнатура. Это позволяет напрямую управлять поведением обновления состояния определенного объекта. Если не None, у этого подлежащего выкупу будет приоритет над __setstate__() метод объекта. (Представлен Pierre Glaser и Olivier Grisel в 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')]
    

    (Вклад Barry Warsaw и Jason R. Coombs в bpo-34632.)

Улучшение модулей

ast

Узлы AST теперь имеют атрибуты end_lineno и end_col_offset, которые дают точное расположение конца узла. (Это только относится к узлам, у которых есть lineno и col_offset атрибуты.)

Новая функция ast.get_source_segment() возвращает источник код для определенного узла AST.

(Представлен Ivan Levkivskyi в bpo-33416.)

Функция ast.parse() имеет несколько новых флагов:

  • type_comments=True приводит к возврату текста комментариев типа PEP 484 и PEP 526, связанных с определенными узлами AST;
  • mode='func_type' может быть используемый для разбора PEP 484 «сигнатура type comments» (возвращаемых для определения функции узлы AST);
  • feature_version=(3, N) позволяет указать более раннюю версию Python 3. Например, feature_version=(3, 4) будет рассматривать async и await как незарезервированные слова.

(Представлен Guido van Rossum в bpo-35766.)

asyncio

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

import asyncio

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

asyncio.run(main())

Это roughly эквивалентно:

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() должен быть предпочтительным способом запуска программ asyncio.

(Внесено Yury Selivanov в 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

(Представлен Yury Selivanov в bpo-37028.)

Исключение asyncio.CancelledError теперь наследуется от BaseException, а не от Exception, и больше не наследуется от concurrent.futures.CancelledError. (Внесено Юрием Селивановым в bpo-32528.)

На Windows дефолт событийный цикл - теперь ProactorEventLoop. (Представлен Victor Stinner в bpo-34687.)

ProactorEventLoop теперь также поддерживает UDP. (Предоставлено Adam Meily и Andrew Svetlov в bpo-29883.)

Теперь ProactorEventLoop может прерываться командой KeyboardInterrupt («CTRL+C»). (Представлен Vladimir Matveev в bpo-23057.)

Добавлено asyncio.Task.get_coro() для получения обернутой корутины в пределах asyncio.Task. (Вклад Alex Grönholm в bpo-36999.)

Теперь задачи Asyncio можно именовать либо путем передачи аргумента name ключевой в asyncio.create_task() или метод create_task() событийный цикл, либо путем вызова метода set_name() метод в объекте задачи. Имя задачи видимо в продукции repr() asyncio.Task и может также быть восстановлено, используя get_name() метод. (Представлен Alex Grönholm в bpo-34270.)

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

builtins

Встроенное compile() было улучшено, чтобы принять флаг ast.PyCF_ALLOW_TOP_LEVEL_AWAIT. Если этот новый флаг передан, compile() будет разрешать конструкции верхнего уровня await, async for и async with, которые обычно считаются недопустимым синтаксисом. Затем может быть возвращен асинхронный объект код, помеченный флагом CO_COROUTINE. (Предоставлено Matthias Bussonnier в bpo-34616)

collections

Теперь _asdict() метод для collections.namedtuple() возвращает dict вместо collections.OrderedDict. Это работает, потому что регулярные документы гарантировали порядок с Python 3.7. Если требуются дополнительные функции OrderedDict, предлагаемое исправление должно привести результат к требуемому типу: OrderedDict(nt._asdict()). (Представлен Raymond Hettinger в bpo-35864.)

cProfile

cProfile.Profile класс может теперь быть используемый как менеджером контекст. Выполните профилирование блока код:

import cProfile

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

(Предоставлено Scott Sanderson в bpo-29235.)

csv

Теперь csv.DictReader возвращает сущности dict вместо collections.OrderedDict. Инструмент теперь быстрее и использует меньше памяти, сохраняя при этом порядок полей. (Представлен Michael Selik в bpo-34003.)

curses

Добавлена новая переменная, содержащая информацию о структурированной версии для библиотеки ncurses: ncurses_version. (Представлен Serhiy Storchaka в bpo-31680.)

ctypes

В Windows CDLL и подклассы теперь принимают параметр winmode, чтобы указать флаги для базового вызова LoadLibraryEx. Флаги по умолчанию устанавливаются для загрузки только зависимостей DLL из надежных расположений, включая путь, по которому хранится DLL (если для загрузки начальной DLL-библиотеки используемый полный или частичный путь), и пути, добавляемые add_dll_directory(). (Предоставлено Steve Dower в bpo-36085.)

datetime

Добавлены новые альтернативные конструкторы datetime.date.fromisocalendar() и datetime.datetime.fromisocalendar(), которые строят объекты date и datetime соответственно из года ISO, номера недели и дня недели; это обратная величина для каждого класса isocalendar метод. (Предоставлено Paul Ganssle в bpo-36004.)

functools

functools.lru_cache() может теперь быть используемый как прямым декоратором, а не как функция, возвратив декоратор. Так что оба они теперь поддерживаются:

@lru_cache
def f(x):
    ...

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

(Представлен Raymond Hettinger в 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)

(Представлен Carl Meyer в bpo-21145)

Добавлен новый декоратор functools.singledispatchmethod(), который преобразует методы в общие функции с помощью одиночной диспетчеризации:

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]

(Представлен Ethan Smith в bpo-32380)

gc

Теперь get_objects() может получить необязательный параметр generation, указывающий генерацию для получения объектов. (Представлен Pablo Galindo в bpo-36016.)

gettext

Добавлены pgettext() и его варианты. (Вклад Franz Glasner, Éric Araujo и Cheryl Sabella в bpo-2504.)

gzip

Добавлен параметр mtime в gzip.compress() для воспроизводимого вывода. (Внесён Guo Ci Teo в bpo-34898.)

Исключение BadGzipFile теперь поднято вместо OSError для определенных типов инвалида или повреждённых gzip файлов. (Вклад Filip Gruszczyński, Michele Orrù и Zackery Spyt в bpo-6584.)

IDLE и idlelib

Вывод по N линиям (по умолчанию 50) сжимается до кнопки. N можно изменить в разделе PyShell на странице общие диалогового окна настройки. Меньше, но, возможно, слишком длинных линий можно сжать, щелкнув правой кнопкой мыши на выходе. Сжатые выходные данные можно развернуть по месту, дважды нажав кнопку или в буфер обмена или в отдельном окне, щелкнув кнопку правой кнопкой мыши. (Внесен Tal Einat в bpo-1529353.)

Добавьте «Run Customized» в меню Run для запуска модуля с настроенными настройками. Все введенные аргументы командной строки добавляются в sys.argv. Они также повторно появляются в поле для следующего настраиваемого прогона. Можно также подавить обычный перезапуск основного модуля Shell. (Вклад Cheryl Sabella, Terry Jan Reedy и других в bpo-5680 и bpo-37627.)

Добавлены дополнительные номера строк для окон редактора IDLE. Окна открываются без номеров строк, если не указано иное на вкладке «Общие» диалогового окна конфигурации. Номера строк для существующего окна отображаются и скрываются в меню «Параметры». (Предоставлено Tal Einat и Saimadhav Heblikarв bpo-17535.)

Уроженцем OS кодировка является теперь используемый для преобразования между объектами Python строки и Tcl. Это позволяет IDLE работать с эмодзи и другими символами, отличными от BMP. Эти символы могут отображаться или копироваться и вставляться в буфер обмена или из него. Преобразование строки из Tcl в Python и обратно теперь никогда не завершается неудачно. (Многие люди работали над этим восемь лет, но проблема была окончательно решена Serhiy Storchaka в bpo-13153.)

Новое в 3.8.1:

Добавлена опция для отключения мигания курсора. (Внесен Закери Спицем в bpo-4603.)

Клавиша Escape теперь закрывает окна завершения простоя. (Вклад Джонни Наджеры в bpo-38944.)

Вышеприведенные изменения были перенесены обратно в версии технического обслуживания 3.7.

Добавлены ключевые слова в списоковое включение имени модуля. (Вклад Терри Дж. Риди в bpo-37765.)

inspect

Функция 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)

(Представлен Raymond Hettinger в bpo-36326.)

io

В режиме разработки (-X env) и при отладочной сборке финализатор io.IOBase регистрирует исключение в случае сбоя close() метод. Исключение по умолчанию игнорируется без предупреждения при построении выпуска. (Представлен Victor Stinner в bpo-18748.)

itertools

Функция itertools.accumulate() добавила аргумент option initial ключевой для указания начального значения:

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

(Внесена Lisa Roach в bpo-34659.)

json.tool

Добавьте опцию --json-lines, чтобы разобрать каждую входную строку как отдельный объект JSON. (Представлен Weipeng Hong в bpo-31553.)

logging

Добавлен ключевой аргумент force logging.basicConfig(), когда установлено в истинный, любые существующие обработчики были свойственны корневому логгеру удалены и закрыты перед выполнением конфигурации, определенной другими аргументами.

Это решает давнюю проблему. Как только вызов логгер или basicConfig() был вызван, последующие звонки в basicConfig() были молча проигнорированы. Это затрудняло обновление, экспериментирование или обучение различных опций конфигурации логирование с помощью интерактивного приглашения или блокнота Jupyter.

(Предложено Raymond Hettinger, реализовано Dong-hee Na и рассмотрено Vinay Sajip в bpo-33897.)

math

Добавлена новая функция math.dist() для вычисления евклидового расстояния между двумя точками. (Представлен Raymond Hettinger в bpo-33089.

Расширена функция math.hypot() для обработки нескольких размеров. Ранее она поддерживала только дело 2-D. (Представлен Raymond Hettinger в bpo-33089.

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

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

(Представлен Pablo Galindo в 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

(Представлен Mark Dickinson в bpo-36887.)

Функция math.factorial() больше не принимает аргументы, не похожие на int. (Внесено Pablo Galindo в bpo-33083.)

mmap

Теперь mmap.mmap класс имеет madvise() метод для доступа к системному вызову madvise(). (Представлен Zackery Spytz в bpo-32941.)

multiprocessing

Добавлен новый модуль multiprocessing.shared_memory. (Представлен Davin Potts в bpo-35813.)

На macOS начинаются spawn, метод - теперь используемый по умолчанию. (Представлен Victor Stinner в bpo-33725.)

os

Добавлена новая функция add_dll_directory() в Windows для предоставления дополнительных путей поиска собственных зависимостей при импорте модулей расширений или загрузке DLL с помощью ctypes. (Предоставлено Steve Dower в bpo-36085.)

Добавлена новая функция os.memfd_create() для переноса memfd_create() syscall. (Представлен 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(), может теперь рассматривать соединения как ссылки.

(Предоставлено Steve Dower в bpo-37834.)

os.path

os.path функции, возвращающие логический результат, такие как exists(), lexists(), isdir(), isfile(), islink() и ismount(), теперь возвращают False вместо увеличения ValueError или его подклассы UnicodeEncodeError и UnicodeDecodeError для путей, которые содержат символы или байты, непредставимые на уровне OS. (Представлен Serhiy Storchaka в bpo-33721.)

expanduser() в Windows теперь предпочитает переменную среды USERPROFILE и не использует HOME, которая обычно не устанавливается для обычных учетных записей пользователей. (Представлен Anthony Sottile в bpo-36264.)

isdir() в Windows больше не возвращает True для ссылки на несуществующий каталог.

realpath() в Windows теперь разрешает точки повторной обработки, включая ссылки и соединения каталогов.

(Предоставлено Steve Dower в bpo-37834.)

pathlib

pathlib.Path методы, возвращающие логический результат, такой как exists(), is_dir(), is_file(), is_mount(), is_symlink(), is_block_device(), is_char_device(), is_fifo(), is_socket(), теперь возвращают False вместо увеличения ValueError или его подкласс UnicodeEncodeError для путей, которые содержат символы, непредставимые на уровне OS. (Представлен Serhiy Storchaka в bpo-33721.)

Добавлено pathlib.Path.link_to(), создающее жесткую связь, указывающую на контур. (Представлен Joannah Nanjekye в bpo-26978)

pickle

Расширения pickle, подклассирующие C-оптимизированные Pickler, теперь могут переопределять логику pickling функций и классы, определяя специальные reducer_override() метод. (Вклад Pierre Glaser и Olivier Grisel в bpo-35900.)

plistlib

Добавленный новый plistlib.UID и включил поддержку чтения и написания набора из двух предметов NSKeyedArchiver-кодированный plists. (Представлен Jon Janzen в bpo-26707.)

pprint

Модуль pprint добавил параметр sort_dicts к нескольким функциям. По умолчанию эти функции продолжают сортировать словари перед визуализацией или печатью. Однако, если sort_dicts установлен в ложный, словари сохраняют порядок, что ключи были вставлены. Это может быть полезно для сравнения с входными данными 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'}

(Вклад Rémi Lapeyre в bpo-30670.)

py_compile

Теперь py_compile.compile() поддерживает бесшумный режим. (Представлен Joannah Nanjekye в bpo-22640.)

shlex

Новая функция shlex.join() действует как инверсия shlex.split(). (Представлен Bo Bayles в bpo-32102.)

shutil

Теперь shutil.copytree() принимает новый ключевой аргумент dirs_exist_ok. (Предоставлено Josh Bronson в bpo-20849.)

shutil.make_archive() теперь не выполняют своих обязательств к современному миру (POSIX.1-2001) формат, чтобы новые архивы улучшили мобильность и соответствие стандартов, унаследованное от соответствующего изменения до модуля tarfile. (Автор: C.A.M. Gerlach в bpo-30661.)

shutil.rmtree() в Windows теперь удаляет соединения каталогов без рекурсивного удаления их содержимого. (Предоставлено Steve Dower в bpo-37834.)

socket

Добавлены функции удобства create_server() и has_dualstack_ipv6() для автоматизации необходимых задач, обычно задействованных при создании серверного сокета, включая прием как IPv4, так и IPv6 подключений на одном и том же сокет. (Автор - Giampaolo Rodolà в bpo-17561.)

Функции socket.if_nameindex(), socket.if_nametoindex() и socket.if_indextoname() реализованы в Windows. (Представлен Zackery Spytz в bpo-37007.)

ssl

Добавленный post_handshake_auth, чтобы включить и verify_client_post_handshake(), чтобы начать идентификацию TLS 1.3 пострукопожатия. (Представлен Christian Heimes в bpo-34670.)

statistics

Добавленный statistics.fmean() как более быстрый вариант с плавающей запятой statistics.mean(). (Представлен Raymond Hettinger и Steven D’Aprano в bpo-35904.)

Добавлено statistics.geometric_mean() (внесено Raymond Hettinger в bpo-27181.)

Добавленный statistics.multimode(), который возвращает список из наиболее распространенных ценностей. (Представлен Raymond Hettinger в bpo-35892.)

Добавлено statistics.quantiles(), которое делит данные или распределение в к настраиваемым интервалам (например, квартили, децили или процентили). (Представлен Raymond Hettinger в bpo-36546.)

Добавленный statistics.NormalDist, инструмент для создания и управления нормальными распределениями случайной переменной. (Представлен Raymond Hettinger в 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

Добавьте новую функцию sys.unraisablehook(), которая может быть переопределена для управления обработкой «неразрешимых исключений». Это называют, когда исключение произошло, но нет никакого пути к Python, чтобы обращаться с ним. Например, когда деструктор вызывает исключение или во время сборки мусора (gc.collect()). (Представлен Victor Stinner в bpo-36829.)

tarfile

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

threading

Добавьте новую функцию threading.excepthook(), которая обрабатывает необученное исключение threading.Thread.run(). Она может быть переопределена для управления обработкой необнаруженных исключений threading.Thread.run(). (Представлен Victor Stinner в bpo-1230540.)

Добавьте новую функцию threading.get_native_id() и функцию native_id атрибут к threading.Thread класс. Они возвращают собственный интегральный идентификатор потока текущего поток, назначенного ядром. Эта функция доступна только на определенных платформах, см. раздел get_native_id для получения дополнительной информации. (Представлен Jake Tesler в bpo-36084.)

tokenize

Модуль tokenize теперь неявно выдает токен NEWLINE, когда ему предоставляется вход, который не имеет конечной новой строки. Это поведение теперь совпадает с тем, что делает внутренний токенизатор C. (Представлен Ammar Askar в bpo-33899.)

tkinter

Добавлены методы selection_from(), selection_present(), selection_range() и selection_to() в tkinter.Spinbox класс. (Внесена Juliette Monsel в bpo-34829.)

Добавлено метод moveto() в tkinter.Canvas класс. (Вклад Juliette Monsel в bpo-23831.)

В tkinter.PhotoImage класс теперь есть transparency_get() и transparency_set() методы. (Представлен Zackery Spytz в bpo-25451.)

time

Добавленные новые часы CLOCK_UPTIME_RAW для macOS 10.12. (Представлен Joannah Nanjekye в bpo-35702.)

typing

Модуль 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(). Простые ABCs, как typing.SupportsInt теперь Protocol подклассы.

  • Новый протокол класс typing.SupportsIndex.

  • Новые функции typing.get_origin() и typing.get_args().

unicodedata

Модуль unicodedata обновлен для использования версии Unicode 12.1.0.

Новая функция is_normalized() может быть используемый для проверки того, что строка находится в определенной нормальной форме, часто гораздо быстрее, чем путем фактической нормализации строка. (Вклад Max Belanger, David Euresti и Greg Price в bpo-32285 и bpo-37966).

unittest

Добавлено AsyncMock для поддержки асинхронной версии Mock. Также добавлены соответствующие новые функции утверждения для тестирования. (Внесена Lisa Roach в bpo-26467).

Добавлены addModuleCleanup() и addClassCleanup(), чтобы unittest поддерживать очистки для setUpModule() и setUpClass(). (Внесена Lisa Roach в bpo-24412.)

Несколько функций mock assert теперь также печатают список фактических вызовов при сбое. (Представлен Petter Strandmark в bpo-35047.)

Модуль unittest получил поддержку coroutines, которые должны быть используемый в качестве тестовых случаев с unittest.IsolatedAsyncioTestCase. (Представлен Andrew Svetlov в 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. (Представлен Brett Cannon в bpo-32718.)

weakref

Прокси-объекты, возвращаемые weakref.proxy(), теперь поддерживают операторы умножения матрицы @ и @= в дополнение к другим числовым операторам. (Представлен Mark Dickinson в bpo-36669.)

xml

Как смягчение по отношению к DTD и извлечению внешнего объекта, модули xml.dom.minidom и xml.sax больше не обрабатывают внешние объекты по умолчанию. (Представлен Christian Heimes в bpo-17239.)

.find*() методы в модуле xml.etree.ElementTree поддерживают подстановочный символ поиска, например {*}tag, который игнорирует пространство имен и {namespace}* который возвращает все теги в данном пространстве имен. (Представлен Stefan Behnel в bpo-28238.)

Модуль xml.etree.ElementTree предоставляет новую функцию –xml.etree.ElementTree.canonicalize(), реализующую C14N 2.0. (Внесён Stefan Behnel в bpo-13611.)

Целевой объект xml.etree.ElementTree.XMLParser может принимать события объявления пространства имен через новые колбэк методы start_ns() и end_ns(). Кроме того, цель xml.etree.ElementTree.TreeBuilder может быть настроена, чтобы обработать события о комментариях и инструкциях по обработке включать их в произведенное дерево. (Представлен Stefan Behnel в bpo-36676 и bpo-36673.)

xmlrpc

Теперь xmlrpc.client.ServerProxy поддерживает дополнительный аргумент headers ключевой для последовательности заголовков HTTP, отправляемых с каждым запросом. Помимо прочего, это позволяет обновить базовую аутентификацию по умолчанию до более быстрой аутентификации сеанса. (Представлен Cédric Krier в документе bpo-35153.)

Оптимизация

  • Модуль subprocess теперь может использовать функцию os.posix_spawn() в некоторых случаях для повышения производительности. В настоящее время он используемый только на macOS и Linux (с использованием glibc 2.24 или новее), если все эти условия выполнены:

    • close_fds равен false;
    • preexec_fn, pass_fds, cwd и start_new_session параметры не установлены;
    • executable путь содержащий каталог.

    (Вклад Joannah Nanjekye и Victor Stinner в bpo-35537.)

  • shutil.copyfile(), shutil.copy(), shutil.copy2(), shutil.copytree() и shutil.move() используют зависящие от платформы «быстрые копии» syscalls в Linux и macOS для более эффективного копирования файла. «быстрое копирование» означает, что операция копирования происходит внутри ядра, избегая использования буферов пользовательского пространства в Python, как в «outfd.write(infd.read()).» на использовании Windows shutil.copyfile() больший размер буфера по умолчанию (1 MiB вместо 16 KiB) и основанный на memoryview() вариант shutil.copyfileobj() является используемый. Ускорение копирования файла 512 MiB в том же разделе составляет около 26% в Linux, 50% в macOS и 40% в Windows. Кроме того, используется гораздо меньше циклов CPU. См. раздел Зависящие от платформы эффективные операции копирования. (Автор - Giampaolo Rodolà в документе bpo-33671.)

  • shutil.copytree() использует функцию os.scandir(), а все функции копирования в зависимости от нее используют кэшированные значения os.stat(). Ускорение копирования каталога с 8000 файлами составляет около 9% для Linux, 20% для Windows и 30% для общего ресурса Windows SMB. Также количество os.stat() syscalls сокращено на 38%, делающих shutil.copytree() особенно быстрее в сетевых файловых системах. (Представлен Giampaolo Rodolà в bpo-33695.)

  • Протоколом по умолчанию в модуле pickle теперь является протокол 4, впервые представленный в Python 3.4. Он обеспечивает более высокую производительность и меньший размер по сравнению с протоколом 3, доступным с Python 3.0.

  • Удален один элемент Py_ssize_t из PyGC_Head. Размер всех отслеживаемых объектов GC (например, кортежа, списка, dict) уменьшается на 4 или 8 байт. (Внесена Inada Naoki в bpo-33597.)

  • Теперь uuid.UUID использует __slots__, чтобы уменьшить объем памяти. (Вклад Wouter Bolsterlee и Tal Einat в bpo-30977)

  • Повышение производительности operator.itemgetter() на 33%. Оптимизированная обработка аргументов и добавление быстрого пути для общего случая одного неотрицательного целочисленного индекса в кортеж (что является типичным случаем использования в стандартной библиотеке). (Представлен Raymond Hettinger в bpo-35664.)

  • Ускоренный поиск полей в collections.namedtuple(). Они теперь больше чем в два раза быстрее, делая их самой быстрой формой переменного поиска сущность в Python. (Вклад Raymond Hettinger, Pablo Galindo и Joe Jevnik, Serhiy Storchaka в bpo-32492.)

  • Конструктор list не перераспределяет внутренний буфер элементов, если входной итератор имеет известную длину (на входе реализован __len__). Это делает созданный список в среднем на 12% меньше. (Вклад Raymond Hettinger и Pablo Galindo в bpo-33234.)

  • Удвоение скорости записи переменной класс. Когда non-dunder атрибут был обновлен, было ненужное требование обновить места. (Вклад Stefan Behnel, Pablo Galindo Salgado, Raymond Hettinger, Neil Schemenauer и Serhiy Storchaka в bpo-36012.)

  • Уменьшение накладных расходов на преобразование аргументов, передаваемых во многие функции построения и методы. Это ускорило вызов некоторых простых функций построения и методы до 20 - 50%. (Представлен Serhiy Storchaka в bpo-23867, bpo-35582 и bpo-36127.)

  • В инструкции LOAD_GLOBAL теперь используется новый механизм «per opcode cache». Сейчас это примерно на 40% быстрее. (Представлен Yury Selivanov и инадой наоки в bpo-26219.)

Изменения C API и сборки

  • Дефолт sys.abiflags стал пустой последовательностью: флаг m для pymalloc стал бесполезным (строит с, и без pymalloc ABI совместимый), и удаленный - также. (Представлен Victor Stinner в 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 должен быть портативным public стабильным C API.
    • Include/cpython/*.h должен быть нестабильным C API, специфичным для CPython; public API, с некоторым частным API, префиксом _Py или _PY.
    • Include/internal/*.h является частным внутренним API C, очень специфичным для CPython. Этот API не имеет гарантии обратной совместимости и не должен быть используемый вне CPython. Он доступен только для очень специфических потребностей, таких как отладчики и профили, которые имеют доступ к внутренним CPython без вызова функций. Этот API теперь установлен make install.

    (Представлен Victor Stinner в bpo-35134 и bpo-35081, работа инициирована Eric Snow в Python 3.7.)

  • Некоторые макросы были преобразованы в статические встроенные функции: типы параметров и возвращаемый тип хорошо определены, они не имеют проблем, специфичных для макросов, переменные имеют локальная области видимости. Примеры:

    (Представлен Victor Stinner в bpo-35059.)

  • Функции PyByteArray_Init() и PyByteArray_Fini() удалены. Они ничего не сделали, поскольку Python 2.7.4 и Python 3.2.0, были исключены из ограниченного API (стабильный ABI) и не были задокументированы. (Представлен Victor Stinner в bpo-35713.)

  • Результат PyExceptionClass_Name() теперь тип const char *, а не char *. (Представлен Serhiy Storchaka в bpo-33818.)

  • Двойственность Modules/Setup.dist и Modules/Setup устранена. Ранее при обновлении исходного дерева CPython приходилось вручную копировать Modules/Setup.dist (внутри исходного дерева) в Modules/Setup (внутри дерева построения), чтобы отразить любые изменения в восходящем направлении. Это имело небольшое преимущество для пакетов в ущерб частому раздражению разработчиков после разработки CPython, так как забывание скопировать файл могло привести к сбоям сборки.

    Теперь построить система всегда читает от Modules/Setup в исходном дереве. Людям, которые хотят настроить этот файл, рекомендуется сохранять свои изменения в git- вилке CPython или в виде файлов исправлений, как это было бы сделано для любого другого изменения исходного дерева.

    (Предоставлено Antoine Pitrou в bpo-32430.)

  • Функции, которые преобразуют Python число в C целое подобное PyLong_AsLong() и аргумент парсинг функции подобной PyArg_ParseTuple() с целым преобразование единиц формата, как 'i' теперь будет использовать __index__() специальное метод вместо __int__(), если доступно. Запрещение, предупреждающее, будет испускаться для объектов с __int__() метод, но без __index__() метод (как Decimal и Fraction).:c:func:PyNumber_Check теперь возвратит 1 для объектов, осуществляющих __index__().:c:func:PyNumber_Long PyNumber_Float() и PyFloat_AsDouble() также теперь использует __index__() метод при наличии. (Представлен Serhiy Storchaka в bpo-36048 и bpo-20092.)

  • Объекты типа, выделенные кучой, теперь увеличат число ссылок в PyObject_Init() (и их параллельный макрос PyObject_INIT), а не в PyType_GenericAlloc(). Типы, которые изменяют распределение сущность или освобождение, возможно, должны быть приспособлены. (Представлен Eddie Elizondo в bpo-35810.)

  • Новая функция PyCode_NewWithPosOnlyArgs() позволяет создавать код объекты подобные PyCode_New(), но с дополнительным параметром posonlyargcount для указания количества аргументов только позиции. (Представлен Pablo Galindo в bpo-37221.)

  • Py_SetPath() теперь устанавливает sys.executable в программу весь путь (Py_GetProgramFullPath()), а не к названию программы (Py_GetProgramName()). (Представлен Victor Stinner в bpo-38234.)

Запрещённые

Удаление API и функций

Следующие функции и API были удалены из Python 3,8:

  • Начиная с Python 3,3 импорт ABC из collections устарел, а импорт должен выполняться из collections.abc. Возможность импорта из коллекций была отмечена для удаления в 3.8, но была отложена до 3.9. (См. bpo-36952.)
  • Модуль macpath, устаревший в Python 3.7, удален. (Представлен Victor Stinner в bpo-35471.)
  • Функция platform.popen() была удалена после того, как устарела с Python 3.3: используйте os.popen(). (Представлен Victor Stinner в bpo-35345.)
  • Функция time.clock() была удалена после того, как устарела с Python 3.3: использовать time.perf_counter() или time.process_time() вместо этого, в зависимости от ваших требований, чтобы иметь четко определенное поведение. (Представлен Matthias Bussonnier в bpo-36895.)
  • Сценарий pyvenv был удален в пользу python3.8 -m venv, чтобы помочь устранить беспорядок относительно того, к какому Python интерпретатор сценарий pyvenv связан. (Представлен Brett Cannon в bpo-25427.)
  • parse_qs, parse_qsl и escape извлекаются из модуля cgi. Они устарели в Python 3.2 или старше. Вместо этого их следует импортировать из модулей urllib.parse и html.
  • Функция filemode удаляется из модуля tarfile. Он не документирован и устарел с Python 3.3.
  • Конструктор XMLParser больше не принимает аргумент html. Он никогда не имел эффекта и был запрещён в Python 3.4. Все остальные параметры теперь keyword-only. (Представлен Serhiy Storchaka в bpo-29209.)
  • Удалён doctype() метод XMLParser. (Представлен Serhiy Storchaka в bpo-29209.)
  • «unicode_internal» кодировка удаляется. (Внесена Inada Naoki в bpo-36297.)
  • Cache и объекты Statement модуля sqlite3 не выставлены пользователю. (Предоставлено Aviv Palivoda в bpo-30262.)
  • Ключевой аргумент bufsize fileinput.input() и fileinput.FileInput(), который был пропущен и устарел с Python 3.6, был удален. bpo-36952 (Автор - Matthias Bussonnier.)
  • Функции sys.set_coroutine_wrapper() и sys.get_coroutine_wrapper(), устаревшие в Python 3.7, были исключены; bpo-36933 (Автор - Matthias Bussonnier.)

Портирование на Python 3.8

В этом разделе перечислены ранее описанные изменения и другие ошибки, которые могут потребовать изменения вашего код.

Изменения в поведении Python

  • Выражения yield (как yield, так и yield from) теперь не разрешены в представлениях и выражениях генератор (помимо итерабельного выражения в крайнем левом предложении for). (Предоставлено Serhiy Storchaka в bpo-10544.)
  • Компилятор теперь создает SyntaxWarning, когда проверки удостоверений (is и is not) используемый с определенными типами литералов (например, строки, числа). Они могут часто работать случайно в CPython, но не гарантируются языковой spec. Предупреждение советует пользователям использовать тесты на равенство (== и !=) вместо этого. (Представлен Serhiy Storchaka в bpo-34850.)
  • CPython интерпретатор может глотать исключения при некоторых обстоятельствах. В Python 3.8 это происходит в меньшем количестве случаев. В частности, исключения, возникшие при получении атрибут из словаря типов, больше не игнорируются. (Представлен Serhiy Storchaka в bpo-35459.)
  • Удаленные внедрения __str__ от встроенных типов bool, int, float, complex и немного классы из стандартной библиотеки. Теперь они наследуют __str__() от object. В результате определение __repr__() метод в подкласс этих классы повлияет на их представление строка. (Представлен Serhiy Storchaka в bpo-36793.)
  • В AIX sys.platform больше не содержит основной версии. Это всегда 'aix', вместо 'aix3'.. 'aix7'. Так как старые версии Python включают номер версии, поэтому рекомендуется всегда использовать sys.platform.startswith('aix'). (Внесен M. Felt в bpo-36588.)
  • PyEval_AcquireLock() и PyEval_AcquireThread() теперь завершают текущий поток, если вызывается, пока интерпретатор завершает работу, делая их согласованными с PyEval_RestoreThread(),:c:func:Py_END_ALLOW_THREADS и PyGILState_Ensure(). Если такое поведение не требуется, защитите вызов от вызова проверки _Py_IsFinalizing() или sys.is_finalizing(). (Представлен Joannah Nanjekye в bpo-36475.)

Изменения в API Python

  • Функция os.getcwdb() теперь использует UTF-8 кодировка на Windows, а не кодировку ANSI : см. PEP 529 для объяснения. Функция больше не устарела в Windows. (Представлен Victor Stinner в bpo-37412.)
  • subprocess.Popen может теперь использовать os.posix_spawn() в некоторых случаях для лучшего исполнения. В подсистеме Windows для Linux и эмуляции пользователя QEMU конструктор Popen, использующий os.posix_spawn(), больше не вызывает исключение при таких ошибках, как «отсутствующая программа». Вместо этого дочерний процесс терпит неудачу с отличным от нуля returncode. (Вклад Joannah Nanjekye и Victor Stinner в bpo-35537.)
  • Аргумент preexec_fn * subprocess.Popen больше не совместим с субинтерпретерами. Использование параметра в субинтерпреторе теперь вызывает RuntimeError. (Представлен Eric Snow в bpo-34651, модифицирован Christian Heimes в bpo-37951.)
  • imap.IMAP4.logout() метод больше не игнорирует произвольные исключения. (Представлен Victor Stinner в bpo-36348.)
  • Функция platform.popen() была удалена после того, как устарела с Python 3.3: используйте os.popen(). (Представлен Victor Stinner в bpo-35345.)
  • Функция statistics.mode() больше не вызывает исключения при предоставлении мультимодальных данных. Вместо этого возвращается первый режим, встречающийся во входных данных. (Представлен Raymond Hettinger в bpo-35892.)
  • selection() метод tkinter.ttk.Treeview класс больше не принимают аргументы. Использование его с аргументами для изменения выделенной области устарело в Python 3.6. Используйте специализированные методы, как selection_set(), для изменения выбора. (Представлен Serhiy Storchaka в bpo-31508.)
  • writexml(), toxml() и toprettyxml() методы xml.dom.minidom и write() метод xml.etree, теперь сохраняют порядок атрибута, определенный пользователем. (Вклад Diego Rojas и Raymond Hettinger в bpo-34160.)
  • База данных dbm.dumb, открытая с флагами 'r', теперь доступна только для чтения. dbm.dumb.open() с флагами 'r' и 'w' больше не создает базу данных, если она не существует. (Представлен Serhiy Storchaka в bpo-32749.)
  • doctype() метод, определенный в подкласс XMLParser, больше не будет вызываться и будет испускать RuntimeWarning вместо DeprecationWarning. Определите doctype() метод на целевом объекте для обработки объявления типа документа XML. (Представлен Serhiy Storchaka в bpo-29209.)
  • Теперь RuntimeError возникает, когда пользовательский метакласс не предоставляет запись __classcell__ в пространстве имен, переданном type.__new__. В Python 3.6-3.7 испускался DeprecationWarning. (Представлен Serhiy Storchaka в bpo-23722.)
  • cProfile.Profile класс может теперь быть используемый как менеджером контекст. (Представлен Scott Sanderson в bpo-29235.)
  • shutil.copyfile(), shutil.copy(), shutil.copy2(), shutil.copytree() и shutil.move() используют специфичные для платформы «быстрые копии» syscalls (см. раздел Зависящие от платформы эффективные операции копирования).
  • shutil.copyfile() по умолчанию размер буфера в Windows был изменен с 16 KiB на 1 MiB.
  • Структура PyGC_Head полностью изменилась. Все код, которые коснулись элемента структуры, должны быть переписаны. (См. bpo-33597.)
  • Структура PyInterpreterState была перемещена во «внутренние» заголовочные файлы (конкретно Include/internal/pycore_pystate.h). Непрозрачный PyInterpreterState все еще доступен как часть public API (и стабильный ABI). Документы указывают, что ни одно из полей структуры не является открытым, поэтому мы надеемся, что никто не использовал их. Однако, если вы полагаетесь на одно или несколько из этих частных полей и у вас нет альтернативы, пожалуйста, откройте проблему BPO. Мы будем работать над помощью вам приспособиться (возможно включая добавление accessor функции к public API). (См. bpo-35886.)
  • Теперь mmap.flush() метод возвращает None на успех и вызывает исключение при ошибке на всех платформах. Ранее его поведение было платформенно- зависимым: при успехе возвращалось ненулевое значение; при ошибке в Windows возвращен нуль. При успехе возвращено нулевое значение; возникло исключение при ошибке в Unix. (Представлен Berker Peksag в bpo-2122.)
  • Модули xml.dom.minidom и xml.sax больше не обрабатывают внешние объекты по умолчанию. (Представлен Christian Heimes в 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. (Представлен Serhiy Storchaka в bpo-32892.)
  • expanduser() в Windows теперь предпочитает переменную среды USERPROFILE и не использует HOME, которая обычно не устанавливается для обычных учетных записей пользователей. (Представлен Anthony Sottile в bpo-36264.)
  • Исключение asyncio.CancelledError теперь наследуется от BaseException, а не от Exception, и больше не наследуется от concurrent.futures.CancelledError. (Внесено Юрием Селивановым в bpo-32528.)
  • Функция asyncio.wait_for() теперь правильно ждет отмены, используя сущность asyncio.Task. Ранее по достижении timeout он отменялся и немедленно возвращался. (Представлен Elvis Pranskevichus в bpo-32751.)
  • Функция asyncio.BaseTransport.get_extra_info() теперь возвращает безопасный для использования объект сокет, когда «сокет» передается параметру name. (Представлен Yury Selivanov в н640382364.)
  • asyncio.BufferedProtocol вышел на стабильный API.
  • Зависимости DLL для модулей расширений и DLL, загруженных с помощью ctypes в Windows, теперь разрешены более безопасно. Только системные пути, каталог, содержащий файл DLL или PYD, и каталоги, добавленные вместе с add_dll_directory(), являются найденный для зависимостей времени загрузки. В частности, PATH и текущий рабочий каталог больше не используются, и изменения в них больше не будут влиять на нормальное разрешение DLL. Если ваше заявление полагается на эти механизмы, вы должны проверить на add_dll_directory() и если это существует, используйте его, чтобы добавить ваш каталог DLLs, загружая вашу библиотеку. Обратите внимание, что пользователи Windows 7 должны будут гарантировать, что Windows Update KB2533623 был установлен (это также проверено инсталлятором). (Предоставлено Steve Dower в bpo-36085.
  • Заголовочные файлы и функции, связанные с pgen, были удалены после замены их чистой Python реализацией. (Внесено Pablo Galindo в bpo-36623.)
  • types.CodeType имеет новый параметр во второй позиции конструктора (posonlyargcount) для поддержки аргументов только для позиций, определенных в PEP 570. Первый аргумент (argcount) теперь представляет общее число позиционных аргументов (включая только позиционные аргументы). Новый replace() метод types.CodeType может быть используемый, чтобы сделать код соответствующим требованиям завтрашнего дня.

Изменения в API C

  • PyCompilerFlags структура получила новое поле cf_feature_version. Она должена быть инициализирован для PY_MINOR_VERSION. Поле игнорируется по умолчанию и имеет значение используемый тогда и только тогда, когда флаг PyCF_ONLY_AST установлен в cf_flags. (Представлен Guido van Rossum в bpo-35766.)

  • Функция PyEval_ReInitThreads() удалена из API C. Вместо этого его не следует называть явно использовать PyOS_AfterFork_Child(). (Представлен Victor Stinner в bpo-36728.

  • В Unix расширения C больше не связаны с libpython, кроме Android и Cygwin. Когда Python встроен, libpython должен быть загружен не RTLD_LOCAL, а RTLD_GLOBAL вместо этого. Ранее, используя RTLD_LOCAL, было уже не возможно загрузить расширения C, которые не были связаны с libpython, как расширения C стандартной библиотеки, построенной *shared* разделом Modules/Setup. (Представлен Victor Stinner в bpo-21536.)

  • Использование вариантов # форматов в парсинг или сборочным значением (например PyArg_ParseTuple(), Py_BuildValue(), PyObject_CallFunction(), и т.д.) без определенного PY_SSIZE_T_CLEAN поднимает DeprecationWarning теперь. Он будет удален в 3.10 или 4.0. Прочитайте Анализ аргументов и сборка значений для детали. (Внесена Inada Naoki в bpo-36381.)

  • Сущности выделенных кучой типов (например, созданные с PyType_FromSpec()) содержат ссылку на объект-тип. Увеличение справочного количества этих объектов типа было перемещено из PyType_GenericAlloc() в больше функций низкоуровневое: c:func:PyObject_Init и PyObject_INIT(). Это делает созданный через PyType_FromSpec() типов, ведут себя как другой классы в управляемом код.

    Статически распределенные типы не затрагиваются.

    Для подавляющего большинства случаев не должно быть побочных эффектов. Однако типы, которые вручную увеличивают число ссылок после выделения сущность (возможно, для работы вокруг ошибки), теперь могут стать бессмертными. Чтобы избежать этого, эти классы должны назвать Py_DECREF на объекте типа во время освобождения сущность.

    Чтобы правильно перенести эти типы в 3.8, примените следующие изменения:

    • Удалён Py_INCREF на объекте типа после распределения сущность - если таковые имеются. Это может произойти после

      Это может произойти после вызова PyObject_New(), PyObject_NewVar(), PyObject_GC_New(), PyObject_GC_NewVar() или любой другой пользовательский аллокатор, который использует PyObject_Init() или 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;
      }
      
      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
      }
      
    • Убедитесь, что все пользовательские функции 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);
    

    (Представлен Zackery Spytz в bpo-33407.)

  • Интерпретатор больше не поддерживает двоичную совместимость типов расширений между выпусками компонентов. PyTypeObject, экспортируемые сторонним модулем расширения, должны иметь все слоты, ожидаемые в текущей версии Python, including:c:member:~PyTypeObject.tp_finalize (Py_TPFLAGS_HAVE_FINALIZE больше не проверяется перед чтением tp_finalize).

    (Представлен Antoine Pitrou в bpo-32388.

  • Теперь функции PyNode_AddChild() и PyParser_AddToken() принимают два дополнительных int аргумента end_lineno и end_col_offset.

  • Файл libpython38.a, позволяющий инструментам MinGW связываться непосредственно с python38.dll, больше не входит в обычный дистрибутив Windows. Если требуется этот файл, он может быть создан с помощью инструментов gendef и dlltool, которые являются частью пакета binutils MinGW:

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

    Расположение установленного pythonXY.dll будет зависеть от параметров установки и версии и языка Windows. Дополнительные сведения см. в разделе Использование Python в Windows. Полученная библиотека должна быть помещена в тот же каталог, что и pythonXY.lib, который обычно является каталогом libs при установке Python.

    (Представлен Steve Dower в bpo-37351.)

Изменения байткода CPython

  • Цикл интерпретатора был упрощен за счет перемещения логики распаковки стека блоков в компилятор. Компилятор выдает теперь явные инструкции по настройке стека значений и вызову код очистки для break, continue и return.

    Сняты коды операций BREAK_LOOP, CONTINUE_LOOP, SETUP_LOOP и SETUP_EXCEPT. Добавлены новые коды операций ROT_FOUR, BEGIN_FINALLY, CALL_FINALLY и POP_FINALLY. Изменило поведение END_FINALLY и WITH_CLEANUP_START.

    (Вклад Mark Shanno, Antoine Pitrou и Serhiy Storchaka в bpo-17611.

  • Добавленный новый opcode END_ASYNC_FOR для обработки исключений поднял, ожидая следующего предмета в петле async for. (Представлен Serhiy Storchaka в bpo-33041.

  • Теперь MAP_ADD ожидает значение как первый элемент в стеке, а ключ - как второй элемент. Это изменение было сделано, так что ключ всегда оценивается перед значением в словарных толкованиях, как предложено PEP 572. (Представлен Jörn Heissler в bpo-35224.)

Демонстрации и инструменты

Добавлен сценарий бенчмарка для синхронизации различных способов доступа к переменным: Tools/scripts/var_access_benchmark.py. (Представлен Raymond Hettinger в 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

Оценки измерялись на Intel® Core™ i7-4960HQ processor, работающем на macOS 64 битами, строит найденный в python.org. Сценарий тестирования отображает время в наносекундах.

Заметные изменения в Python 3.8.1

Из-за значительных проблем безопасности параметр reuse_address asyncio.loop.create_datagram_endpoint() больше не поддерживается. Это связано с поведением параметра сокета SO_REUSEADDR в UDP. Для получения дополнительной информации см. документацию для loop.create_datagram_endpoint(). (Вклад Kyle Stanley, Antoine Pitrou и Yury Selivanov в bpo-37228.)

Заметные изменения в Python 3.8.2

Исправлена регрессия с ignore колбэк shutil.copytree(). Типы аргументов теперь снова являются str и List[str]. (Вклад Manuel Barkhau и Giampaolo Rodola в bpo-39390.)

Заметные изменения в Python 3.8.3

Постоянные значения будущих флагов в модуле __future__ обновляются для предотвращения конфликтов с флагами компилятора. Ранее PyCF_ALLOW_TOP_LEVEL_AWAIT конфликтовал с CO_FUTURE_DIVISION. (Предоставлено Batuhan Taskaya в bpo-39562)

Заметные изменения в Python 3.8.8

Более ранние версии Python позволяли использовать как ;, так и & в качестве разделителей параметров запроса в urllib.parse.parse_qs() и urllib.parse.parse_qsl(). Из-за проблем безопасности и в соответствии с новыми рекомендациями W3C этот параметр был изменён, чтобы разрешить только один разделительный ключ. По умолчанию используется &. Это изменение также влияет на cgi.parse() и cgi.parse_multipart(), поскольку они используют затронутые функции внутри системы. Для получения более подробной информации, пожалуйста, ознакомьтесь с их соответствующей документацией. (Вклад Адама Гольдшмидта, Сентила Кумарана и Кена Джина в bpo-42967.)