3.8.md
1> **Источник:** https://python-all.ru/3.9/whatsnew/3.8.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Что нового в Python 3.889**Редактор**1011Raymond Hettinger1213В этой статье описываются новые возможности Python 3.8 по сравнению с версией 3.7. Полные подробности см. в [журнале изменений](https://python-all.ru/3.9/whatsnew/changelog.html#changelog).1415## Итоги – основные изменения1617## Новые возможности1819### Выражения присваивания2021Появился новый синтаксис `:=`, который присваивает значения переменным внутри более крупного выражения. Его ласково называют «оператором моржа» из-за сходства с [глазами и клыками моржа](https://python-all.ru/3.9/whatsnew/3.8.html).2223В этом примере выражение присваивания помогает избежать двукратного вызова [`len()`](https://python-all.ru/3.9/library/functions.html#len):2425```python26if (n := len(a)) > 10:27 print(f"List is too long ({n} elements, expected <= 10)")28```2930Аналогичное преимущество возникает при сопоставлении с регулярным выражением, когда объект совпадения нужен дважды: один раз для проверки, было ли совпадение, и второй раз для извлечения подгруппы:3132```python33discount = 0.034if (mo := re.search(r'(\d+)% discount', advertisement)):35 discount = float(mo.group(1)) / 100.036```3738Оператор также полезен в циклах while, которые вычисляют значение для проверки условия завершения цикла, а затем снова используют это же значение в теле цикла:3940```python41# Цикл по блокам фиксированной длины42while (block := f.read(256)) != '':43 process(block)44```4546Ещё один мотивирующий пример – списковые включения, где значение, вычисленное в условии фильтрации, также требуется в теле выражения:4748```python49[clean_name.title() for name in names50 if (clean_name := normalize('NFC', name)) in allowed_names]51```5253Следует ограничивать использование оператора моржа только теми случаями, которые снижают сложность и повышают читаемость.5455См. [**PEP 572**](https://python-all.ru/3.9/whatsnew/3.8.html) для полного описания.5657(Предложено Emily Morehouse в [bpo-35224](https://python-all.ru/3.9/whatsnew/3.8.html).)5859### Только позиционные параметры6061Появился новый синтаксис параметров функций `/`, который указывает, что некоторые параметры функции должны задаваться позиционно и не могут использоваться как именованные аргументы. Это та же нотация, что показывается `help()` для C- функций, аннотированных с помощью инструмента [Argument Clinic](https://python-all.ru/3.9/whatsnew/3.8.html) Ларри Хастингса.6263В следующем примере параметры *a* и *b* являются только позиционными, *c* или *d* могут быть позиционными или именованными, а *e* или *f* должны быть именованными:6465```python66def f(a, b, /, c, d, *, e, f):67 print(a, b, c, d, e, f)68```6970Следующий вызов допустим:7172```python73f(10, 20, 30, d=40, e=50, f=60)74```7576Однако следующие вызовы некорректны:7778```python79f(10, b=20, c=30, d=40, e=50, f=60) # b не может быть именованным аргументом80f(10, 20, 30, 40, 50, f=60) # e должен быть именованным аргументом81```8283Один из вариантов использования этой нотации – она позволяет чистым функциям Python полностью эмулировать поведение существующих функций, написанных на C. Например, встроенная функция [`divmod()`](https://python-all.ru/3.9/library/functions.html#divmod) не принимает именованных аргументов:8485```python86def divmod(a, b, /):87 "Emulate the built in divmod() function"88 return (a // b, a % b)89```9091Другой случай – запрет именованных аргументов, когда имя параметра не несет смысловой нагрузки. Например, встроенная функция [`len()`](https://python-all.ru/3.9/library/functions.html#len) имеет сигнатуру `len(obj, /)`. Это предотвращает неудобные вызовы вроде:9293```python94len(obj='hello') # Именованный аргумент "obj" ухудшает читаемость95```9697Ещё одно преимущество пометки параметра как только позиционного – возможность в будущем изменить имя параметра без риска сломать клиентский код. Например, в модуле [`statistics`](https://python-all.ru/3.9/library/statistics.html#module-statistics) имя параметра *dist* может быть изменено в будущем. Это стало возможным благодаря следующему описанию функции:9899```python100def quantiles(dist, /, *, n=4, method='exclusive')101 ...102```103104Поскольку параметры слева от `/` не раскрываются как возможные ключевые слова, их имена остаются доступными для использования в `**kwargs`:105106```python107>>> def f(a, b, /, **kwargs):108... print(a, b, kwargs)109...110>>> f(10, 20, a=1, b=2, c=3) # a и b используются двумя способами11110 20 {'a': 1, 'b': 2, 'c': 3}112```113114Это значительно упрощает реализацию функций и методов, которым нужно принимать произвольные именованные аргументы. Например, вот выдержка из кода модуля [`collections`](https://python-all.ru/3.9/library/collections.html#module-collections):115116```python117class Counter(dict):118119 def __init__(self, iterable=None, /, **kwds):120 # Примечание: «iterable» может быть именованным аргументом121```122123Полное описание см. в [**PEP 570**](https://python-all.ru/3.9/whatsnew/3.8.html).124125(Автор: Pablo Galindo в [bpo-36540](https://python-all.ru/3.9/whatsnew/3.8.html).)126127### Параллельный кэш файловой системы для скомпилированных файлов байт-кода128129Новый параметр [`PYTHONPYCACHEPREFIX`](https://python-all.ru/3.9/using/cmdline.html#envvar-PYTHONPYCACHEPREFIX) (также доступен как [`-X`](https://python-all.ru/3.9/using/cmdline.html#id5) `pycache_prefix`) настраивает неявный кэш байт-кода на использование отдельного параллельного дерева файловой системы вместо подкаталогов `__pycache__` по умолчанию внутри каждого исходного каталога.130131Расположение кэша сообщается в [`sys.pycache_prefix`](https://python-all.ru/3.9/library/sys.html#sys.pycache_prefix) ([`None`](https://python-all.ru/3.9/library/constants.html#None) указывает расположение по умолчанию в подкаталогах `__pycache__`).132133(Автор: Carl Meyer в [bpo-33499](https://python-all.ru/3.9/whatsnew/3.8.html).)134135### Отладочная сборка использует тот же ABI, что и обычная сборка136137Python теперь использует один и тот же ABI независимо от того, собран ли он в режиме выпуска (release) или отладки (debug). В Unix при сборке Python в режиме отладки теперь можно загружать C- расширения, собранные в режиме выпуска, а также C-расширения, собранные со стабильным ABI.138139Сборки release и debug теперь совместимы по ABI: определение макроса `Py_DEBUG` больше не подразумевает макрос `Py_TRACE_REFS`, который вносил единственную несовместимость ABI. Макрос `Py_TRACE_REFS`, который добавляет функцию `sys.getobjects()` и переменную окружения [`PYTHONDUMPREFS`](https://python-all.ru/3.9/using/cmdline.html#envvar-PYTHONDUMPREFS), можно задать с помощью новой опции сборки `./configure --with-trace-refs`. (Автор: Victor Stinner, [bpo-36465](https://python-all.ru/3.9/whatsnew/3.8.html).)140141В Unix расширения на C больше не линкуются с libpython, за исключением Android и Cygwin. Теперь стало возможным для статически слинкованного Python загружать расширение на C, собранное с использованием разделяемой библиотеки Python. (Автор: Victor Stinner в [bpo-21536](https://python-all.ru/3.9/whatsnew/3.8.html).)142143В Unix, когда Python собран в отладочном режиме, оператор import теперь также ищет расширения на C, скомпилированные в обычном режиме, и расширения на C, скомпилированные со стабильным ABI. (Автор: Victor Stinner в [bpo-36722](https://python-all.ru/3.9/whatsnew/3.8.html).)144145Чтобы встроить Python в приложение, необходимо передать новый параметр `--embed` в `python3-config --libs --embed` для получения `-lpython3.8` (линковка приложения с libpython). Для поддержки как 3.8, так и более старых версий, сначала попробуйте `python3-config --libs --embed`, а в случае неудачи – `python3-config --libs` (без `--embed`).146147Добавлен модуль 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.148149С другой стороны, `pkg-config python3.8 --libs` больше не содержит `-lpython3.8`. Расширения на C не должны линковаться с libpython (за исключением Android и Cygwin, чьи случаи обрабатываются скриптом); это изменение намеренно нарушает обратную совместимость. (Автор: Victor Stinner в [bpo-36721](https://python-all.ru/3.9/whatsnew/3.8.html).)150151### f-строки поддерживают `=` для самодокументируемых выражений и отладки152153Добавлен спецификатор `=` для [f-строк](https://python-all.ru/3.9/glossary.html#term-f-string). F-строка вида `f'{expr=}'` будет разворачиваться в текст выражения, знак равенства, а затем представление вычисленного выражения. Например:154155```python156>>> user = 'eric_idle'157>>> member_since = date(1975, 7, 31)158>>> f'{user=} {member_since=}'159"user='eric_idle' member_since=datetime.date(1975, 7, 31)"160```161162Обычные [спецификаторы формата f-строк](https://python-all.ru/3.9/reference/lexical_analysis.html#f-strings) позволяют лучше контролировать отображение результата выражения:163164```python165>>> delta = date.today() - member_since166>>> f'{user=!s} {delta.days=:,d}'167'user=eric_idle delta.days=16,075'168```169170Спецификатор `=` отображает всё выражение, чтобы можно было показать вычисления:171172```python173>>> print(f'{theta=} {cos(radians(theta))=:.3f}')174theta=30 cos(radians(theta))=0.866175```176177(Авторы: Eric V. Smith и Larry Hastings в [bpo-36817](https://python-all.ru/3.9/whatsnew/3.8.html).)178179### PEP 578: Хуки аудита времени выполнения Python180181В PEP добавляются Audit Hook и Verified Open Hook. Оба доступны из Python и нативного кода, что позволяет приложениям и фреймворкам, написанным на чистом Python, получать дополнительные уведомления, а также позволяет разработчикам, встраивающим Python, или системным администраторам разворачивать сборки Python, в которых аудит всегда включён.182183Подробности см. в [**PEP 578**](https://python-all.ru/3.9/whatsnew/3.8.html).184185### PEP 587: Конфигурация инициализации Python186187[**PEP 587**](https://python-all.ru/3.9/whatsnew/3.8.html) добавляет новый C API для настройки инициализации Python, обеспечивая более тонкий контроль над всей конфигурацией и улучшенное сообщение об ошибках.188189Новые структуры:190191- [`PyConfig`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig)192- [`PyPreConfig`](https://python-all.ru/3.9/c-api/init_config.html#c.PyPreConfig)193- [`PyStatus`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus)194- [`PyWideStringList`](https://python-all.ru/3.9/c-api/init_config.html#c.PyWideStringList)195196Новые функции:197198- [`PyConfig_Clear()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_Clear)199- [`PyConfig_InitIsolatedConfig()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_InitIsolatedConfig)200- [`PyConfig_InitPythonConfig()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_InitPythonConfig)201- [`PyConfig_Read()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_Read)202- [`PyConfig_SetArgv()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_SetArgv)203- [`PyConfig_SetBytesArgv()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_SetBytesArgv)204- [`PyConfig_SetBytesString()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_SetBytesString)205- [`PyConfig_SetString()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig_SetString)206- [`PyPreConfig_InitIsolatedConfig()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyPreConfig_InitIsolatedConfig)207- [`PyPreConfig_InitPythonConfig()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyPreConfig_InitPythonConfig)208- [`PyStatus_Error()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus_Error)209- [`PyStatus_Exception()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus_Exception)210- [`PyStatus_Exit()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus_Exit)211- [`PyStatus_IsError()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus_IsError)212- [`PyStatus_IsExit()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus_IsExit)213- [`PyStatus_NoMemory()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus_NoMemory)214- [`PyStatus_Ok()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyStatus_Ok)215- [`PyWideStringList_Append()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyWideStringList_Append)216- [`PyWideStringList_Insert()`](https://python-all.ru/3.9/c-api/init_config.html#c.PyWideStringList_Insert)217- [`Py_BytesMain()`](https://python-all.ru/3.9/c-api/veryhigh.html#c.Py_BytesMain)218- [`Py_ExitStatusException()`](https://python-all.ru/3.9/c-api/init_config.html#c.Py_ExitStatusException)219- [`Py_InitializeFromConfig()`](https://python-all.ru/3.9/c-api/init_config.html#c.Py_InitializeFromConfig)220- [`Py_PreInitialize()`](https://python-all.ru/3.9/c-api/init_config.html#c.Py_PreInitialize)221- [`Py_PreInitializeFromArgs()`](https://python-all.ru/3.9/c-api/init_config.html#c.Py_PreInitializeFromArgs)222- [`Py_PreInitializeFromBytesArgs()`](https://python-all.ru/3.9/c-api/init_config.html#c.Py_PreInitializeFromBytesArgs)223- [`Py_RunMain()`](https://python-all.ru/3.9/c-api/init_config.html#c.Py_RunMain)224225Этот PEP также добавляет поля `_PyRuntimeState.preconfig` (тип [`PyPreConfig`](https://python-all.ru/3.9/c-api/init_config.html#c.PyPreConfig)) и `PyInterpreterState.config` (тип [`PyConfig`](https://python-all.ru/3.9/c-api/init_config.html#c.PyConfig)) в эти внутренние структуры. `PyInterpreterState.config` становится новой эталонной конфигурацией, заменяя глобальные переменные конфигурации и другие приватные переменные.226227См. [Python Initialization Configuration](https://python-all.ru/3.9/c-api/init_config.html#init-config) в документации.228229Полное описание см. в [**PEP 587**](https://python-all.ru/3.9/whatsnew/3.8.html).230231(Предложено Виктором Стиннером в [bpo-36763](https://python-all.ru/3.9/whatsnew/3.8.html).)232233### PEP 590: Vectorcall: быстрый протокол вызова для CPython234235[Протокол Vectorcall](https://python-all.ru/3.9/c-api/call.html#vectorcall) добавлен в Python/C API. Он предназначен для формализации существующих оптимизаций, которые уже были реализованы для различных классов. Любой статический тип, реализующий вызываемый объект, может использовать этот протокол.236237В настоящее время это экспериментальная возможность. Цель – сделать её полностью общедоступной в Python 3.9.238239Полное описание см. в [**PEP 590**](https://python-all.ru/3.9/whatsnew/3.8.html).240241(Предложено Jeroen Demeyer, Mark Shannon и Petr Viktorin в [bpo-36974](https://python-all.ru/3.9/whatsnew/3.8.html).)242243### Протокол Pickle 5 с внеполосными буферами данных244245Когда [`pickle`](https://python-all.ru/3.9/library/pickle.html#module-pickle) используется для передачи больших данных между процессами Python для использования многоядерной или многомашинной обработки, важно оптимизировать передачу, уменьшая количество копирований памяти, и возможно применяя пользовательские методы, такие как сжатие, зависящее от данных.246247Протокол [`pickle`](https://python-all.ru/3.9/library/pickle.html#module-pickle) 5 вводит поддержку внеполосных буферов, где данные, совместимые с [**PEP 3118**](https://python-all.ru/3.9/whatsnew/3.8.html), могут передаваться отдельно от основного потока pickle, по усмотрению коммуникационного уровня.248249Полное описание см. в [**PEP 574**](https://python-all.ru/3.9/whatsnew/3.8.html).250251(Предложено Antoine Pitrou в [bpo-36785](https://python-all.ru/3.9/whatsnew/3.8.html).)252253## Прочие изменения языка254255- Оператор [`continue`](https://python-all.ru/3.9/reference/simple_stmts.html#continue) был недопустим в предложении [`finally`](https://python-all.ru/3.9/reference/compound_stmts.html#finally) из-за проблемы в реализации. В Python 3.8 это ограничение было снято. (Предложено Сергеем Сторчакой в [bpo-32489](https://python-all.ru/3.9/whatsnew/3.8.html).)256- Типы [`bool`](https://python-all.ru/3.9/library/functions.html#bool), [`int`](https://python-all.ru/3.9/library/functions.html#int) и [`fractions.Fraction`](https://python-all.ru/3.9/library/fractions.html#fractions.Fraction) теперь имеют метод [`as_integer_ratio()`](https://python-all.ru/3.9/library/stdtypes.html#int.as_integer_ratio), как у [`float`](https://python-all.ru/3.9/library/functions.html#float) и [`decimal.Decimal`](https://python-all.ru/3.9/library/decimal.html#decimal.Decimal). Это небольшое расширение API позволяет писать `numerator, denominator = x.as_integer_ratio()` и использовать его с различными числовыми типами. (Предложено Lisa Roach в [bpo-33073](https://python-all.ru/3.9/whatsnew/3.8.html) и Raymond Hettinger в [bpo-37819](https://python-all.ru/3.9/whatsnew/3.8.html).)257- Конструкторы [`int`](https://python-all.ru/3.9/library/functions.html#int), [`float`](https://python-all.ru/3.9/library/functions.html#float) и [`complex`](https://python-all.ru/3.9/library/functions.html#complex) теперь будут использовать специальный метод [`__index__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__index__), если он доступен, а соответствующий метод [`__int__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__int__), [`__float__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__float__) или [`__complex__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__complex__) недоступен. (Предложено Сергеем Сторчакой в [bpo-20092](https://python-all.ru/3.9/whatsnew/3.8.html).)258- Добавлена поддержка экранирующих последовательностей `\N{name}` в [`regular expressions`](https://python-all.ru/3.9/library/re.html#module-re):259260 ```python261 >>> notice = 'Copyright © 2019'262 >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})')263 >>> int(copyright_year_pattern.search(notice).group(1))264 2019265 ```266267 (Предложено Jonathan Eunice и Сергеем Сторчакой в [bpo-30688](https://python-all.ru/3.9/whatsnew/3.8.html).)268- Словари и представления словарей теперь можно перебирать в обратном порядке вставки с помощью [`reversed()`](https://python-all.ru/3.9/library/functions.html#reversed). (Предложено Rémi Lapeyre в [bpo-33462](https://python-all.ru/3.9/whatsnew/3.8.html).)269- Синтаксис, разрешённый для имён ключевых аргументов в вызовах функций, был дополнительно ограничен. В частности, `f((keyword)=arg)` больше не допускается. Никогда не предполагалось разрешать более одного простого имени в левой части присваивания ключевого аргумента. (Предложено Benjamin Peterson в [bpo-34641](https://python-all.ru/3.9/whatsnew/3.8.html).)270- Обобщённая распаковка итерируемых объектов в операторах [`yield`](https://python-all.ru/3.9/reference/simple_stmts.html#yield) и [`return`](https://python-all.ru/3.9/reference/simple_stmts.html#return) больше не требует заключения в скобки. Это приводит синтаксис *yield* и *return* в большее соответствие с обычным синтаксисом присваивания:271272 ```python273 >>> def parse(family):274 lastname, *members = family.split()275 return lastname.upper(), *members276277 >>> parse('simpsons homer marge bart lisa maggie')278 ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')279 ```280281 (Предложено David Cuthbert и Jordan Chapman в [bpo-32117](https://python-all.ru/3.9/whatsnew/3.8.html).)282- Когда в коде пропущена запятая, например, в `[(10, 20) (30, 40)]`, компилятор выводит [`SyntaxWarning`](https://python-all.ru/3.9/library/exceptions.html#SyntaxWarning) с полезной подсказкой. Это улучшает ситуацию по сравнению с простым сообщением [`TypeError`](https://python-all.ru/3.9/library/exceptions.html#TypeError), указывающим, что первый кортеж не был вызываемым. (Предложено Сергеем Сторчакой в [bpo-15248](https://python-all.ru/3.9/whatsnew/3.8.html).)283- Арифметические операции между подклассами [`datetime.date`](https://python-all.ru/3.9/library/datetime.html#datetime.date) или [`datetime.datetime`](https://python-all.ru/3.9/library/datetime.html#datetime.datetime) и объектами [`datetime.timedelta`](https://python-all.ru/3.9/library/datetime.html#datetime.timedelta) теперь возвращают экземпляр подкласса, а не базового класса. Это также влияет на тип возвращаемого значения операций, реализация которых (прямо или косвенно) использует арифметику [`datetime.timedelta`](https://python-all.ru/3.9/library/datetime.html#datetime.timedelta), например, [`astimezone()`](https://python-all.ru/3.9/library/datetime.html#datetime.datetime.astimezone). (Предложено Paul Ganssle в [bpo-32417](https://python-all.ru/3.9/whatsnew/3.8.html).)284- Когда интерпретатор Python прерывается по Ctrl-C (SIGINT) и возникающее исключение [`KeyboardInterrupt`](https://python-all.ru/3.9/library/exceptions.html#KeyboardInterrupt) не перехватывается, процесс Python теперь завершается через сигнал SIGINT или с правильным кодом возврата, так что вызывающий процесс может обнаружить, что он завершился из-за Ctrl-C. Оболочки на POSIX и Windows используют это для корректного завершения скриптов в интерактивных сеансах. (Предложено Google через Gregory P. Smith в [bpo-1054041](https://python-all.ru/3.9/whatsnew/3.8.html).)285- Некоторые продвинутые стили программирования требуют обновления объекта [`types.CodeType`](https://python-all.ru/3.9/library/types.html#types.CodeType) для существующей функции. Поскольку объекты кода неизменяемы, необходимо создать новый объект кода, который моделируется на основе существующего. С 19 параметрами это было довольно утомительно. Теперь новый метод `replace()` позволяет создать клон с несколькими изменёнными параметрами.286287 Вот пример, который изменяет функцию [`statistics.mean()`](https://python-all.ru/3.9/library/statistics.html#statistics.mean), чтобы предотвратить использование параметра *data* в качестве ключевого аргумента:288289 ```python290 >>> from statistics import mean291 >>> mean(data=[10, 20, 90])292 40293 >>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1)294 >>> mean(data=[10, 20, 90])295 Traceback (most recent call last):296 ...297 TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'298 ```299300 (Предложено Victor Stinner в [bpo-37032](https://python-all.ru/3.9/whatsnew/3.8.html).)301- Для целых чисел трёхаргументная форма функции [`pow()`](https://python-all.ru/3.9/library/functions.html#pow) теперь допускает отрицательный показатель степени, если основание является взаимно простым с модулем. Затем она вычисляет модульную инверсию основания, когда показатель равен `-1`, и соответствующую степень этой инверсии для других отрицательных показателей. Например, чтобы вычислить [модульную мультипликативную инверсию](https://python-all.ru/3.9/whatsnew/3.8.html) числа 38 по модулю 137, напишите:302303 ```python304 >>> pow(38, -1, 137)305 119306 >>> 119 * 38 % 137307 1308 ```309310 Модульные инверсии возникают при решении [линейных диофантовых уравнений](https://python-all.ru/3.9/whatsnew/3.8.html). Например, чтобы найти целочисленные решения для `4258𝑥 + 147𝑦 = 369`, сначала перепишите как `4258𝑥 ≡ 369 (mod 147)`, затем решите:311312 ```python313 >>> x = 369 * pow(4258, -1, 147) % 147314 >>> y = (4258 * x - 369) // -147315 >>> 4258 * x + 147 * y316 369317 ```318319 (Предложено Mark Dickinson в [bpo-36027](https://python-all.ru/3.9/whatsnew/3.8.html).)320- Генераторы словарей синхронизированы со словарными литералами: сначала вычисляется ключ, а затем значение:321322 ```python323 >>> # Генератор словаря324 >>> cast = {input('role? '): input('actor? ') for i in range(2)}325 role? King Arthur326 actor? Chapman327 role? Black Knight328 actor? Cleese329330 >>> # Литерал словаря331 >>> cast = {input('role? '): input('actor? ')}332 role? Sir Robin333 actor? Eric Idle334 ```335336 Гарантированный порядок выполнения полезен для выражений присваивания: переменные, присвоенные в выражении ключа, будут доступны в выражении значения:337338 ```python339 >>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald']340 >>> {(n := normalize('NFC', name)).casefold() : n for name in names}341 {'martin von löwis': 'Martin von Löwis',342 'łukasz langa': 'Łukasz Langa',343 'walter dörwald': 'Walter Dörwald'}344 ```345346 (Автор: Jörn Heissler в [bpo-35224](https://python-all.ru/3.9/whatsnew/3.8.html).)347- Метод [`object.__reduce__()`](https://python-all.ru/3.9/library/pickle.html#object.__reduce__) теперь может возвращать кортеж длиной от двух до шести элементов. Ранее пределом было пять. Новый, необязательный шестой элемент представляет собой вызываемый объект с сигнатурой `(obj, state)`. Это позволяет напрямую управлять поведением обновления состояния конкретного объекта. Если значение не равно *None*, этот вызываемый объект будет иметь приоритет над методом [`__setstate__()`](https://python-all.ru/3.9/library/pickle.html#object.__setstate__) объекта. (Авторы: Pierre Glaser и Olivier Grisel в [bpo-35900](https://python-all.ru/3.9/whatsnew/3.8.html).)348349## Новые модули350351- Новый модуль [`importlib.metadata`](https://python-all.ru/3.9/library/importlib.metadata.html#module-importlib.metadata) предоставляет (временную) поддержку для чтения метаданных из сторонних пакетов. Например, он может извлечь номер версии установленного пакета, список точек входа и другое:352353 ```python354 >>> # Примечание: следующий пример требует, чтобы популярный пакет "requests"355 >>> # был установлен.356 >>>357 >>> from importlib.metadata import version, requires, files358 >>> version('requests')359 '2.22.0'360 >>> list(requires('requests'))361 ['chardet (<3.1.0,>=3.0.2)']362 >>> list(files('requests'))[:5]363 [PackagePath('requests-2.22.0.dist-info/INSTALLER'),364 PackagePath('requests-2.22.0.dist-info/LICENSE'),365 PackagePath('requests-2.22.0.dist-info/METADATA'),366 PackagePath('requests-2.22.0.dist-info/RECORD'),367 PackagePath('requests-2.22.0.dist-info/WHEEL')]368 ```369370 (Авторы: Barry Warsaw и Jason R. Coombs в [bpo-34632](https://python-all.ru/3.9/whatsnew/3.8.html).)371372## Улучшенные модули373374### ast375376Узлы AST теперь имеют атрибуты `end_lineno` и `end_col_offset`, которые указывают точное местоположение конца узла. (Это применимо только к узлам, имеющим атрибуты `lineno` и `col_offset`.)377378Новая функция [`ast.get_source_segment()`](https://python-all.ru/3.9/library/ast.html#ast.get_source_segment) возвращает исходный код для конкретного узла AST.379380(Автор: Ivan Levkivskyi в [bpo-33416](https://python-all.ru/3.9/whatsnew/3.8.html).)381382Функция [`ast.parse()`](https://python-all.ru/3.9/library/ast.html#ast.parse) получила несколько новых флагов:383384- `type_comments=True` заставляет её возвращать текст [**PEP 484**](https://python-all.ru/3.9/whatsnew/3.8.html) и [**PEP 526**](https://python-all.ru/3.9/whatsnew/3.8.html) комментариев типов, связанных с определёнными узлами AST;385- `mode='func_type'` можно использовать для разбора [**PEP 484**](https://python-all.ru/3.9/whatsnew/3.8.html) «комментариев типов сигнатур» (возвращаемых для узлов AST определения функций);386- `feature_version=(3, N)` позволяет указать более раннюю версию Python 3. Например, `feature_version=(3, 4)` будет рассматривать [`async`](https://python-all.ru/3.9/reference/compound_stmts.html#async) и [`await`](https://python-all.ru/3.9/reference/expressions.html#await) как незарезервированные слова.387388(Автор: Guido van Rossum в [bpo-35766](https://python-all.ru/3.9/whatsnew/3.8.html).)389390### asyncio391392[`asyncio.run()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.run) перешёл из временного в стабильный API. Эта функция может использоваться для выполнения [корутины](https://python-all.ru/3.9/glossary.html#term-coroutine) и возврата результата с автоматическим управлением циклом событий. Например:393394```python395import asyncio396397async def main():398 await asyncio.sleep(0)399 return 42400401asyncio.run(main())402```403404Это *примерно* эквивалентно:405406```python407import asyncio408409async def main():410 await asyncio.sleep(0)411 return 42412413loop = asyncio.new_event_loop()414asyncio.set_event_loop(loop)415try:416 loop.run_until_complete(main())417finally:418 asyncio.set_event_loop(None)419 loop.close()420```421422Фактическая реализация значительно сложнее. Поэтому [`asyncio.run()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.run) должен быть предпочтительным способом запуска asyncio-программ.423424(Автор: Yury Selivanov в [bpo-32314](https://python-all.ru/3.9/whatsnew/3.8.html).)425426Запуск `python -m asyncio` запускает нативно асинхронную REPL. Это позволяет быстро экспериментировать с кодом, содержащим [`await`](https://python-all.ru/3.9/reference/expressions.html#await) на верхнем уровне. Больше нет необходимости напрямую вызывать `asyncio.run()`, который при каждом вызове создавал новый цикл событий:427428```text429$ python -m asyncio430asyncio REPL 3.8.0431Use "await" directly instead of "asyncio.run()".432Type "help", "copyright", "credits" or "license" for more information.433>>> import asyncio434>>> await asyncio.sleep(10, result='hello')435hello436```437438(Автор: Yury Selivanov в [bpo-37028](https://python-all.ru/3.9/whatsnew/3.8.html).)439440Исключение [`asyncio.CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError) теперь наследуется от [`BaseException`](https://python-all.ru/3.9/library/exceptions.html#BaseException) вместо [`Exception`](https://python-all.ru/3.9/library/exceptions.html#Exception) и больше не наследуется от [`concurrent.futures.CancelledError`](https://python-all.ru/3.9/library/concurrent.futures.html#concurrent.futures.CancelledError). (Автор: Yury Selivanov в [bpo-32528](https://python-all.ru/3.9/whatsnew/3.8.html).)441442В Windows цикл событий по умолчанию теперь [`ProactorEventLoop`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.ProactorEventLoop). (Автор: Victor Stinner в [bpo-34687](https://python-all.ru/3.9/whatsnew/3.8.html).)443444[`ProactorEventLoop`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.ProactorEventLoop) теперь также поддерживает UDP. (Авторы: Adam Meily и Andrew Svetlov в [bpo-29883](https://python-all.ru/3.9/whatsnew/3.8.html).)445446[`ProactorEventLoop`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.ProactorEventLoop) теперь можно прервать с помощью [`KeyboardInterrupt`](https://python-all.ru/3.9/library/exceptions.html#KeyboardInterrupt) («CTRL+C»). (Автор: Vladimir Matveev в [bpo-23057](https://python-all.ru/3.9/whatsnew/3.8.html).)447448Добавлен [`asyncio.Task.get_coro()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.get_coro) для получения обёрнутой корутины внутри [`asyncio.Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task). (Автор: Alex Grönholm в [bpo-36999](https://python-all.ru/3.9/whatsnew/3.8.html).)449450Задачам asyncio теперь можно задавать имена: либо передав именованный аргумент `name` в [`asyncio.create_task()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.create_task) или метод [`create_task()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.loop.create_task) цикла событий, либо вызвав метод [`set_name()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.set_name) у объекта задачи. Имя задачи видно в выводе `repr()` команды [`asyncio.Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task), а также может быть получено с помощью метода [`get_name()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.get_name). (Автор: Alex Grönholm в [bpo-34270](https://python-all.ru/3.9/whatsnew/3.8.html).)451452Добавлена поддержка [Happy Eyeballs](https://python-all.ru/3.9/whatsnew/3.8.html) для [`asyncio.loop.create_connection()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.loop.create_connection). Для настройки поведения добавлены два новых параметра: *happy\_eyeballs\_delay* и *interleave*. Алгоритм Happy Eyeballs повышает отзывчивость приложений, поддерживающих IPv4 и IPv6, за счёт попытки одновременного подключения по обоим протоколам. (Автор: twisteroid ambassador в [bpo-33530](https://python-all.ru/3.9/whatsnew/3.8.html).)453454### builtins455456Встроенная функция [`compile()`](https://python-all.ru/3.9/library/functions.html#compile) была улучшена: теперь она принимает флаг `ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`. При передаче этого нового флага [`compile()`](https://python-all.ru/3.9/library/functions.html#compile) будет разрешать конструкции верхнего уровня `await`, `async for` и `async with`, которые обычно считаются недопустимым синтаксисом. Затем может быть возвращён асинхронный объект кода, помеченный флагом `CO_COROUTINE`. (Автор: Matthias Bussonnier в [bpo-34616](https://python-all.ru/3.9/whatsnew/3.8.html))457458### collections459460Метод [`_asdict()`](https://python-all.ru/3.9/library/collections.html#collections.somenamedtuple._asdict) для [`collections.namedtuple()`](https://python-all.ru/3.9/library/collections.html#collections.namedtuple) теперь возвращает [`dict`](https://python-all.ru/3.9/library/stdtypes.html#dict) вместо [`collections.OrderedDict`](https://python-all.ru/3.9/library/collections.html#collections.OrderedDict). Это работает, поскольку обычные словари с Python 3.7 гарантированно упорядочены. Если требуются дополнительные возможности `OrderedDict`, рекомендуется привести результат к нужному типу: `OrderedDict(nt._asdict())`. (Предложено Raymond Hettinger в [bpo-35864](https://python-all.ru/3.9/whatsnew/3.8.html).)461462### cProfile463464Класс [`cProfile.Profile`](https://python-all.ru/3.9/library/profile.html#profile.Profile) теперь можно использовать как контекстный менеджер. Профилирование блока кода выполняется командой:465466```python467import cProfile468469with cProfile.Profile() as profiler:470 # код для профилирования471 ...472```473474(Предложено Scott Sanderson в [bpo-29235](https://python-all.ru/3.9/whatsnew/3.8.html).)475476### csv477478[`csv.DictReader`](https://python-all.ru/3.9/library/csv.html#csv.DictReader) теперь возвращает экземпляры [`dict`](https://python-all.ru/3.9/library/stdtypes.html#dict) вместо [`collections.OrderedDict`](https://python-all.ru/3.9/library/collections.html#collections.OrderedDict). Инструмент стал быстрее и использует меньше памяти, сохраняя порядок полей. (Предложено Michael Selik в [bpo-34003](https://python-all.ru/3.9/whatsnew/3.8.html).)479480### curses481482Добавлена новая переменная, содержащая структурированную информацию о версии базовой библиотеки ncurses: [`ncurses_version`](https://python-all.ru/3.9/library/curses.html#curses.ncurses_version). (Предложено Serhiy Storchaka в [bpo-31680](https://python-all.ru/3.9/whatsnew/3.8.html).)483484### ctypes485486В Windows [`CDLL`](https://python-all.ru/3.9/library/ctypes.html#ctypes.CDLL) и его подклассы теперь принимают параметр *winmode*, чтобы задавать флаги для вызова `LoadLibraryEx`. Флаги по умолчанию настроены так, чтобы загружать зависимости DLL только из доверенных мест, включая путь, где находится DLL (если для загрузки исходной DLL используется полный или частичный путь), а также пути, добавленные [`add_dll_directory()`](https://python-all.ru/3.9/library/os.html#os.add_dll_directory). (Предложено Steve Dower в [bpo-36085](https://python-all.ru/3.9/whatsnew/3.8.html).)487488### datetime489490Добавлены новые альтернативные конструкторы [`datetime.date.fromisocalendar()`](https://python-all.ru/3.9/library/datetime.html#datetime.date.fromisocalendar) и [`datetime.datetime.fromisocalendar()`](https://python-all.ru/3.9/library/datetime.html#datetime.datetime.fromisocalendar), которые создают объекты `date` и [`datetime`](https://python-all.ru/3.9/library/datetime.html#module-datetime) соответственно на основе года ISO, номера недели и дня недели; это обратные операции по отношению к методу `isocalendar` каждого класса. (Предложено Paul Ganssle в [bpo-36004](https://python-all.ru/3.9/whatsnew/3.8.html).)491492### functools493494[`functools.lru_cache()`](https://python-all.ru/3.9/library/functools.html#functools.lru_cache) теперь можно использовать напрямую как декоратор, а не как функцию, возвращающую декоратор. Поэтому теперь поддерживаются оба варианта:495496```python497@lru_cache498def f(x):499 ...500501@lru_cache(maxsize=256)502def f(x):503 ...504```505506(Предложено Raymond Hettinger в [bpo-36772](https://python-all.ru/3.9/whatsnew/3.8.html).)507508Добавлен новый декоратор [`functools.cached_property()`](https://python-all.ru/3.9/library/functools.html#functools.cached_property) для вычисляемых свойств, которые кэшируются на всё время жизни экземпляра.509510```python511import functools512import statistics513514class Dataset:515 def __init__(self, sequence_of_numbers):516 self.data = sequence_of_numbers517518 @functools.cached_property519 def variance(self):520 return statistics.variance(self.data)521```522523(Предложено Carl Meyer в [bpo-21145](https://python-all.ru/3.9/whatsnew/3.8.html))524525Добавлен новый декоратор [`functools.singledispatchmethod()`](https://python-all.ru/3.9/library/functools.html#functools.singledispatchmethod), который преобразует методы в [обобщённые функции](https://python-all.ru/3.9/glossary.html#term-generic-function) с помощью [одиночной диспетчеризации](https://python-all.ru/3.9/glossary.html#term-single-dispatch):526527```python528from functools import singledispatchmethod529from contextlib import suppress530531class TaskManager:532533 def __init__(self, tasks):534 self.tasks = list(tasks)535536 @singledispatchmethod537 def discard(self, value):538 with suppress(ValueError):539 self.tasks.remove(value)540541 @discard.register(list)542 def _(self, tasks):543 targets = set(tasks)544 self.tasks = [x for x in self.tasks if x not in targets]545```546547(Предложено Ethan Smith в [bpo-32380](https://python-all.ru/3.9/whatsnew/3.8.html))548549### gc550551[`get_objects()`](https://python-all.ru/3.9/library/gc.html#gc.get_objects) теперь может принимать необязательный параметр *generation*, указывающий поколение, из которого нужно получить объекты. (Предложено Pablo Galindo в [bpo-36016](https://python-all.ru/3.9/whatsnew/3.8.html).)552553### gettext554555Добавлены [`pgettext()`](https://python-all.ru/3.9/library/gettext.html#gettext.pgettext) и его варианты. (Предложено Franz Glasner, Éric Araujo и Cheryl Sabella в [bpo-2504](https://python-all.ru/3.9/whatsnew/3.8.html).)556557### gzip558559Добавлен параметр *mtime* в [`gzip.compress()`](https://python-all.ru/3.9/library/gzip.html#gzip.compress) для воспроизводимого вывода. (Предложено Guo Ci Teo в [bpo-34898](https://python-all.ru/3.9/whatsnew/3.8.html).)560561Исключение [`BadGzipFile`](https://python-all.ru/3.9/library/gzip.html#gzip.BadGzipFile) теперь возбуждается вместо [`OSError`](https://python-all.ru/3.9/library/exceptions.html#OSError) для некоторых типов недопустимых или повреждённых gzip-файлов. (Предложено Filip Gruszczyński, Michele Orrù и Zackery Spytz в [bpo-6584](https://python-all.ru/3.9/whatsnew/3.8.html).)562563### IDLE и idlelib564565Вывод длиннее N строк (по умолчанию 50) сворачивается в кнопку. N можно изменить в разделе PyShell на вкладке General диалогового окна Settings. Меньшее количество строк, но возможно очень длинных, можно свернуть, щелкнув правой кнопкой по выводу. Свёрнутый вывод можно развернуть на месте двойным щелчком по кнопке, либо в буфер обмена или отдельное окно щелчком правой кнопки по кнопке. (Предложено Tal Einat в [bpo-1529353](https://python-all.ru/3.9/whatsnew/3.8.html).)566567Добавлен пункт «Run Customized» в меню Run для запуска модуля с настраиваемыми параметрами. Введённые аргументы командной строки добавляются в sys.argv. Они также снова отображаются в поле для следующего настраиваемого запуска. Также можно отключить обычный перезапуск главного модуля Shell. (Предложено Cheryl Sabella, Terry Jan Reedy и другими в [bpo-5680](https://python-all.ru/3.9/whatsnew/3.8.html) и [bpo-37627](https://python-all.ru/3.9/whatsnew/3.8.html).)568569Добавлены опциональные номера строк для окон редактора IDLE. Окна открываются без номеров строк, если не указано иное на вкладке General диалога конфигурации. Номера строк для существующего окна можно показать или скрыть в меню Options. (Предложено Tal Einat и Saimadhav Heblikar в [bpo-17535](https://python-all.ru/3.9/whatsnew/3.8.html).)570571Теперь используется родная кодировка ОС для преобразования между строками Python и объектами Tcl. Это позволяет IDLE работать с эмодзи и другими символами вне BMP. Эти символы можно отображать или копировать и вставлять в/из буфера обмена. Преобразование строк из Tcl в Python и обратно теперь никогда не завершается ошибкой. (Многие люди работали над этим восемь лет, но проблема была окончательно решена Serhiy Storchaka в [bpo-13153](https://python-all.ru/3.9/whatsnew/3.8.html).)572573Новое в 3.8.1:574575Добавлена опция для отключения мигания курсора. (Предложено Zackery Spytz в [bpo-4603](https://python-all.ru/3.9/whatsnew/3.8.html).)576577Клавиша Escape теперь закрывает окна автодополнения IDLE. (Автор: Johnny Najera в [bpo-38944](https://python-all.ru/3.9/whatsnew/3.8.html).)578579Эти изменения были перенесены в версии 3.7 с поддержкой.580581Добавлены ключевые слова в список автодополнения имён модулей. (Предложено Terry J. Reedy в [bpo-37765](https://python-all.ru/3.9/whatsnew/3.8.html).)582583### inspect584585Функция [`inspect.getdoc()`](https://python-all.ru/3.9/library/inspect.html#inspect.getdoc) теперь может находить строки документации для `__slots__`, если этот атрибут является [`dict`](https://python-all.ru/3.9/library/stdtypes.html#dict), значения которого – строки документации. Это даёт возможности документации, аналогичные тем, что уже есть для [`property()`](https://python-all.ru/3.9/library/functions.html#property), [`classmethod()`](https://python-all.ru/3.9/library/functions.html#classmethod) и [`staticmethod()`](https://python-all.ru/3.9/library/functions.html#staticmethod):586587```python588class AudioClip:589 __slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place',590 'duration': 'in seconds, rounded up to an integer'}591 def __init__(self, bit_rate, duration):592 self.bit_rate = round(bit_rate / 1000.0, 1)593 self.duration = ceil(duration)594```595596(Предложено Raymond Hettinger в [bpo-36326](https://python-all.ru/3.9/whatsnew/3.8.html).)597598### io599600В режиме разработки ([`-X`](https://python-all.ru/3.9/using/cmdline.html#id5) `env`) и в отладочной сборке финализатор [`io.IOBase`](https://python-all.ru/3.9/library/io.html#io.IOBase) теперь записывает исключение в журнал, если метод `close()` завершается ошибкой. В сборке release по умолчанию исключение игнорируется без вывода сообщений. (Автор: Victor Stinner, [bpo-18748](https://python-all.ru/3.9/whatsnew/3.8.html).)601602### itertools603604Функция [`itertools.accumulate()`](https://python-all.ru/3.9/library/itertools.html#itertools.accumulate) получила необязательный именованный аргумент *initial* для задания начального значения:605606```python607>>> from itertools import accumulate608>>> list(accumulate([10, 5, 30, 15], initial=1000))609[1000, 1010, 1015, 1045, 1060]610```611612(Предложено Lisa Roach в [bpo-34659](https://python-all.ru/3.9/whatsnew/3.8.html).)613614### json.tool615616Добавлена опция `--json-lines` для разбора каждой входной строки как отдельного JSON-объекта. (Предложено Weipeng Hong в [bpo-31553](https://python-all.ru/3.9/whatsnew/3.8.html).)617618### logging619620Добавлен именованный аргумент *force* в [`logging.basicConfig()`](https://python-all.ru/3.9/library/logging.html#logging.basicConfig) Если он установлен в true, все существующие обработчики, прикреплённые к корневому логгеру, удаляются и закрываются перед выполнением конфигурации, заданной другими аргументами.621622Это решает давнюю проблему. После вызова логгера или *basicConfig()* последующие вызовы *basicConfig()* молча игнорировались. Это затрудняло обновление, эксперименты или обучение различным возможностям настройки логирования в интерактивной оболочке или Jupyter notebook.623624(Предложено Raymond Hettinger, реализовано Dong-hee Na и проверено Vinay Sajip в [bpo-33897](https://python-all.ru/3.9/whatsnew/3.8.html).)625626### math627628Добавлена новая функция [`math.dist()`](https://python-all.ru/3.9/library/math.html#math.dist) для вычисления евклидова расстояния между двумя точками. (Предложено Raymond Hettinger в [bpo-33089](https://python-all.ru/3.9/whatsnew/3.8.html).)629630Функция [`math.hypot()`](https://python-all.ru/3.9/library/math.html#math.hypot) расширена для работы с несколькими измерениями. Ранее она поддерживала только двумерный случай. (Предложено Raymond Hettinger в [bpo-33089](https://python-all.ru/3.9/whatsnew/3.8.html).)631632Добавлена новая функция [`math.prod()`](https://python-all.ru/3.9/library/math.html#math.prod), аналогичная [`sum()`](https://python-all.ru/3.9/library/functions.html#sum), которая возвращает произведение начального значения (по умолчанию 1) и элементов переданной последовательности чисел:633634```python635>>> prior = 0.8636>>> likelihoods = [0.625, 0.84, 0.30]637>>> math.prod(likelihoods, start=prior)6380.126639```640641(Предложено Pablo Galindo в [bpo-35606](https://python-all.ru/3.9/whatsnew/3.8.html).)642643Добавлены две новые комбинаторные функции [`math.perm()`](https://python-all.ru/3.9/library/math.html#math.perm) и [`math.comb()`](https://python-all.ru/3.9/library/math.html#math.comb):644645```python646>>> math.perm(10, 3) # Перестановки из 10 элементов по 3647720648>>> math.comb(10, 3) # Сочетания из 10 элементов по 3649120650```651652(Предложено Yash Aggarwal, Keller Fuchs, Serhiy Storchaka и Raymond Hettinger в [bpo-37128](https://python-all.ru/3.9/whatsnew/3.8.html), [bpo-37178](https://python-all.ru/3.9/whatsnew/3.8.html) и [bpo-35431](https://python-all.ru/3.9/whatsnew/3.8.html).)653654Добавлена новая функция [`math.isqrt()`](https://python-all.ru/3.9/library/math.html#math.isqrt) для точного вычисления целочисленного квадратного корня без преобразования в число с плавающей запятой. Новая функция поддерживает целые числа произвольной величины. Она быстрее `floor(sqrt(n))`, но медленнее [`math.sqrt()`](https://python-all.ru/3.9/library/math.html#math.sqrt):655656```python657>>> r = 650320427658>>> s = r ** 2659>>> isqrt(s - 1) # правильно660650320426661>>> floor(sqrt(s - 1)) # неправильно662650320427663```664665(Предложено Mark Dickinson в [bpo-36887](https://python-all.ru/3.9/whatsnew/3.8.html).)666667Функция [`math.factorial()`](https://python-all.ru/3.9/library/math.html#math.factorial) больше не принимает аргументы, не являющиеся целочисленными. (Предложено Pablo Galindo в [bpo-33083](https://python-all.ru/3.9/whatsnew/3.8.html).)668669### mmap670671Класс [`mmap.mmap`](https://python-all.ru/3.9/library/mmap.html#mmap.mmap) теперь имеет метод [`madvise()`](https://python-all.ru/3.9/library/mmap.html#mmap.mmap.madvise) для доступа к системному вызову `madvise()`. (Предложено Zackery Spytz в [bpo-32941](https://python-all.ru/3.9/whatsnew/3.8.html).)672673### multiprocessing674675Добавлен новый модуль [`multiprocessing.shared_memory`](https://python-all.ru/3.9/library/multiprocessing.shared_memory.html#module-multiprocessing.shared_memory). (Предложено Davin Potts в [bpo-35813](https://python-all.ru/3.9/whatsnew/3.8.html).)676677На macOS метод запуска *spawn* теперь используется по умолчанию. (Автор: Victor Stinner в [bpo-33725](https://python-all.ru/3.9/whatsnew/3.8.html).)678679### os680681Добавлена новая функция [`add_dll_directory()`](https://python-all.ru/3.9/library/os.html#os.add_dll_directory) в Windows для предоставления дополнительных путей поиска для нативных зависимостей при импорте модулей расширения или загрузке DLL с помощью [`ctypes`](https://python-all.ru/3.9/library/ctypes.html#module-ctypes). (Автор: Steve Dower в [bpo-36085](https://python-all.ru/3.9/whatsnew/3.8.html).)682683Добавлена новая функция [`os.memfd_create()`](https://python-all.ru/3.9/library/os.html#os.memfd_create), оборачивающая системный вызов `memfd_create()`. (Авторы: Zackery Spytz и Christian Heimes в [bpo-26836](https://python-all.ru/3.9/whatsnew/3.8.html).)684685В Windows большая часть ручной логики обработки точек повторного анализа (включая символические ссылки и соединения каталогов) передана операционной системе. В частности, [`os.stat()`](https://python-all.ru/3.9/library/os.html#os.stat) теперь будет обходить всё, что поддерживается операционной системой, в то время как [`os.lstat()`](https://python-all.ru/3.9/library/os.html#os.lstat) будет открывать только точки повторного анализа, которые идентифицируются как «заместители имени», а остальные открываются как для [`os.stat()`](https://python-all.ru/3.9/library/os.html#os.stat). Во всех случаях `stat_result.st_mode` будет иметь `S_IFLNK`, установленный только для символических ссылок, а не для других видов точек повторного анализа. Чтобы идентифицировать другие виды точек повторного анализа, проверьте новый атрибут `stat_result.st_reparse_tag`.686687В Windows [`os.readlink()`](https://python-all.ru/3.9/library/os.html#os.readlink) теперь умеет читать соединения каталогов. Обратите внимание, что [`islink()`](https://python-all.ru/3.9/library/os.path.html#os.path.islink) вернёт `False` для соединений каталогов, поэтому код, который сначала проверяет `islink`, продолжит считать соединения каталогов директориями, а код, обрабатывающий ошибки от [`os.readlink()`](https://python-all.ru/3.9/library/os.html#os.readlink), теперь может считать соединения каталогов ссылками.688689(Автор: Steve Dower в [bpo-37834](https://python-all.ru/3.9/whatsnew/3.8.html).)690691### os.path692693Функции [`os.path`](https://python-all.ru/3.9/library/os.path.html#module-os.path), возвращающие булев результат, такие как [`exists()`](https://python-all.ru/3.9/library/os.path.html#os.path.exists), [`lexists()`](https://python-all.ru/3.9/library/os.path.html#os.path.lexists), [`isdir()`](https://python-all.ru/3.9/library/os.path.html#os.path.isdir), [`isfile()`](https://python-all.ru/3.9/library/os.path.html#os.path.isfile), [`islink()`](https://python-all.ru/3.9/library/os.path.html#os.path.islink) и [`ismount()`](https://python-all.ru/3.9/library/os.path.html#os.path.ismount), теперь возвращают `False` вместо возбуждения [`ValueError`](https://python-all.ru/3.9/library/exceptions.html#ValueError) или его подклассов [`UnicodeEncodeError`](https://python-all.ru/3.9/library/exceptions.html#UnicodeEncodeError) и [`UnicodeDecodeError`](https://python-all.ru/3.9/library/exceptions.html#UnicodeDecodeError) для путей, содержащих символы или байты, непредставимые на уровне ОС. (Автор: Serhiy Storchaka в [bpo-33721](https://python-all.ru/3.9/whatsnew/3.8.html).)694695[`expanduser()`](https://python-all.ru/3.9/library/os.path.html#os.path.expanduser) в Windows теперь отдаёт предпочтение переменной окружения `USERPROFILE` и не использует `HOME`, которая обычно не установлена для обычных учётных записей пользователей. (Автор: Anthony Sottile в [bpo-36264](https://python-all.ru/3.9/whatsnew/3.8.html).)696697[`isdir()`](https://python-all.ru/3.9/library/os.path.html#os.path.isdir) в Windows больше не возвращает `True` для ссылки на несуществующий каталог.698699[`realpath()`](https://python-all.ru/3.9/library/os.path.html#os.path.realpath) в Windows теперь обрабатывает точки повторного анализа, включая символические ссылки и соединения каталогов.700701(Автор: Steve Dower в [bpo-37834](https://python-all.ru/3.9/whatsnew/3.8.html).)702703### pathlib704705Методы [`pathlib.Path`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path), возвращающие булев результат, такие как [`exists()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.exists), [`is_dir()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_dir), [`is_file()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_file), [`is_mount()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_mount), [`is_symlink()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_symlink), [`is_block_device()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_block_device), [`is_char_device()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_char_device), [`is_fifo()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_fifo), [`is_socket()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.is_socket), теперь возвращают `False` вместо возбуждения [`ValueError`](https://python-all.ru/3.9/library/exceptions.html#ValueError) или его подкласса [`UnicodeEncodeError`](https://python-all.ru/3.9/library/exceptions.html#UnicodeEncodeError) для путей, содержащих символы, непредставимые на уровне ОС. (Автор: Serhiy Storchaka в [bpo-33721](https://python-all.ru/3.9/whatsnew/3.8.html).)706707Добавлена [`pathlib.Path.link_to()`](https://python-all.ru/3.9/library/pathlib.html#pathlib.Path.link_to), которая создаёт жёсткую ссылку, указывающую на путь. (Автор: Joannah Nanjekye в [bpo-26978](https://python-all.ru/3.9/whatsnew/3.8.html))708709### pickle710711Расширения [`pickle`](https://python-all.ru/3.9/library/pickle.html#module-pickle), наследующие от оптимизированной на C реализации [`Pickler`](https://python-all.ru/3.9/library/pickle.html#pickle.Pickler), теперь могут переопределять логику сериализации (pickling) функций и классов, определяя специальный метод [`reducer_override()`](https://python-all.ru/3.9/library/pickle.html#pickle.Pickler.reducer_override). (Авторы: Pierre Glaser и Olivier Grisel в [bpo-35900](https://python-all.ru/3.9/whatsnew/3.8.html).)712713### plistlib714715Добавлена новая [`plistlib.UID`](https://python-all.ru/3.9/library/plistlib.html#plistlib.UID) и включена поддержка чтения и записи бинарных plist-файлов, закодированных NSKeyedArchiver. (Автор: Jon Janzen в [bpo-26707](https://python-all.ru/3.9/whatsnew/3.8.html).)716717### pprint718719Модуль [`pprint`](https://python-all.ru/3.9/library/pprint.html#module-pprint) добавил параметр *sort\_dicts* в несколько функций. По умолчанию эти функции продолжают сортировать словари перед отображением или выводом на печать. Однако если *sort\_dicts* установлен в false, словари сохраняют порядок вставки ключей. Это может быть полезно для сравнения с JSON-данными при отладке.720721Кроме того, добавлена новая удобная функция [`pprint.pp()`](https://python-all.ru/3.9/library/pprint.html#pprint.pp), которая работает как [`pprint.pprint()`](https://python-all.ru/3.9/library/pprint.html#pprint.pprint), но с параметром *sort\_dicts*, по умолчанию установленным в `False`:722723```python724>>> from pprint import pprint, pp725>>> d = dict(source='input.txt', operation='filter', destination='output.txt')726>>> pp(d, width=40) # Исходный порядок727{'source': 'input.txt',728 'operation': 'filter',729 'destination': 'output.txt'}730>>> pprint(d, width=40) # Ключи, отсортированные по алфавиту731{'destination': 'output.txt',732 'operation': 'filter',733 'source': 'input.txt'}734```735736(Автор: Rémi Lapeyre в [bpo-30670](https://python-all.ru/3.9/whatsnew/3.8.html).)737738### py\_compile739740[`py_compile.compile()`](https://python-all.ru/3.9/library/py_compile.html#py_compile.compile) теперь поддерживает тихий режим. (Автор: Joannah Nanjekye в [bpo-22640](https://python-all.ru/3.9/whatsnew/3.8.html).)741742### shlex743744Новая функция [`shlex.join()`](https://python-all.ru/3.9/library/shlex.html#shlex.join) действует как обратная к [`shlex.split()`](https://python-all.ru/3.9/library/shlex.html#shlex.split). (Автор: Bo Bayles в [bpo-32102](https://python-all.ru/3.9/whatsnew/3.8.html).)745746### shutil747748[`shutil.copytree()`](https://python-all.ru/3.9/library/shutil.html#shutil.copytree) теперь принимает новый именованный аргумент `dirs_exist_ok`. (Автор: Josh Bronson в [bpo-20849](https://python-all.ru/3.9/whatsnew/3.8.html).)749750[`shutil.make_archive()`](https://python-all.ru/3.9/library/shutil.html#shutil.make_archive) теперь по умолчанию использует современный формат pax (POSIX.1-2001) для новых архивов для улучшения переносимости и соответствия стандартам, унаследовано от соответствующего изменения в модуле [`tarfile`](https://python-all.ru/3.9/library/tarfile.html#module-tarfile). (Автор: C.A.M. Gerlach в [bpo-30661](https://python-all.ru/3.9/whatsnew/3.8.html).)751752[`shutil.rmtree()`](https://python-all.ru/3.9/library/shutil.html#shutil.rmtree) в Windows теперь удаляет соединения каталогов без предварительного рекурсивного удаления их содержимого. (Автор: Steve Dower в [bpo-37834](https://python-all.ru/3.9/whatsnew/3.8.html).)753754### socket755756Добавлены функции [`create_server()`](https://python-all.ru/3.9/library/socket.html#socket.create_server) и [`has_dualstack_ipv6()`](https://python-all.ru/3.9/library/socket.html#socket.has_dualstack_ipv6) автоматизирующие типичные задачи при создании серверного сокета, включая приём соединений как по IPv4, так и по IPv6 на одном сокете. (Предложено Giampaolo Rodolà в [bpo-17561](https://python-all.ru/3.9/whatsnew/3.8.html).)757758Функции [`socket.if_nameindex()`](https://python-all.ru/3.9/library/socket.html#socket.if_nameindex), [`socket.if_nametoindex()`](https://python-all.ru/3.9/library/socket.html#socket.if_nametoindex) и [`socket.if_indextoname()`](https://python-all.ru/3.9/library/socket.html#socket.if_indextoname) реализованы в Windows. (Предложено Zackery Spytz в [bpo-37007](https://python-all.ru/3.9/whatsnew/3.8.html).)759760### ssl761762Добавлены [`post_handshake_auth`](https://python-all.ru/3.9/library/ssl.html#ssl.SSLContext.post_handshake_auth) для включения и [`verify_client_post_handshake()`](https://python-all.ru/3.9/library/ssl.html#ssl.SSLSocket.verify_client_post_handshake) для запуска аутентификации после рукопожатия TLS 1.3. (Предложено Christian Heimes в [bpo-34670](https://python-all.ru/3.9/whatsnew/3.8.html).)763764### statistics765766Добавлена [`statistics.fmean()`](https://python-all.ru/3.9/library/statistics.html#statistics.fmean) как более быстрый вариант с плавающей точкой для [`statistics.mean()`](https://python-all.ru/3.9/library/statistics.html#statistics.mean). (Авторы: Raymond Hettinger и Steven D’Aprano в [bpo-35904](https://python-all.ru/3.9/whatsnew/3.8.html).)767768Добавлено [`statistics.geometric_mean()`](https://python-all.ru/3.9/library/statistics.html#statistics.geometric_mean) (Предложено Raymond Hettinger в [bpo-27181](https://python-all.ru/3.9/whatsnew/3.8.html).)769770Добавлено [`statistics.multimode()`](https://python-all.ru/3.9/library/statistics.html#statistics.multimode), возвращающее список наиболее распространённых значений. (Предложено Raymond Hettinger в [bpo-35892](https://python-all.ru/3.9/whatsnew/3.8.html).)771772Добавлено [`statistics.quantiles()`](https://python-all.ru/3.9/library/statistics.html#statistics.quantiles), которое делит данные или распределение на равновероятные интервалы (например, квартили, децили или процентили). (Предложено Raymond Hettinger в [bpo-36546](https://python-all.ru/3.9/whatsnew/3.8.html).)773774Добавлено [`statistics.NormalDist`](https://python-all.ru/3.9/library/statistics.html#statistics.NormalDist) – инструмент для создания и управления нормальными распределениями случайной величины. (Предложено Raymond Hettinger в [bpo-36018](https://python-all.ru/3.9/whatsnew/3.8.html).)775776```python777>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14])778>>> temperature_feb.mean7796.0780>>> temperature_feb.stdev7816.356099432828281782783>>> temperature_feb.cdf(3) # Вероятность оказаться ниже 3 градусов7840.3184678262814532785>>> # Относительная вероятность 7 градусов против 10786>>> temperature_feb.pdf(7) / temperature_feb.pdf(10)7871.2039930378537762788789>>> el_niño = NormalDist(4, 2.5)790>>> temperature_feb += el_niño # Добавить климатический эффект791>>> temperature_feb792NormalDist(mu=10.0, sigma=6.830080526611674)793794>>> temperature_feb * (9/5) + 32 # Преобразовать в градусы Фаренгейта795NormalDist(mu=50.0, sigma=12.294144947901014)796>>> temperature_feb.samples(3) # Сгенерировать случайные выборки797[7.672102882379219, 12.000027119750287, 4.647488369766392]798```799800### sys801802Добавлена новая функция [`sys.unraisablehook()`](https://python-all.ru/3.9/library/sys.html#sys.unraisablehook), которую можно переопределить, чтобы управлять обработкой «необрабатываемых исключений». Она вызывается, когда возникает исключение, но у Python нет способа его обработать. Например, когда деструктор порождает исключение или во время сборки мусора ([`gc.collect()`](https://python-all.ru/3.9/library/gc.html#gc.collect)). (Предложено Victor Stinner в [bpo-36829](https://python-all.ru/3.9/whatsnew/3.8.html).)803804### tarfile805806Модуль [`tarfile`](https://python-all.ru/3.9/library/tarfile.html#module-tarfile) теперь по умолчанию использует современный формат pax (POSIX.1-2001) для новых архивов вместо прежнего, специфичного для GNU. Это улучшает кроссплатформенную переносимость благодаря единой кодировке (UTF-8) в стандартизированном и расширяемом формате, а также предоставляет ряд других преимуществ. (Предложено C.A.M. Gerlach в [bpo-36268](https://python-all.ru/3.9/whatsnew/3.8.html).)807808### threading809810Добавлена новая функция [`threading.excepthook()`](https://python-all.ru/3.9/library/threading.html#threading.excepthook), обрабатывающая неперехваченное исключение [`threading.Thread.run()`](https://python-all.ru/3.9/library/threading.html#threading.Thread.run). Её можно переопределить, чтобы управлять обработкой неперехваченных исключений [`threading.Thread.run()`](https://python-all.ru/3.9/library/threading.html#threading.Thread.run). (Предложено Victor Stinner в [bpo-1230540](https://python-all.ru/3.9/whatsnew/3.8.html).)811812Добавлены новая функция [`threading.get_native_id()`](https://python-all.ru/3.9/library/threading.html#threading.get_native_id) и атрибут [`native_id`](https://python-all.ru/3.9/library/threading.html#threading.Thread.native_id) в класс [`threading.Thread`](https://python-all.ru/3.9/library/threading.html#threading.Thread). Они возвращают собственный целочисленный идентификатор текущего потока, назначаемый ядром. Эта возможность доступна только на некоторых платформах; подробнее см. [`get_native_id`](https://python-all.ru/3.9/library/threading.html#threading.get_native_id). (Предложено Jake Tesler в [bpo-36084](https://python-all.ru/3.9/whatsnew/3.8.html).)813814### tokenize815816Модуль [`tokenize`](https://python-all.ru/3.9/library/tokenize.html#module-tokenize) теперь неявно генерирует токен `NEWLINE`, если входные данные не содержат завершающего перевода строки. Такое поведение теперь соответствует тому, что делает внутренний токенизатор C. (Предложено Ammar Askar в [bpo-33899](https://python-all.ru/3.9/whatsnew/3.8.html).)817818### tkinter819820В класс `tkinter.Spinbox` добавлены методы `selection_from()`, `selection_present()`, `selection_range()` и `selection_to()`. (Предложено Juliette Monsel в [bpo-34829](https://python-all.ru/3.9/whatsnew/3.8.html).)821822В класс `tkinter.Canvas` добавлен метод `moveto()`. (Предложено Juliette Monsel в [bpo-23831](https://python-all.ru/3.9/whatsnew/3.8.html).)823824У класса `tkinter.PhotoImage` теперь есть методы `transparency_get()` и `transparency_set()`. (Предложено Zackery Spytz в [bpo-25451](https://python-all.ru/3.9/whatsnew/3.8.html).)825826### time827828Добавлены новые часы [`CLOCK_UPTIME_RAW`](https://python-all.ru/3.9/library/time.html#time.CLOCK_UPTIME_RAW) для macOS 10.12. (Предложено Joannah Nanjekye в [bpo-35702](https://python-all.ru/3.9/whatsnew/3.8.html).)829830### typing831832Модуль [`typing`](https://python-all.ru/3.9/library/typing.html#module-typing) включает несколько новых возможностей:833834- Тип словаря с типизацией по ключам. См. [**PEP 589**](https://python-all.ru/3.9/whatsnew/3.8.html) и [`typing.TypedDict`](https://python-all.ru/3.9/library/typing.html#typing.TypedDict). TypedDict использует только строковые ключи. По умолчанию каждый ключ обязан присутствовать. Укажите “total=False”, чтобы сделать ключи необязательными:835836 ```python837 class Location(TypedDict, total=False):838 lat_long: tuple839 grid_square: str840 xy_coordinate: tuple841 ```842- Литеральные типы. См. [**PEP 586**](https://python-all.ru/3.9/whatsnew/3.8.html) и [`typing.Literal`](https://python-all.ru/3.9/library/typing.html#typing.Literal). Литеральные типы указывают, что параметр или возвращаемое значение ограничены одним или несколькими конкретными литеральными значениями:843844 ```python845 def get_status(port: int) -> Literal['connected', 'disconnected']:846 ...847 ```848- «Финальные» переменные, функции, методы и классы. См. [**PEP 591**](https://python-all.ru/3.9/whatsnew/3.8.html), [`typing.Final`](https://python-all.ru/3.9/library/typing.html#typing.Final) и [`typing.final()`](https://python-all.ru/3.9/library/typing.html#typing.final). Квалификатор final указывает статическому проверщику типов ограничивать наследование, переопределение или переназначение:849850 ```python851 pi: Final[float] = 3.1415926536852 ```853- Определения протоколов. См. [**PEP 544**](https://python-all.ru/3.9/whatsnew/3.8.html), [`typing.Protocol`](https://python-all.ru/3.9/library/typing.html#typing.Protocol) и [`typing.runtime_checkable()`](https://python-all.ru/3.9/library/typing.html#typing.runtime_checkable). Простые абстрактные базовые классы (ABC), такие как [`typing.SupportsInt`](https://python-all.ru/3.9/library/typing.html#typing.SupportsInt), теперь являются подклассами `Protocol`.854- Новый класс протокола [`typing.SupportsIndex`](https://python-all.ru/3.9/library/typing.html#typing.SupportsIndex).855- Новые функции [`typing.get_origin()`](https://python-all.ru/3.9/library/typing.html#typing.get_origin) и [`typing.get_args()`](https://python-all.ru/3.9/library/typing.html#typing.get_args).856857### unicodedata858859Модуль [`unicodedata`](https://python-all.ru/3.9/library/unicodedata.html#module-unicodedata) обновлён для использования версии [Unicode 12.1.0](https://python-all.ru/3.9/whatsnew/3.8.html).860861Новая функция [`is_normalized()`](https://python-all.ru/3.9/library/unicodedata.html#unicodedata.is_normalized) позволяет проверить, находится ли строка в определённой нормальной форме, часто гораздо быстрее, чем при фактической нормализации строки. (Предложено Max Belanger, David Euresti и Greg Price в [bpo-32285](https://python-all.ru/3.9/whatsnew/3.8.html) и [bpo-37966](https://python-all.ru/3.9/whatsnew/3.8.html)).862863### unittest864865Добавлен [`AsyncMock`](https://python-all.ru/3.9/library/unittest.mock.html#unittest.mock.AsyncMock) для поддержки асинхронной версии [`Mock`](https://python-all.ru/3.9/library/unittest.mock.html#unittest.mock.Mock). Также добавлены соответствующие новые функции assert для тестирования. (Предложено Lisa Roach в [bpo-26467](https://python-all.ru/3.9/whatsnew/3.8.html)).866867Добавлены [`addModuleCleanup()`](https://python-all.ru/3.9/library/unittest.html#unittest.addModuleCleanup) и [`addClassCleanup()`](https://python-all.ru/3.9/library/unittest.html#unittest.TestCase.addClassCleanup) в unittest для поддержки очистки для `setUpModule()` и [`setUpClass()`](https://python-all.ru/3.9/library/unittest.html#unittest.TestCase.setUpClass). (Предложено Lisa Roach в [bpo-24412](https://python-all.ru/3.9/whatsnew/3.8.html).)868869Некоторые mock-функции assert теперь также выводят список фактических вызовов при неудаче. (Предложено Petter Strandmark в [bpo-35047](https://python-all.ru/3.9/whatsnew/3.8.html).)870871Модуль [`unittest`](https://python-all.ru/3.9/library/unittest.html#module-unittest) получил поддержку использования корутин в качестве тестовых случаев с помощью [`unittest.IsolatedAsyncioTestCase`](https://python-all.ru/3.9/library/unittest.html#unittest.IsolatedAsyncioTestCase). (Предложено Andrew Svetlov в [bpo-32972](https://python-all.ru/3.9/whatsnew/3.8.html).)872873Пример:874875```python876import unittest877878class TestRequest(unittest.IsolatedAsyncioTestCase):879880 async def asyncSetUp(self):881 self.connection = await AsyncConnection()882883 async def test_get(self):884 response = await self.connection.get("https://example.com")885 self.assertEqual(response.status_code, 200)886887 async def asyncTearDown(self):888 await self.connection.close()889890if __name__ == "__main__":891 unittest.main()892```893894### venv895896[`venv`](https://python-all.ru/3.9/library/venv.html#module-venv) теперь включает скрипт `Activate.ps1` на всех платформах для активации виртуальных окружений в PowerShell Core 6.1. (Предложено Brett Cannon в [bpo-32718](https://python-all.ru/3.9/whatsnew/3.8.html).)897898### weakref899900Прокси-объекты, возвращаемые [`weakref.proxy()`](https://python-all.ru/3.9/library/weakref.html#weakref.proxy), теперь поддерживают операторы умножения матриц `@` и `@=` в дополнение к другим числовым операторам. (Предложено Mark Dickinson в [bpo-36669](https://python-all.ru/3.9/whatsnew/3.8.html).)901902### xml903904В качестве меры защиты от DTD и извлечения внешних сущностей модули [`xml.dom.minidom`](https://python-all.ru/3.9/library/xml.dom.minidom.html#module-xml.dom.minidom) и [`xml.sax`](https://python-all.ru/3.9/library/xml.sax.html#module-xml.sax) больше не обрабатывают внешние сущности по умолчанию. (Предложено Christian Heimes в [bpo-17239](https://python-all.ru/3.9/whatsnew/3.8.html).)905906Методы `.find*()` в модуле [`xml.etree.ElementTree`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) поддерживают поиск по шаблону, например `{*}tag`, который игнорирует пространство имён, и `{namespace}*`, который возвращает все теги в заданном пространстве имён. (Предложено Stefan Behnel в [bpo-28238](https://python-all.ru/3.9/whatsnew/3.8.html).)907908Модуль [`xml.etree.ElementTree`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) предоставляет новую функцию `–xml.etree.ElementTree.canonicalize()`, реализующую C14N 2.0. (Предложено Stefan Behnel в [bpo-13611](https://python-all.ru/3.9/whatsnew/3.8.html).)909910Целевой объект [`xml.etree.ElementTree.XMLParser`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser) может получать события объявления пространства имён через новые методы колбэков `start_ns()` и `end_ns()`. Кроме того, цель [`xml.etree.ElementTree.TreeBuilder`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder) можно настроить на обработку событий о комментариях и инструкциях обработки, чтобы включить их в создаваемое дерево. (Предложено Stefan Behnel в [bpo-36676](https://python-all.ru/3.9/whatsnew/3.8.html) и [bpo-36673](https://python-all.ru/3.9/whatsnew/3.8.html).)911912### xmlrpc913914[`xmlrpc.client.ServerProxy`](https://python-all.ru/3.9/library/xmlrpc.client.html#xmlrpc.client.ServerProxy) теперь поддерживает необязательный именованный аргумент *headers* для последовательности HTTP-заголовков, отправляемых с каждым запросом. В частности, это позволяет перейти с базовой аутентификации по умолчанию на более быструю сессионную аутентификацию. (Предложено Cédric Krier в [bpo-35153](https://python-all.ru/3.9/whatsnew/3.8.html).)915916## Оптимизации917918- Модуль [`subprocess`](https://python-all.ru/3.9/library/subprocess.html#module-subprocess) теперь может использовать функцию [`os.posix_spawn()`](https://python-all.ru/3.9/library/os.html#os.posix_spawn) в некоторых случаях для повышения производительности. В настоящее время он используется только в macOS и Linux (с glibc 2.24 или новее) при соблюдении всех следующих условий:919920 - *close\_fds* имеет значение false;921 - параметры *preexec\_fn*, *pass\_fds*, *cwd* и *start\_new\_session* не заданы;922 - путь *executable* содержит каталог.923924 (Предложено Joannah Nanjekye и Victor Stinner в [bpo-35537](https://python-all.ru/3.9/whatsnew/3.8.html).)925- [`shutil.copyfile()`](https://python-all.ru/3.9/library/shutil.html#shutil.copyfile), [`shutil.copy()`](https://python-all.ru/3.9/library/shutil.html#shutil.copy), [`shutil.copy2()`](https://python-all.ru/3.9/library/shutil.html#shutil.copy2), [`shutil.copytree()`](https://python-all.ru/3.9/library/shutil.html#shutil.copytree) и [`shutil.move()`](https://python-all.ru/3.9/library/shutil.html#shutil.move) используют платформозависимые системные вызовы «fast-copy» в Linux и macOS для более эффективного копирования файлов. «fast-copy» означает, что операция копирования происходит внутри ядра, избегая использования буферов пользовательского пространства в Python, как в «`outfd.write(infd.read())`». В Windows [`shutil.copyfile()`](https://python-all.ru/3.9/library/shutil.html#shutil.copyfile) использует больший размер буфера по умолчанию (1 МиБ вместо 16 КиБ) и используется вариант [`shutil.copyfileobj()`](https://python-all.ru/3.9/library/shutil.html#shutil.copyfileobj) на основе [`memoryview()`](https://python-all.ru/3.9/library/stdtypes.html#memoryview). Ускорение копирования файла размером 512 МиБ в пределах одного раздела составляет около +26% в Linux, +50% в macOS и +40% в Windows. Кроме того, потребляется гораздо меньше тактов ЦП. См. раздел [Эффективные операции копирования, зависящие от платформы](https://python-all.ru/3.9/library/shutil.html#shutil-platform-dependent-efficient-copy-operations). (Предложено Giampaolo Rodolà в [bpo-33671](https://python-all.ru/3.9/whatsnew/3.8.html).)926- [`shutil.copytree()`](https://python-all.ru/3.9/library/shutil.html#shutil.copytree) использует функцию [`os.scandir()`](https://python-all.ru/3.9/library/os.html#os.scandir), и все функции копирования, зависящие от неё, используют кэшированные значения [`os.stat()`](https://python-all.ru/3.9/library/os.html#os.stat). Ускорение копирования каталога с 8000 файлов составляет около +9% в Linux, +20% в Windows и +30% в общей папке Windows SMB. Кроме того, количество системных вызовов [`os.stat()`](https://python-all.ru/3.9/library/os.html#os.stat) сокращено на 38%, что делает [`shutil.copytree()`](https://python-all.ru/3.9/library/shutil.html#shutil.copytree) особенно быстрее в сетевых файловых системах. (Предложено Giampaolo Rodolà в [bpo-33695](https://python-all.ru/3.9/whatsnew/3.8.html).)927- Протоколом по умолчанию в модуле [`pickle`](https://python-all.ru/3.9/library/pickle.html#module-pickle) теперь является Протокол 4, впервые представленный в Python 3.4. Он обеспечивает более высокую производительность и меньший размер по сравнению с Протоколом 3, доступным с Python 3.0.928- Удалён один элемент [`Py_ssize_t`](https://python-all.ru/3.9/c-api/intro.html#c.Py_ssize_t) из `PyGC_Head`. Размер всех объектов, отслеживаемых GC (например, tuple, list, dict), уменьшен на 4 или 8 байт. (Предложено Inada Naoki в [bpo-33597](https://python-all.ru/3.9/whatsnew/3.8.html).)929- [`uuid.UUID`](https://python-all.ru/3.9/library/uuid.html#uuid.UUID) теперь использует `__slots__` для уменьшения потребления памяти. (Предложено Wouter Bolsterlee и Tal Einat в [bpo-30977](https://python-all.ru/3.9/whatsnew/3.8.html))930- Производительность [`operator.itemgetter()`](https://python-all.ru/3.9/library/operator.html#operator.itemgetter) улучшена на 33%. Оптимизирована обработка аргументов и добавлен быстрый путь для распространённого случая одного неотрицательного целочисленного индекса в кортеже (что является типичным случаем использования в стандартной библиотеке). (Предложено Raymond Hettinger в [bpo-35664](https://python-all.ru/3.9/whatsnew/3.8.html).)931- Ускорен поиск полей в [`collections.namedtuple()`](https://python-all.ru/3.9/library/collections.html#collections.namedtuple). Теперь он выполняется более чем в два раза быстрее, что делает его самой быстрой формой поиска переменных экземпляра в Python. (Разработка Рэймонда Хеттингера, Пабло Галиндо, Джо Джевника и Сергея Сторчаки – [bpo-32492](https://python-all.ru/3.9/whatsnew/3.8.html).)932- Конструктор [`list`](https://python-all.ru/3.9/library/stdtypes.html#list) больше не выделяет лишнюю память для внутреннего буфера элементов, если длина входного итерируемого объекта известна (вход реализует `__len__`). Благодаря этому создаваемый список в среднем на 12% меньше. (Разработка Рэймонда Хеттингера и Пабло Галиндо – [bpo-33234](https://python-all.ru/3.9/whatsnew/3.8.html).)933- Скорость записи переменных класса удвоена. При обновлении атрибута, не являющегося дандером, выполнялся лишний вызов для обновления слотов. (Разработка Стефана Бенела, Пабло Галиндо Сальгадо, Рэймонда Хеттингера, Нила Шеменауэра и Сергея Сторчаки – [bpo-36012](https://python-all.ru/3.9/whatsnew/3.8.html).)934- Снижены накладные расходы на преобразование аргументов, передаваемых многим встроенным функциям и методам. Это ускорило вызов некоторых простых встроенных функций и методов на 20–50%. (Разработка Сергея Сторчаки – [bpo-23867](https://python-all.ru/3.9/whatsnew/3.8.html), [bpo-35582](https://python-all.ru/3.9/whatsnew/3.8.html) и [bpo-36127](https://python-all.ru/3.9/whatsnew/3.8.html).)935- Инструкция `LOAD_GLOBAL` теперь использует новый механизм «per opcode cache». Она стала примерно на 40% быстрее. (Разработка Юрия Селиванова и Инады Наоки – [bpo-26219](https://python-all.ru/3.9/whatsnew/3.8.html).)936937## Изменения в сборке и C API938939- Значение по умолчанию [`sys.abiflags`](https://python-all.ru/3.9/library/sys.html#sys.abiflags) стало пустой строкой: флаг `m` для pymalloc стал бесполезен (сборки с pymalloc и без него ABI-совместимы), поэтому он был удалён. (Разработка Виктора Стиннера – [bpo-36707](https://python-all.ru/3.9/whatsnew/3.8.html).)940941 Пример изменений:942943 - Устанавливается только программа `python3.8`, программа `python3.8m` удалена.944 - Устанавливается только скрипт `python3.8-config`, скрипт `python3.8m-config` удалён.945 - Флаг `m` удалён из суффикса имён файлов динамических библиотек: модулей расширения стандартной библиотеки, а также тех, что создаются и устанавливаются сторонними пакетами (например, загруженными из PyPI). В Linux, например, суффикс `.cpython-37m-x86_64-linux-gnu.so` для Python 3.7 стал `.cpython-38-x86_64-linux-gnu.so` в Python 3.8.946- Заголовочные файлы были переорганизованы для лучшего разделения различных видов API:947948 - `Include/*.h` – это переносимый публичный стабильный C API.949 - `Include/cpython/*.h` – это нестабильный C API, специфичный для CPython; публичный API, с некоторыми приватными частями, имеющими префикс `_Py` или `_PY`.950 - `Include/internal/*.h` – это приватный внутренний C API, очень специфичный для CPython. Этот API не предоставляет гарантий обратной совместимости и не должен использоваться за пределами CPython. Он открыт только для особых нужд, таких как отладчики и профилировщики, которым требуется доступ к внутренностям CPython без вызова функций. Теперь этот API устанавливается с помощью `make install`.951952 (Разработка Виктора Стиннера – [bpo-35134](https://python-all.ru/3.9/whatsnew/3.8.html) и [bpo-35081](https://python-all.ru/3.9/whatsnew/3.8.html); работа начата Эриком Сноу в Python 3.7.)953- Некоторые макросы преобразованы в статические встраиваемые функции: типы параметров и возвращаемое значение чётко определены, отсутствуют проблемы, свойственные макросам, переменные имеют локальную область видимости. Примеры:954955 - [`Py_INCREF()`](https://python-all.ru/3.9/c-api/refcounting.html#c.Py_INCREF), [`Py_DECREF()`](https://python-all.ru/3.9/c-api/refcounting.html#c.Py_DECREF)956 - [`Py_XINCREF()`](https://python-all.ru/3.9/c-api/refcounting.html#c.Py_XINCREF), [`Py_XDECREF()`](https://python-all.ru/3.9/c-api/refcounting.html#c.Py_XDECREF)957 - `PyObject_INIT()`, `PyObject_INIT_VAR()`958 - Приватные функции: `_PyObject_GC_TRACK()`, `_PyObject_GC_UNTRACK()`, `_Py_Dealloc()`959960 (Разработка Виктора Стиннера – [bpo-35059](https://python-all.ru/3.9/whatsnew/3.8.html).)961- Функции `PyByteArray_Init()` и `PyByteArray_Fini()` удалены. Они ничего не делали начиная с Python 2.7.4 и Python 3.2.0, были исключены из ограниченного API (стабильного ABI) и не документировались. (Разработка Виктора Стиннера – [bpo-35713](https://python-all.ru/3.9/whatsnew/3.8.html).)962- Результат `PyExceptionClass_Name()` теперь имеет тип `const char *`, а не `char *`. (Разработка Сергея Сторчаки – [bpo-33818](https://python-all.ru/3.9/whatsnew/3.8.html).)963- Двойственность `Modules/Setup.dist` и `Modules/Setup` устранена. Раньше при обновлении исходного дерева CPython приходилось вручную копировать `Modules/Setup.dist` (внутри исходного дерева) в `Modules/Setup` (внутри дерева сборки), чтобы отразить любые изменения. Это приносило небольшую пользу сборщикам пакетов, но часто раздражало разработчиков, следящих за разработкой CPython, так как забыв скопировать файл, можно было получить сбой сборки.964965 Теперь система сборки всегда читает из `Modules/Setup` внутри исходного дерева. Тем, кто хочет настроить этот файл, рекомендуется поддерживать свои изменения в git-форке CPython или в виде патч-файлов, как и любые другие изменения исходного дерева.966967 (Разработка Антуана Питру – [bpo-32430](https://python-all.ru/3.9/whatsnew/3.8.html).)968- Функции, преобразующие число Python в целое C, такие как [`PyLong_AsLong()`](https://python-all.ru/3.9/c-api/long.html#c.PyLong_AsLong), и функции разбора аргументов, например [`PyArg_ParseTuple()`](https://python-all.ru/3.9/c-api/arg.html#c.PyArg_ParseTuple), с форматными единицами преобразования в целое, например `'i'`, теперь будут использовать специальный метод [`__index__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__index__) вместо [`__int__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__int__), если он доступен. Предупреждение об устаревании будет выдаваться для объектов, у которых есть метод `__int__()`, но отсутствует `__index__()` (например, [`Decimal`](https://python-all.ru/3.9/library/decimal.html#decimal.Decimal) и [`Fraction`](https://python-all.ru/3.9/library/fractions.html#fractions.Fraction)). [`PyNumber_Check()`](https://python-all.ru/3.9/c-api/number.html#c.PyNumber_Check) теперь будет возвращать `1` для объектов, реализующих `__index__()`. [`PyNumber_Long()`](https://python-all.ru/3.9/c-api/number.html#c.PyNumber_Long), [`PyNumber_Float()`](https://python-all.ru/3.9/c-api/number.html#c.PyNumber_Float) и [`PyFloat_AsDouble()`](https://python-all.ru/3.9/c-api/float.html#c.PyFloat_AsDouble) также теперь используют метод `__index__()`, если он доступен. (Разработка Сергея Сторчаки – [bpo-36048](https://python-all.ru/3.9/whatsnew/3.8.html) и [bpo-20092](https://python-all.ru/3.9/whatsnew/3.8.html).)969- Объекты типов, выделяемые в куче, теперь будут увеличивать счётчик ссылок в [`PyObject_Init()`](https://python-all.ru/3.9/c-api/allocation.html#c.PyObject_Init) (и в параллельном макросе `PyObject_INIT`) вместо [`PyType_GenericAlloc()`](https://python-all.ru/3.9/c-api/type.html#c.PyType_GenericAlloc). Типы, которые изменяют выделение или освобождение экземпляров, возможно, потребуют корректировки. (Разработка Эдди Элизондо – [bpo-35810](https://python-all.ru/3.9/whatsnew/3.8.html).)970- Новая функция [`PyCode_NewWithPosOnlyArgs()`](https://python-all.ru/3.9/c-api/code.html#c.PyCode_NewWithPosOnlyArgs) позволяет создавать объекты кода, как [`PyCode_New()`](https://python-all.ru/3.9/c-api/code.html#c.PyCode_New), но с дополнительным параметром *posonlyargcount* для указания количества позиционных аргументов. (Разработка Пабло Галиндо – [bpo-37221](https://python-all.ru/3.9/whatsnew/3.8.html).)971- [`Py_SetPath()`](https://python-all.ru/3.9/c-api/init.html#c.Py_SetPath) теперь устанавливает [`sys.executable`](https://python-all.ru/3.9/library/sys.html#sys.executable) в полный путь программы ([`Py_GetProgramFullPath()`](https://python-all.ru/3.9/c-api/init.html#c.Py_GetProgramFullPath)), а не в имя программы ([`Py_GetProgramName()`](https://python-all.ru/3.9/c-api/init.html#c.Py_GetProgramName)). (Разработка Виктора Стиннера – [bpo-38234](https://python-all.ru/3.9/whatsnew/3.8.html).)972973## Устарело974975- Команда distutils `bdist_wininst` теперь устарела; вместо неё используйте `bdist_wheel` (пакеты wheel). (Разработка Виктора Стиннера – [bpo-37481](https://python-all.ru/3.9/whatsnew/3.8.html).)976- Устаревшие методы `getchildren()` и `getiterator()` в модуле [`ElementTree`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) теперь порождают [`DeprecationWarning`](https://python-all.ru/3.9/library/exceptions.html#DeprecationWarning) вместо [`PendingDeprecationWarning`](https://python-all.ru/3.9/library/exceptions.html#PendingDeprecationWarning). Они будут удалены в Python 3.9. (Разработка Сергея Сторчаки – [bpo-29209](https://python-all.ru/3.9/whatsnew/3.8.html).)977- Передача [`loop.set_default_executor()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.loop.set_default_executor) объекта, не являющегося экземпляром [`concurrent.futures.ThreadPoolExecutor`](https://python-all.ru/3.9/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor), объявлена устаревшей и будет запрещена в Python 3.9. (Разработка Элвиса Пранскевичуса – [bpo-34075](https://python-all.ru/3.9/whatsnew/3.8.html).)978- Методы [`__getitem__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__getitem__) классов [`xml.dom.pulldom.DOMEventStream`](https://python-all.ru/3.9/library/xml.dom.pulldom.html#xml.dom.pulldom.DOMEventStream), [`wsgiref.util.FileWrapper`](https://python-all.ru/3.9/library/wsgiref.html#wsgiref.util.FileWrapper) и [`fileinput.FileInput`](https://python-all.ru/3.9/library/fileinput.html#fileinput.FileInput) объявлены устаревшими.979980 Реализации этих методов игнорировали параметр *index* и вместо этого возвращали следующий элемент. (Разработка Беркера Пексага – [bpo-9372](https://python-all.ru/3.9/whatsnew/3.8.html).)981- Класс [`typing.NamedTuple`](https://python-all.ru/3.9/library/typing.html#typing.NamedTuple) объявил устаревшим атрибут `_field_types` в пользу атрибута `__annotations__`, который содержит ту же информацию. (Автор: Raymond Hettinger в [bpo-36320](https://python-all.ru/3.9/whatsnew/3.8.html).)982- Классы [`ast`](https://python-all.ru/3.9/library/ast.html#module-ast) `Num`, `Str`, `Bytes`, `NameConstant` и `Ellipsis` считаются устаревшими и будут удалены в будущих версиях Python. Вместо них следует использовать [`Constant`](https://python-all.ru/3.9/library/ast.html#ast.Constant). (Автор: Serhiy Storchaka в [bpo-32892](https://python-all.ru/3.9/whatsnew/3.8.html).)983- Методы [`ast.NodeVisitor`](https://python-all.ru/3.9/library/ast.html#ast.NodeVisitor) `visit_Num()`, `visit_Str()`, `visit_Bytes()`, `visit_NameConstant()` и `visit_Ellipsis()` теперь устарели и не будут вызываться в будущих версиях Python. Добавьте метод `visit_Constant()` для обработки всех постоянных узлов. (Автор: Serhiy Storchaka в [bpo-36917](https://python-all.ru/3.9/whatsnew/3.8.html).)984- [`asyncio.coroutine()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.coroutine) [декоратор](https://python-all.ru/3.9/glossary.html#term-decorator) устарел и будет удалён в версии 3.10. Вместо `@asyncio.coroutine` используйте [`async def`](https://python-all.ru/3.9/reference/compound_stmts.html#async-def). (Автор: Andrew Svetlov в [bpo-36921](https://python-all.ru/3.9/whatsnew/3.8.html).)985- В [`asyncio`](https://python-all.ru/3.9/library/asyncio.html#module-asyncio) явная передача аргумента *цикл событий* устарела и будет удалена в версии 3.10 для следующих: [`asyncio.sleep()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.sleep), [`asyncio.gather()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.gather), [`asyncio.shield()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.shield), [`asyncio.wait_for()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.wait_for), [`asyncio.wait()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.wait), [`asyncio.as_completed()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.as_completed), [`asyncio.Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task), [`asyncio.Lock`](https://python-all.ru/3.9/library/asyncio-sync.html#asyncio.Lock), [`asyncio.Event`](https://python-all.ru/3.9/library/asyncio-sync.html#asyncio.Event), [`asyncio.Condition`](https://python-all.ru/3.9/library/asyncio-sync.html#asyncio.Condition), [`asyncio.Semaphore`](https://python-all.ru/3.9/library/asyncio-sync.html#asyncio.Semaphore), [`asyncio.BoundedSemaphore`](https://python-all.ru/3.9/library/asyncio-sync.html#asyncio.BoundedSemaphore), [`asyncio.Queue`](https://python-all.ru/3.9/library/asyncio-queue.html#asyncio.Queue), [`asyncio.create_subprocess_exec()`](https://python-all.ru/3.9/library/asyncio-subprocess.html#asyncio.create_subprocess_exec) и [`asyncio.create_subprocess_shell()`](https://python-all.ru/3.9/library/asyncio-subprocess.html#asyncio.create_subprocess_shell).986- Явная передача объектов корутин в [`asyncio.wait()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.wait) устарела и будет удалена в версии 3.11. (Автор: Yury Selivanov в [bpo-34790](https://python-all.ru/3.9/whatsnew/3.8.html).)987- Следующие функции и методы устарели в модуле [`gettext`](https://python-all.ru/3.9/library/gettext.html#module-gettext): [`lgettext()`](https://python-all.ru/3.9/library/gettext.html#gettext.lgettext), [`ldgettext()`](https://python-all.ru/3.9/library/gettext.html#gettext.ldgettext), [`lngettext()`](https://python-all.ru/3.9/library/gettext.html#gettext.lngettext) и [`ldngettext()`](https://python-all.ru/3.9/library/gettext.html#gettext.ldngettext). Они возвращают закодированные байты, и возможны неожиданные исключения, связанные с Unicode, при проблемах с кодировкой переведённых строк. Гораздо лучше использовать альтернативы, которые возвращают строки Unicode в Python 3. Эти функции давно не работают должным образом.988989 Функция [`bind_textdomain_codeset()`](https://python-all.ru/3.9/library/gettext.html#gettext.bind_textdomain_codeset), методы [`output_charset()`](https://python-all.ru/3.9/library/gettext.html#gettext.NullTranslations.output_charset) и [`set_output_charset()`](https://python-all.ru/3.9/library/gettext.html#gettext.NullTranslations.set_output_charset), а также параметр *codeset* функций [`translation()`](https://python-all.ru/3.9/library/gettext.html#gettext.translation) и [`install()`](https://python-all.ru/3.9/library/gettext.html#gettext.install) также устарели, поскольку используются только для функций `l*gettext()`. (Автор: Serhiy Storchaka в [bpo-33710](https://python-all.ru/3.9/whatsnew/3.8.html).)990- Метод `isAlive()` класса [`threading.Thread`](https://python-all.ru/3.9/library/threading.html#threading.Thread) объявлен устаревшим. (Автор: Dong-hee Na в [bpo-35283](https://python-all.ru/3.9/whatsnew/3.8.html).)991- Многие встроенные и расширенные функции, принимающие целочисленные аргументы, теперь выводят предупреждение об устаревании для [`Decimal`](https://python-all.ru/3.9/library/decimal.html#decimal.Decimal), [`Fraction`](https://python-all.ru/3.9/library/fractions.html#fractions.Fraction) и любых других объектов, которые могут быть преобразованы в целые числа только с потерей (например, имеющих метод [`__int__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__int__), но не имеющих метода [`__index__()`](https://python-all.ru/3.9/reference/datamodel.html#object.__index__)). В будущих версиях это станет ошибкой. (Автор: Serhiy Storchaka в [bpo-36048](https://python-all.ru/3.9/whatsnew/3.8.html).)992- Устарела передача следующих аргументов в качестве именованных:993994 - *func* в [`functools.partialmethod()`](https://python-all.ru/3.9/library/functools.html#functools.partialmethod), [`weakref.finalize()`](https://python-all.ru/3.9/library/weakref.html#weakref.finalize), [`profile.Profile.runcall()`](https://python-all.ru/3.9/library/profile.html#profile.Profile.runcall), `cProfile.Profile.runcall()`, [`bdb.Bdb.runcall()`](https://python-all.ru/3.9/library/bdb.html#bdb.Bdb.runcall), [`trace.Trace.runfunc()`](https://python-all.ru/3.9/library/trace.html#trace.Trace.runfunc) и [`curses.wrapper()`](https://python-all.ru/3.9/library/curses.html#curses.wrapper).995 - *function* в [`unittest.TestCase.addCleanup()`](https://python-all.ru/3.9/library/unittest.html#unittest.TestCase.addCleanup).996 - *fn* в методе [`submit()`](https://python-all.ru/3.9/library/concurrent.futures.html#concurrent.futures.Executor.submit) классов [`concurrent.futures.ThreadPoolExecutor`](https://python-all.ru/3.9/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) и [`concurrent.futures.ProcessPoolExecutor`](https://python-all.ru/3.9/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor).997 - *callback* in [`contextlib.ExitStack.callback()`](https://python-all.ru/3.9/library/contextlib.html#contextlib.ExitStack.callback), `contextlib.AsyncExitStack.callback()` and [`contextlib.AsyncExitStack.push_async_callback()`](https://python-all.ru/3.9/library/contextlib.html#contextlib.AsyncExitStack.push_async_callback).998 - *c* и *typeid* в методе `create()` классов `multiprocessing.managers.Server` и `multiprocessing.managers.SharedMemoryServer`.999 - *obj* в [`weakref.finalize()`](https://python-all.ru/3.9/library/weakref.html#weakref.finalize).10001001 В будущих версиях Python они станут [только позиционными](https://python-all.ru/3.9/glossary.html#positional-only-parameter). (Автор: Serhiy Storchaka в [bpo-36492](https://python-all.ru/3.9/whatsnew/3.8.html).)10021003## Удаление API и функций10041005Следующие функции и API были удалены из Python 3.8:10061007- Начиная с Python 3.3 импорт ABCs из [`collections`](https://python-all.ru/3.9/library/collections.html#module-collections) был объявлен устаревшим, и импорт следует осуществлять из [`collections.abc`](https://python-all.ru/3.9/library/collections.abc.html#module-collections.abc). Возможность импорта из collections была помечена к удалению в 3.8, но была отложена до 3.9. (См. [bpo-36952](https://python-all.ru/3.9/whatsnew/3.8.html).)1008- Модуль `macpath`, устаревший в Python 3.7, был удалён. (Автор: Victor Stinner в [bpo-35471](https://python-all.ru/3.9/whatsnew/3.8.html).)1009- Функция `platform.popen()` была удалена после того, как была устаревшей начиная с Python 3.3: используйте вместо неё [`os.popen()`](https://python-all.ru/3.9/library/os.html#os.popen). (Автор: Victor Stinner в [bpo-35345](https://python-all.ru/3.9/whatsnew/3.8.html).)1010- Функция `time.clock()` была удалена после того, как была устаревшей начиная с Python 3.3: используйте [`time.perf_counter()`](https://python-all.ru/3.9/library/time.html#time.perf_counter) или [`time.process_time()`](https://python-all.ru/3.9/library/time.html#time.process_time) в зависимости от ваших требований, чтобы получить строго определённое поведение. (Автор: Matthias Bussonnier в [bpo-36895](https://python-all.ru/3.9/whatsnew/3.8.html).)1011- Скрипт `pyvenv` был удалён в пользу `python3.8 -m venv`, чтобы устранить путаницу с тем, к какому интерпретатору Python привязан скрипт `pyvenv`. (Автор: Brett Cannon в [bpo-25427](https://python-all.ru/3.9/whatsnew/3.8.html).)1012- `parse_qs`, `parse_qsl` и `escape` удалены из модуля [`cgi`](https://python-all.ru/3.9/library/cgi.html#module-cgi). Они устарели в Python 3.2 или старше. Их следует импортировать из модулей `urllib.parse` и `html`.1013- Функция `filemode` удалена из модуля [`tarfile`](https://python-all.ru/3.9/library/tarfile.html#module-tarfile). Она не документирована и устарела начиная с Python 3.3.1014- Конструктор [`XMLParser`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser) больше не принимает аргумент *html*. Он никогда не имел эффекта и был устаревшим в Python 3.4. Все остальные параметры теперь [только именованные](https://python-all.ru/3.9/glossary.html#keyword-only-parameter). (Автор: Serhiy Storchaka в [bpo-29209](https://python-all.ru/3.9/whatsnew/3.8.html).)1015- Удалён метод `doctype()` класса [`XMLParser`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). (Автор: Serhiy Storchaka в [bpo-29209](https://python-all.ru/3.9/whatsnew/3.8.html).)1016- Кодек «unicode\_internal» удалён. (Автор: Inada Naoki в [bpo-36297](https://python-all.ru/3.9/whatsnew/3.8.html).)1017- Объекты `Cache` и `Statement` модуля [`sqlite3`](https://python-all.ru/3.9/library/sqlite3.html#module-sqlite3) не доступны пользователю. (Автор: Aviv Palivoda в [bpo-30262](https://python-all.ru/3.9/whatsnew/3.8.html).)1018- Именованный аргумент `bufsize` функций [`fileinput.input()`](https://python-all.ru/3.9/library/fileinput.html#fileinput.input) и [`fileinput.FileInput()`](https://python-all.ru/3.9/library/fileinput.html#fileinput.FileInput), который игнорировался и был устаревшим начиная с Python 3.6, удалён. [bpo-36952](https://python-all.ru/3.9/whatsnew/3.8.html) (Автор: Matthias Bussonnier.)1019- Функции `sys.set_coroutine_wrapper()` и `sys.get_coroutine_wrapper()`, объявленные устаревшими в Python 3.7, были удалены; [bpo-36933](https://python-all.ru/3.9/whatsnew/3.8.html) (Автор: Matthias Bussonnier.)10201021## Перенос на Python 3.810221023В этом разделе перечислены ранее описанные изменения и другие исправления ошибок, которые могут потребовать изменений в вашем коде.10241025### Изменения в поведении Python10261027- Выражения yield (как `yield`, так и `yield from`) теперь запрещены в включениях и генераторных выражениях (за исключением итерируемого выражения в крайнем левом предложении `for`). (Автор: Serhiy Storchaka в [bpo-10544](https://python-all.ru/3.9/whatsnew/3.8.html).)1028- Теперь компилятор выводит [`SyntaxWarning`](https://python-all.ru/3.9/library/exceptions.html#SyntaxWarning), когда проверки идентичности (`is` и `is not`) используются с определёнными типами литералов (например, строки, числа). В CPython они часто могут работать случайно, но языковая спецификация этого не гарантирует. Предупреждение советует использовать вместо них проверки на равенство (`==` и `!=`). (Автор: Serhiy Storchaka в [bpo-34850](https://python-all.ru/3.9/whatsnew/3.8.html).)1029- Интерпретатор CPython может проглатывать исключения при некоторых обстоятельствах. В Python 3.8 это происходит в меньшем числе случаев. В частности, исключения, возникающие при получении атрибута из словаря типа, больше не игнорируются. (Автор: Serhiy Storchaka в [bpo-35459](https://python-all.ru/3.9/whatsnew/3.8.html).)1030- Удалены реализации `__str__` из встроенных типов [`bool`](https://python-all.ru/3.9/library/functions.html#bool), [`int`](https://python-all.ru/3.9/library/functions.html#int), [`float`](https://python-all.ru/3.9/library/functions.html#float), [`complex`](https://python-all.ru/3.9/library/functions.html#complex) и нескольких классов из стандартной библиотеки. Теперь они наследуют `__str__()` от [`object`](https://python-all.ru/3.9/library/functions.html#object). В результате определение метода `__repr__()` в подклассе этих классов повлияет на их строковое представление. (Автор: Serhiy Storchaka в [bpo-36793](https://python-all.ru/3.9/whatsnew/3.8.html).)1031- На AIX [`sys.platform`](https://python-all.ru/3.9/library/sys.html#sys.platform) больше не содержит мажорную версию. Теперь это всегда `'aix'`, вместо `'aix3'` .. `'aix7'`. Поскольку старые версии Python включают номер версии, рекомендуется всегда использовать `sys.platform.startswith('aix')`. (Автор: M. Felt в [bpo-36588](https://python-all.ru/3.9/whatsnew/3.8.html).)1032- [`PyEval_AcquireLock()`](https://python-all.ru/3.9/c-api/init.html#c.PyEval_AcquireLock) и [`PyEval_AcquireThread()`](https://python-all.ru/3.9/c-api/init.html#c.PyEval_AcquireThread) теперь завершают текущий поток, если вызваны во время финализации интерпретатора, что делает их согласованными с [`PyEval_RestoreThread()`](https://python-all.ru/3.9/c-api/init.html#c.PyEval_RestoreThread), [`Py_END_ALLOW_THREADS()`](https://python-all.ru/3.9/c-api/init.html#c.Py_END_ALLOW_THREADS) и [`PyGILState_Ensure()`](https://python-all.ru/3.9/c-api/init.html#c.PyGILState_Ensure). Если такое поведение нежелательно, защитите вызов проверкой `_Py_IsFinalizing()` или `sys.is_finalizing()`. (Автор: Joannah Nanjekye в [bpo-36475](https://python-all.ru/3.9/whatsnew/3.8.html).)10331034### Изменения в Python API10351036- Функция [`os.getcwdb()`](https://python-all.ru/3.9/library/os.html#os.getcwdb) теперь использует кодировку UTF-8 в Windows, вместо кодовой страницы ANSI: см. [**PEP 529**](https://python-all.ru/3.9/whatsnew/3.8.html) для обоснования. Эта функция больше не считается устаревшей в Windows. (Автор: Victor Stinner в [bpo-37412](https://python-all.ru/3.9/whatsnew/3.8.html).)1037- [`subprocess.Popen`](https://python-all.ru/3.9/library/subprocess.html#subprocess.Popen) теперь может использовать [`os.posix_spawn()`](https://python-all.ru/3.9/library/os.html#os.posix_spawn) в некоторых случаях для повышения производительности. В подсистеме Windows для Linux и эмуляции QEMU User конструктор `Popen`, использующий [`os.posix_spawn()`](https://python-all.ru/3.9/library/os.html#os.posix_spawn), больше не вызывает исключение при ошибках вроде «отсутствующая программа». Вместо этого дочерний процесс завершается с ненулевым `returncode`. (Авторы: Joannah Nanjekye и Victor Stinner, [bpo-35537](https://python-all.ru/3.9/whatsnew/3.8.html).)1038- Аргумент *preexec\_fn* функции \* [`subprocess.Popen`](https://python-all.ru/3.9/library/subprocess.html#subprocess.Popen) больше не совместим с подинтерпретаторами. Использование этого параметра в подинтерпретаторе теперь вызывает [`RuntimeError`](https://python-all.ru/3.9/library/exceptions.html#RuntimeError). (Автор: Eric Snow в [bpo-34651](https://python-all.ru/3.9/whatsnew/3.8.html), доработано Christian Heimes в [bpo-37951](https://python-all.ru/3.9/whatsnew/3.8.html).)1039- Метод `imap.IMAP4.logout()` больше не игнорирует произвольные исключения без предупреждения. (Автор: Victor Stinner в [bpo-36348](https://python-all.ru/3.9/whatsnew/3.8.html).)1040- Функция `platform.popen()` была удалена после того, как была объявлена устаревшей начиная с Python 3.3: используйте [`os.popen()`](https://python-all.ru/3.9/library/os.html#os.popen) вместо неё. (Автор: Victor Stinner в [bpo-35345](https://python-all.ru/3.9/whatsnew/3.8.html).)1041- Функция [`statistics.mode()`](https://python-all.ru/3.9/library/statistics.html#statistics.mode) больше не вызывает исключение при передаче мультимодальных данных. Вместо этого она возвращает первую моду, встреченную во входных данных. (Автор: Raymond Hettinger в [bpo-35892](https://python-all.ru/3.9/whatsnew/3.8.html).)1042- Метод [`selection()`](https://python-all.ru/3.9/library/tkinter.ttk.html#tkinter.ttk.Treeview.selection) класса [`tkinter.ttk.Treeview`](https://python-all.ru/3.9/library/tkinter.ttk.html#tkinter.ttk.Treeview) больше не принимает аргументы. Его использование с аргументами для изменения выделения было объявлено устаревшим в Python 3.6. Используйте специализированные методы, например [`selection_set()`](https://python-all.ru/3.9/library/tkinter.ttk.html#tkinter.ttk.Treeview.selection_set), для изменения выделения. (Автор: Serhiy Storchaka в [bpo-31508](https://python-all.ru/3.9/whatsnew/3.8.html).)1043- Методы `writexml()`, `toxml()` и `toprettyxml()` класса [`xml.dom.minidom`](https://python-all.ru/3.9/library/xml.dom.minidom.html#module-xml.dom.minidom), а также метод `write()` класса `xml.etree`, теперь сохраняют порядок атрибутов, заданный пользователем. (Авторы: Diego Rojas и Raymond Hettinger, [bpo-34160](https://python-all.ru/3.9/whatsnew/3.8.html).)1044- База данных [`dbm.dumb`](https://python-all.ru/3.9/library/dbm.html#module-dbm.dumb), открытая с флагами `'r'`, теперь доступна только для чтения. [`dbm.dumb.open()`](https://python-all.ru/3.9/library/dbm.html#dbm.dumb.open) с флагами `'r'` и `'w'` больше не создаёт базу данных, если она не существует. (Автор: Serhiy Storchaka в [bpo-32749](https://python-all.ru/3.9/whatsnew/3.8.html).)1045- Метод `doctype()`, определённый в подклассе [`XMLParser`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser), больше не будет вызываться и будет выдавать [`RuntimeWarning`](https://python-all.ru/3.9/library/exceptions.html#RuntimeWarning) вместо [`DeprecationWarning`](https://python-all.ru/3.9/library/exceptions.html#DeprecationWarning). Определите метод [`doctype()`](https://python-all.ru/3.9/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder.doctype) на цели для обработки объявления типа документа XML. (Автор: Serhiy Storchaka в [bpo-29209](https://python-all.ru/3.9/whatsnew/3.8.html).)1046- Теперь вызывается [`RuntimeError`](https://python-all.ru/3.9/library/exceptions.html#RuntimeError), когда пользовательский метакласс не предоставляет запись `__classcell__` в пространстве имён, переданном в `type.__new__`. В Python 3.6–3.7 выдавалось [`DeprecationWarning`](https://python-all.ru/3.9/library/exceptions.html#DeprecationWarning). (Автор: Serhiy Storchaka в [bpo-23722](https://python-all.ru/3.9/whatsnew/3.8.html).)1047- Класс `cProfile.Profile` теперь можно использовать как менеджер контекста. (Автор: Scott Sanderson, [bpo-29235](https://python-all.ru/3.9/whatsnew/3.8.html).)1048- [`shutil.copyfile()`](https://python-all.ru/3.9/library/shutil.html#shutil.copyfile), [`shutil.copy()`](https://python-all.ru/3.9/library/shutil.html#shutil.copy), [`shutil.copy2()`](https://python-all.ru/3.9/library/shutil.html#shutil.copy2), [`shutil.copytree()`](https://python-all.ru/3.9/library/shutil.html#shutil.copytree) и [`shutil.move()`](https://python-all.ru/3.9/library/shutil.html#shutil.move) используют платформозависимые системные вызовы «быстрого копирования» (см. раздел [Эффективные операции копирования, зависящие от платформы](https://python-all.ru/3.9/library/shutil.html#shutil-platform-dependent-efficient-copy-operations)).1049- Размер буфера по умолчанию [`shutil.copyfile()`](https://python-all.ru/3.9/library/shutil.html#shutil.copyfile) в Windows изменён с 16 Киб на 1 МиБ.1050- Структура `PyGC_Head` полностью изменена. Весь код, который обращался к полям структуры, должен быть переписан. (См. [bpo-33597](https://python-all.ru/3.9/whatsnew/3.8.html).)1051- Структура [`PyInterpreterState`](https://python-all.ru/3.9/c-api/init.html#c.PyInterpreterState) была перемещена во «внутренние» заголовочные файлы (конкретно Include/internal/pycore\_pystate.h). Непрозрачный `PyInterpreterState` по-прежнему доступен как часть публичного API (и стабильного ABI). В документации указано, что ни одно из полей структуры не является публичным, поэтому мы надеемся, что никто их не использовал. Однако, если вы действительно полагаетесь на одно или несколько из этих частных полей и у вас нет альтернативы, пожалуйста, откройте проблему на BPO. Мы поможем вам адаптироваться (возможно, включая добавление функций доступа в публичный API). (См. [bpo-35886](https://python-all.ru/3.9/whatsnew/3.8.html).)1052- Метод [`mmap.flush()`](https://python-all.ru/3.9/library/mmap.html#mmap.mmap.flush) теперь возвращает `None` в случае успеха и вызывает исключение при ошибке на всех платформах. Ранее его поведение зависело от платформы: на Windows возвращалось ненулевое значение при успехе; ноль при ошибке. На Unix возвращалось нулевое значение при успехе; при ошибке вызывалось исключение. (Автор: Berker Peksag в [bpo-2122](https://python-all.ru/3.9/whatsnew/3.8.html).)1053- Модули [`xml.dom.minidom`](https://python-all.ru/3.9/library/xml.dom.minidom.html#module-xml.dom.minidom) и [`xml.sax`](https://python-all.ru/3.9/library/xml.sax.html#module-xml.sax) больше не обрабатывают внешние сущности по умолчанию. (Автор: Christian Heimes в [bpo-17239](https://python-all.ru/3.9/whatsnew/3.8.html).)1054- Удаление ключа из базы данных [`dbm`](https://python-all.ru/3.9/library/dbm.html#module-dbm), доступной только для чтения ([`dbm.dumb`](https://python-all.ru/3.9/library/dbm.html#module-dbm.dumb), [`dbm.gnu`](https://python-all.ru/3.9/library/dbm.html#module-dbm.gnu) или [`dbm.ndbm`](https://python-all.ru/3.9/library/dbm.html#module-dbm.ndbm)), вызывает `error` ([`dbm.dumb.error`](https://python-all.ru/3.9/library/dbm.html#dbm.dumb.error), [`dbm.gnu.error`](https://python-all.ru/3.9/library/dbm.html#dbm.gnu.error) или [`dbm.ndbm.error`](https://python-all.ru/3.9/library/dbm.html#dbm.ndbm.error)) вместо [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError). (Автор: Xiang Zhang в [bpo-33106](https://python-all.ru/3.9/whatsnew/3.8.html).)1055- Упрощён AST для литералов. Все константы будут представлены как экземпляры [`ast.Constant`](https://python-all.ru/3.9/library/ast.html#ast.Constant). Создание экземпляров старых классов `Num`, `Str`, `Bytes`, `NameConstant` и `Ellipsis` будет возвращать экземпляр `Constant`. (Автор: Serhiy Storchaka в [bpo-32892](https://python-all.ru/3.9/whatsnew/3.8.html).)1056- [`expanduser()`](https://python-all.ru/3.9/library/os.path.html#os.path.expanduser) в Windows теперь предпочитает переменную окружения `USERPROFILE` и не использует `HOME`, которая обычно не установлена для обычных учётных записей пользователей. (Автор: Anthony Sottile в [bpo-36264](https://python-all.ru/3.9/whatsnew/3.8.html).)1057- Исключение [`asyncio.CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError) теперь наследуется от [`BaseException`](https://python-all.ru/3.9/library/exceptions.html#BaseException) вместо [`Exception`](https://python-all.ru/3.9/library/exceptions.html#Exception) и больше не наследуется от [`concurrent.futures.CancelledError`](https://python-all.ru/3.9/library/concurrent.futures.html#concurrent.futures.CancelledError). (Автор: Yury Selivanov в [bpo-32528](https://python-all.ru/3.9/whatsnew/3.8.html).)1058- Функция [`asyncio.wait_for()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.wait_for) теперь корректно ожидает отмены при использовании экземпляра [`asyncio.Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task). Ранее по достижении *timeout* она отменялась и сразу возвращала управление. (Автор: Elvis Pranskevichus в [bpo-32751](https://python-all.ru/3.9/whatsnew/3.8.html).)1059- Функция [`asyncio.BaseTransport.get_extra_info()`](https://python-all.ru/3.9/library/asyncio-protocol.html#asyncio.BaseTransport.get_extra_info) теперь возвращает готовый к использованию объект сокета, когда 'socket' передаётся в параметр *name*. (Автор: Yury Selivanov в [bpo-37027](https://python-all.ru/3.9/whatsnew/3.8.html).)1060- [`asyncio.BufferedProtocol`](https://python-all.ru/3.9/library/asyncio-protocol.html#asyncio.BufferedProtocol) перешёл в стабильный API.10611062- Зависимости DLL для модулей расширения и DLL, загружаемых с помощью [`ctypes`](https://python-all.ru/3.9/library/ctypes.html#module-ctypes) в Windows, теперь разрешаются более безопасно. Для поиска зависимостей во время загрузки используются только системные пути, каталог, содержащий DLL- или PYD-файл, и каталоги, добавленные с помощью [`add_dll_directory()`](https://python-all.ru/3.9/library/os.html#os.add_dll_directory). В частности, `PATH` и текущий рабочий каталог больше не используются, и изменения в них больше не будут влиять на обычное разрешение DLL. Если ваше приложение полагается на эти механизмы, следует проверить наличие [`add_dll_directory()`](https://python-all.ru/3.9/library/os.html#os.add_dll_directory) и, если он существует, использовать его для добавления каталога ваших DLL во время загрузки библиотеки. Обратите внимание, что пользователи Windows 7 должны убедиться, что установлено обновление Windows KB2533623 (это также проверяется установщиком). (Автор: Steve Dower в [bpo-36085](https://python-all.ru/3.9/whatsnew/3.8.html).)1063- Заголовочные файлы и функции, связанные с pgen, были удалены после его замены на чистую реализацию на Python. (Автор: Pablo Galindo в [bpo-36623](https://python-all.ru/3.9/whatsnew/3.8.html).)1064- [`types.CodeType`](https://python-all.ru/3.9/library/types.html#types.CodeType) имеет новый параметр на второй позиции конструктора (*posonlyargcount*) для поддержки позиционных аргументов, определённых в [**PEP 570**](https://python-all.ru/3.9/whatsnew/3.8.html). Первый аргумент (*argcount*) теперь представляет общее количество позиционных аргументов (включая позиционные аргументы). Новый метод `replace()` класса [`types.CodeType`](https://python-all.ru/3.9/library/types.html#types.CodeType) можно использовать для обеспечения перспективности кода.1065- Параметр `digestmod` для [`hmac.new()`](https://python-all.ru/3.9/library/hmac.html#hmac.new) больше не использует дайджест MD5 по умолчанию.10661067### Изменения в C API10681069- Структура [`PyCompilerFlags`](https://python-all.ru/3.9/c-api/veryhigh.html#c.PyCompilerFlags) получила новое поле *cf\_feature\_version*. Его следует инициализировать значением `PY_MINOR_VERSION`. По умолчанию это поле игнорируется и используется только в том случае, если в *cf\_flags* установлен флаг `PyCF_ONLY_AST`. (Автор: Guido van Rossum в [bpo-35766](https://python-all.ru/3.9/whatsnew/3.8.html).)1070- Функция `PyEval_ReInitThreads()` удалена из C API. Её не следует вызывать явно; вместо этого используйте [`PyOS_AfterFork_Child()`](https://python-all.ru/3.9/c-api/sys.html#c.PyOS_AfterFork_Child). (Автор: Victor Stinner в [bpo-36728](https://python-all.ru/3.9/whatsnew/3.8.html).)1071- В Unix расширения на C больше не линкуются с libpython, за исключением Android и Cygwin. Когда Python встраивается, `libpython` должна загружаться не с помощью `RTLD_LOCAL`, а с помощью `RTLD_GLOBAL`. Ранее с использованием `RTLD_LOCAL` уже было невозможно загрузить расширения на C, которые не были слинкованы с `libpython`, например расширения на C из стандартной библиотеки, собранные разделом `*shared*` файла `Modules/Setup`. (Автор: Victor Stinner в [bpo-21536](https://python-all.ru/3.9/whatsnew/3.8.html).)1072- Использование вариантов форматов `#` при разборе или построении значения (например, [`PyArg_ParseTuple()`](https://python-all.ru/3.9/c-api/arg.html#c.PyArg_ParseTuple), [`Py_BuildValue()`](https://python-all.ru/3.9/c-api/arg.html#c.Py_BuildValue), [`PyObject_CallFunction()`](https://python-all.ru/3.9/c-api/call.html#c.PyObject_CallFunction) и т.д.) без определения `PY_SSIZE_T_CLEAN` теперь вызывает `DeprecationWarning`. Это будет удалено в версии 3.10 или 4.0. Подробнее читайте в [Parsing arguments and building values](https://python-all.ru/3.9/c-api/arg.html#arg-parsing). (Автор: Inada Naoki в [bpo-36381](https://python-all.ru/3.9/whatsnew/3.8.html).)1073- Экземпляры типов, выделяемых в куче (например, созданных с помощью [`PyType_FromSpec()`](https://python-all.ru/3.9/c-api/type.html#c.PyType_FromSpec)), содержат ссылку на свой объект-тип. Увеличение счётчика ссылок этих объектов-типов было перенесено из [`PyType_GenericAlloc()`](https://python-all.ru/3.9/c-api/type.html#c.PyType_GenericAlloc) в более низкоуровневые функции [`PyObject_Init()`](https://python-all.ru/3.9/c-api/allocation.html#c.PyObject_Init) и `PyObject_INIT()`. Это заставляет типы, созданные через [`PyType_FromSpec()`](https://python-all.ru/3.9/c-api/type.html#c.PyType_FromSpec), вести себя как другие классы в управляемом коде.10741075 Статически размещённые типы не затрагиваются.10761077 В подавляющем большинстве случаев побочных эффектов не должно быть. Однако типы, которые вручную увеличивают счётчик ссылок после выделения экземпляра (возможно, в обход ошибки), теперь могут стать бессмертными. Чтобы этого избежать, таким классам необходимо вызывать Py\_DECREF для объекта-типа во время освобождения экземпляра.10781079 Чтобы правильно перенести эти типы в 3.8, примените следующие изменения:10801081 - Удалите [`Py_INCREF`](https://python-all.ru/3.9/c-api/refcounting.html#c.Py_INCREF) для объекта-типа после выделения экземпляра – если таковой имеется. Это может произойти после вызова [`PyObject_New()`](https://python-all.ru/3.9/c-api/allocation.html#c.PyObject_New), [`PyObject_NewVar()`](https://python-all.ru/3.9/c-api/allocation.html#c.PyObject_NewVar), [`PyObject_GC_New()`](https://python-all.ru/3.9/c-api/gcsupport.html#c.PyObject_GC_New), [`PyObject_GC_NewVar()`](https://python-all.ru/3.9/c-api/gcsupport.html#c.PyObject_GC_NewVar) или любого другого пользовательского аллокатора, использующего [`PyObject_Init()`](https://python-all.ru/3.9/c-api/allocation.html#c.PyObject_Init) или `PyObject_INIT()`.10821083 Пример:10841085 ```c1086 static foo_struct *1087 foo_new(PyObject *type) {1088 foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type);1089 if (foo == NULL)1090 return NULL;1091 #if PY_VERSION_HEX < 0x030800001092 // Обходной путь для Python issue 35810; начиная с Python 3.8 больше не нужен1093 PY_INCREF(type)1094 #endif1095 return foo;1096 }1097 ```1098 - Убедитесь, что все пользовательские функции `tp_dealloc` типов, выделяемых в куче, уменьшают счётчик ссылок типа.10991100 Пример:11011102 ```c1103 static void1104 foo_dealloc(foo_struct *instance) {1105 PyObject *type = Py_TYPE(instance);1106 PyObject_GC_Del(instance);1107 #if PY_VERSION_HEX >= 0x030800001108 // До Python 3.8 в этом не было необходимости (Python issue 35810)1109 Py_DECREF(type);1110 #endif1111 }1112 ```11131114 (Автор: Eddie Elizondo в [bpo-35810](https://python-all.ru/3.9/whatsnew/3.8.html).)1115- Макрос `Py_DEPRECATED()` реализован для MSVC. Теперь макрос должен размещаться перед именем символа.11161117 Пример:11181119 ```c1120 Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);1121 ```11221123 (Автор: Zackery Spytz в [bpo-33407](https://python-all.ru/3.9/whatsnew/3.8.html).)1124- Интерпретатор больше не претендует на поддержку двоичной совместимости типов расширений между выпусками с новыми возможностями. Экспортируемая модулем расширения третьей стороны структура [`PyTypeObject`](https://python-all.ru/3.9/c-api/type.html#c.PyTypeObject) должна содержать все слоты, ожидаемые в текущей версии Python, включая [`tp_finalize`](https://python-all.ru/3.9/c-api/typeobj.html#c.PyTypeObject.tp_finalize) ([`Py_TPFLAGS_HAVE_FINALIZE`](https://python-all.ru/3.9/c-api/typeobj.html#Py_TPFLAGS_HAVE_FINALIZE) больше не проверяется перед чтением [`tp_finalize`](https://python-all.ru/3.9/c-api/typeobj.html#c.PyTypeObject.tp_finalize)).11251126 (Автор: Antoine Pitrou в [bpo-32388](https://python-all.ru/3.9/whatsnew/3.8.html).)1127- Функции `PyNode_AddChild()` и `PyParser_AddToken()` теперь принимают два дополнительных аргумента `int`: *end\_lineno* и *end\_col\_offset*.1128- Файл `libpython38.a`, позволяющий инструментам MinGW линковаться напрямую с `python38.dll`, больше не включается в обычный дистрибутив Windows. Если вам требуется этот файл, его можно сгенерировать с помощью инструментов `gendef` и `dlltool`, которые входят в пакет MinGW binutils:11291130 ```shell1131 gendef - python38.dll > tmp.def1132 dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a1133 ```11341135 Расположение установленного файла `pythonXY.dll` будет зависеть от параметров установки, а также версии и языка Windows. См. [Using Python on Windows](https://python-all.ru/3.9/using/windows.html#using-on-windows) для получения дополнительной информации. Полученную библиотеку следует поместить в тот же каталог, что и `pythonXY.lib`, который обычно находится в каталоге `libs` вашей установки Python.11361137 (Автор: Steve Dower в [bpo-37351](https://python-all.ru/3.9/whatsnew/3.8.html).)11381139### Изменения байткода CPython11401141- Цикл интерпретатора был упрощён за счёт переноса логики разворачивания стека блоков в компилятор. Теперь компилятор генерирует явные инструкции для корректировки стека значений и вызова кода очистки для [`break`](https://python-all.ru/3.9/reference/simple_stmts.html#break), [`continue`](https://python-all.ru/3.9/reference/simple_stmts.html#continue) и [`return`](https://python-all.ru/3.9/reference/simple_stmts.html#return).11421143 Удалены опкоды `BREAK_LOOP`, `CONTINUE_LOOP`, `SETUP_LOOP` и `SETUP_EXCEPT`. Добавлены новые опкоды [`ROT_FOUR`](https://python-all.ru/3.9/library/dis.html#opcode-ROT_FOUR), `BEGIN_FINALLY`, `CALL_FINALLY` и `POP_FINALLY`. Изменено поведение `END_FINALLY` и `WITH_CLEANUP_START`.11441145 (Авторы: Mark Shannon, Antoine Pitrou и Serhiy Storchaka в [bpo-17611](https://python-all.ru/3.9/whatsnew/3.8.html).)1146- Добавлен новый опкод [`END_ASYNC_FOR`](https://python-all.ru/3.9/library/dis.html#opcode-END_ASYNC_FOR) для обработки исключений, возникающих при ожидании следующего элемента в цикле [`async for`](https://python-all.ru/3.9/reference/compound_stmts.html#async-for). (Автор: Serhiy Storchaka в [bpo-33041](https://python-all.ru/3.9/whatsnew/3.8.html).)1147- [`MAP_ADD`](https://python-all.ru/3.9/library/dis.html#opcode-MAP_ADD) теперь ожидает значение как первый элемент в стеке, а ключ – как второй элемент. Это изменение было сделано для того, чтобы ключ всегда вычислялся до значения в словарных включениях, как предложено в [**PEP 572**](https://python-all.ru/3.9/whatsnew/3.8.html). (Автор: Jörn Heissler в [bpo-35224](https://python-all.ru/3.9/whatsnew/3.8.html).)11481149### Демонстрации и инструменты11501151Добавлен скрипт для бенчмаркинга различных способов доступа к переменным: `Tools/scripts/var_access_benchmark.py`. (Автор: Raymond Hettinger в [bpo-35884](https://python-all.ru/3.9/whatsnew/3.8.html).)11521153Краткий обзор улучшений производительности с Python 3.3:11541155```text1156Python version 3.3 3.4 3.5 3.6 3.7 3.81157-------------- --- --- --- --- --- ---11581159Variable and attribute read access:1160 read_local 4.0 7.1 7.1 5.4 5.1 3.91161 read_nonlocal 5.3 7.1 8.1 5.8 5.4 4.41162 read_global 13.3 15.5 19.0 14.3 13.6 7.61163 read_builtin 20.0 21.1 21.6 18.5 19.0 7.51164 read_classvar_from_class 20.5 25.6 26.5 20.7 19.5 18.41165 read_classvar_from_instance 18.5 22.8 23.5 18.8 17.1 16.41166 read_instancevar 26.8 32.4 33.1 28.0 26.3 25.41167 read_instancevar_slots 23.7 27.8 31.3 20.8 20.8 20.21168 read_namedtuple 68.5 73.8 57.5 45.0 46.8 18.41169 read_boundmethod 29.8 37.6 37.9 29.6 26.9 27.711701171Variable and attribute write access:1172 write_local 4.6 8.7 9.3 5.5 5.3 4.31173 write_nonlocal 7.3 10.5 11.1 5.6 5.5 4.71174 write_global 15.9 19.7 21.2 18.0 18.0 15.81175 write_classvar 81.9 92.9 96.0 104.6 102.1 39.21176 write_instancevar 36.4 44.6 45.8 40.0 38.9 35.51177 write_instancevar_slots 28.7 35.6 36.1 27.3 26.6 25.711781179Data structure read access:1180 read_list 19.2 24.2 24.5 20.8 20.8 19.01181 read_deque 19.9 24.7 25.5 20.2 20.6 19.81182 read_dict 19.7 24.3 25.7 22.3 23.0 21.01183 read_strdict 17.9 22.6 24.3 19.5 21.2 18.911841185Data structure write access:1186 write_list 21.2 27.1 28.5 22.5 21.6 20.01187 write_deque 23.8 28.7 30.1 22.7 21.8 23.51188 write_dict 25.9 31.4 33.3 29.3 29.2 24.71189 write_strdict 22.9 28.4 29.9 27.5 25.2 23.111901191Stack (or queue) operations:1192 list_append_pop 144.2 93.4 112.7 75.4 74.2 50.81193 deque_append_pop 30.4 43.5 57.0 49.4 49.2 42.51194 deque_append_popleft 30.8 43.7 57.3 49.7 49.7 42.811951196Timing loop:1197 loop_overhead 0.3 0.5 0.6 0.4 0.3 0.31198```11991200Тесты производительности проводились на процессоре [Intel® Core™ i7-4960HQ processor](https://python-all.ru/3.9/whatsnew/3.8.html) под управлением 64-битных сборок macOS с [python.org](https://python-all.ru/3.9/whatsnew/3.8.html). Скрипт тестирования выводит время в наносекундах.12011202## Заметные изменения в Python 3.8.112031204Из-за серьёзных проблем безопасности параметр *reuse\_address* функции [`asyncio.loop.create_datagram_endpoint()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint) больше не поддерживается. Это связано с поведением опции сокета `SO_REUSEADDR` в UDP. Подробнее см. документацию `loop.create_datagram_endpoint()`. (Авторы: Kyle Stanley, Antoine Pitrou и Yury Selivanov в [bpo-37228](https://python-all.ru/3.9/whatsnew/3.8.html).)12051206## Заметные изменения в Python 3.8.812071208Более ранние версии Python допускали использование как `;`, так и `&` в качестве разделителей параметров запроса в [`urllib.parse.parse_qs()`](https://python-all.ru/3.9/library/urllib.parse.html#urllib.parse.parse_qs) и [`urllib.parse.parse_qsl()`](https://python-all.ru/3.9/library/urllib.parse.html#urllib.parse.parse_qsl). Из соображений безопасности и для соответствия новым рекомендациям W3C это поведение было изменено: теперь разрешён только один ключ-разделитель, `&` по умолчанию. Это изменение также затрагивает [`cgi.parse()`](https://python-all.ru/3.9/library/cgi.html#cgi.parse) и [`cgi.parse_multipart()`](https://python-all.ru/3.9/library/cgi.html#cgi.parse_multipart), поскольку они внутренне используют затронутые функции. Дополнительные сведения см. в их документации. (Авторы: Adam Goldschmidt, Senthil Kumaran и Ken Jin в [bpo-42967](https://python-all.ru/3.9/whatsnew/3.8.html).)12091210## Заметные изменения в Python 3.8.1212111212Начиная с Python 3.8.12 модуль [`ipaddress`](https://python-all.ru/3.9/library/ipaddress.html#module-ipaddress) больше не принимает ведущие нули в строках IPv4-адресов. Ведущие нули неоднозначны и некоторые библиотеки интерпретируют их как восьмеричную запись. Например, устаревшая функция [`socket.inet_aton()`](https://python-all.ru/3.9/library/socket.html#socket.inet_aton) трактует ведущие нули как восьмеричную запись. Реализация glibc современного [`inet_pton()`](https://python-all.ru/3.9/library/socket.html#socket.inet_pton) не принимает ведущие нули.12131214(Первоначально предоставлено Christian Heimes в [bpo-36384](https://python-all.ru/3.9/whatsnew/3.8.html), бэкпортировано в 3.8 Achraf Merzouki.)1215