3.2.md
1> **Источник:** https://python-all.ru/3.10/whatsnew/3.2.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Что нового в Python 3.289**Автор**1011Raymond Hettinger1213В этой статье описаны новые возможности Python 3.2 по сравнению с 3.1. Python 3.2 был выпущен 20 февраля 2011 года. Статья освещает несколько ключевых моментов и приводит несколько примеров. За полными подробностями обращайтесь к [Misc/NEWS](https://python-all.ru/3.10/whatsnew/3.2.html) файлу.1415> **См. также**16>17> [**PEP 392**](https://python-all.ru/3.10/whatsnew/3.2.html) - График выпуска Python 3.21819## PEP 384: Определение стабильного ABI2021Раньше модули расширения, собранные для одной версии Python, часто были несовместимы с другими версиями. Особенно в Windows каждый выпуск с новыми возможностями требовал пересборки всех модулей расширения, которые хотелось использовать. Это было следствием свободного доступа к внутренним структурам интерпретатора Python, который могли использовать модули расширения.2223В Python 3.2 появляется альтернативный подход: модули расширения, ограничивающие себя ограниченным API (определяя Py\_LIMITED\_API), не могут использовать многие внутренние структуры, но ограничены набором функций API, которые обещают быть стабильными на протяжении нескольких выпусков. В результате модули расширения, собранные для 3.2 в этом режиме, будут также работать с 3.3, 3.4 и так далее. Модули расширения, использующие детали структур памяти, по-прежнему можно собирать, но их придётся перекомпилировать для каждого выпуска с новыми возможностями.2425> **См. также**26>27> **[**PEP 384**](https://python-all.ru/3.10/whatsnew/3.2.html) - Определение стабильного ABI**28>29> PEP написан Мартином фон Лёвисом.3031## PEP 389: Модуль разбора командной строки argparse3233Новый модуль для разбора командной строки, [`argparse`](https://python-all.ru/3.10/library/argparse.html#module-argparse), был представлен, чтобы преодолеть ограничения [`optparse`](https://python-all.ru/3.10/library/optparse.html#module-optparse), который не поддерживал позиционные аргументы (не только опции), подкоманды, обязательные опции и другие типовые паттерны задания и проверки опций.3435Этот модуль уже получил широкое распространение в сообществе как сторонний модуль. Будучи более функциональным, чем его предшественник, модуль [`argparse`](https://python-all.ru/3.10/library/argparse.html#module-argparse) теперь является предпочтительным для обработки командной строки. Старый модуль по-прежнему доступен из-за большого объёма устаревшего кода, который от него зависит.3637Вот пример аннотированного парсера, показывающий такие возможности, как ограничение результатов набором вариантов, указание *metavar* в справке, проверка наличия одного или нескольких позиционных аргументов и создание обязательной опции:3839```python40import argparse41parser = argparse.ArgumentParser(42 description = 'Manage servers', # основное описание для справки43 epilog = 'Tested on Solaris and Linux') # отображается после справки44parser.add_argument('action', # имя аргумента45 choices = ['deploy', 'start', 'stop'], # три допустимых значения46 help = 'action on each target') # сообщение справки47parser.add_argument('targets',48 metavar = 'HOSTNAME', # имя переменной, используемое в сообщении справки49 nargs = '+', # требуется одна или несколько целей50 help = 'url for target machines') # пояснение к сообщению справки51parser.add_argument('-u', '--user', # опция -u или --user52 required = True, # сделать его обязательным аргументом53 help = 'login as user')54```5556Пример вызова парсера для командной строки:5758```python59>>> cmd = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'60>>> result = parser.parse_args(cmd.split())61>>> result.action62'deploy'63>>> result.targets64['sneezy.example.com', 'sleepy.example.com']65>>> result.user66'skycaptain'67```6869Пример автоматически сгенерированной справки парсера:7071```python72>>> parser.parse_args('-h'.split())7374usage: manage_cloud.py [-h] -u USER75 {deploy,start,stop} HOSTNAME [HOSTNAME ...]7677Manage servers7879positional arguments:80 {deploy,start,stop} action on each target81 HOSTNAME url for target machines8283optional arguments:84 -h, --help show this help message and exit85 -u USER, --user USER login as user8687Tested on Solaris and Linux88```8990Особенно удобная возможность [`argparse`](https://python-all.ru/3.10/library/argparse.html#module-argparse) – это возможность определять подпарсеры, каждый со своими шаблонами аргументов и справкой:9192```python93import argparse94parser = argparse.ArgumentParser(prog='HELM')95subparsers = parser.add_subparsers()9697parser_l = subparsers.add_parser('launch', help='Launch Control') # первая подгруппа98parser_l.add_argument('-m', '--missiles', action='store_true')99parser_l.add_argument('-t', '--torpedos', action='store_true')100101parser_m = subparsers.add_parser('move', help='Move Vessel', # вторая подгруппа102 aliases=('steer', 'turn')) # эквивалентные имена103parser_m.add_argument('-c', '--course', type=int, required=True)104parser_m.add_argument('-s', '--speed', type=int, default=0)105```106107```console108$ ./helm.py --help # справка верхнего уровня (запуск и перемещение)109$ ./helm.py launch --help # справка по параметрам запуска110$ ./helm.py launch --missiles # задать missiles=True и torpedos=False111$ ./helm.py steer --course 180 --speed 5 # задать параметры движения112```113114> **См. также**115>116> **[**PEP 389**](https://python-all.ru/3.10/whatsnew/3.2.html) - Новый модуль разбора командной строки**117>118> PEP написан Стивеном Бетардом.119>120> [Обновление кода optparse](https://python-all.ru/3.10/library/argparse.html#upgrading-optparse-code) за подробностями о различиях с [`optparse`](https://python-all.ru/3.10/library/optparse.html#module-optparse).121122## PEP 391: Конфигурация логирования на основе словарей123124Модуль [`logging`](https://python-all.ru/3.10/library/logging.html#module-logging) предоставлял два вида конфигурации: один строится на вызовах функций для каждого параметра, другой – на внешнем файле в формате `ConfigParser`. Эти варианты не давали гибкости для создания конфигураций из файлов JSON или YAML, а также не поддерживали инкрементальную настройку, необходимую для задания параметров логгера из командной строки.125126Для поддержки более гибкого подхода модуль теперь предлагает [`logging.config.dictConfig()`](https://python-all.ru/3.10/library/logging.config.html#logging.config.dictConfig) для задания конфигурации логирования с помощью обычных словарей Python. Параметры конфигурации включают форматтеры, обработчики, фильтры и логгеры. Вот рабочий пример словаря конфигурации:127128```python129{"version": 1,130 "formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},131 "full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"}132 },133 "handlers": {"console": {134 "class": "logging.StreamHandler",135 "formatter": "brief",136 "level": "INFO",137 "stream": "ext://sys.stdout"},138 "console_priority": {139 "class": "logging.StreamHandler",140 "formatter": "full",141 "level": "ERROR",142 "stream": "ext://sys.stderr"}143 },144 "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}145```146147Если этот словарь сохранён в файле `conf.json`, его можно загрузить и вызвать следующим кодом:148149```python150>>> import json, logging.config151>>> with open('conf.json') as f:152... conf = json.load(f)153...154>>> logging.config.dictConfig(conf)155>>> logging.info("Transaction completed normally")156INFO : root : Transaction completed normally157>>> logging.critical("Abnormal termination")1582011-02-17 11:14:36,694 root CRITICAL Abnormal termination159```160161> **См. также**162>163> **[**PEP 391**](https://python-all.ru/3.10/whatsnew/3.2.html) – Конфигурация логирования на основе словарей**164>165> PEP написан Винаем Саджипом.166167## PEP 3148: Модуль `concurrent.futures`168169Код для создания параллельного выполнения и управления им собирается в новом пространстве имён верхнего уровня *concurrent*. Первый его компонент – пакет *futures*, предоставляющий единый высокоуровневый интерфейс для управления потоками и процессами.170171Дизайн [`concurrent.futures`](https://python-all.ru/3.10/library/concurrent.futures.html#module-concurrent.futures) был вдохновлён пакетом *java.util.concurrent*. В этой модели выполняющийся вызов и его результат представлены объектом [`Future`](https://python-all.ru/3.10/library/concurrent.futures.html#concurrent.futures.Future), который абстрагирует общие для потоков, процессов и удалённых вызовов возможности. Этот объект поддерживает проверку состояния (выполняется или завершён), таймауты, отмены, добавление колбэков и доступ к результатам или исключениям.172173Основная часть нового модуля – два класса исполнителей для запуска и управления вызовами. Цель исполнителей – упростить использование существующих инструментов для параллельных вызовов. Они избавляют от необходимости настраивать пул ресурсов, запускать вызовы, создавать очередь результатов, добавлять обработку таймаутов и ограничивать общее количество потоков, процессов или удалённых вызовов.174175В идеале каждое приложение должно использовать один общий исполнитель для нескольких компонентов, чтобы ограничения на процессы и потоки управлялись централизованно. Это решает проблему проектирования, возникающую, когда у каждого компонента своя конкурирующая стратегия управления ресурсами.176177Оба класса имеют общий интерфейс с тремя методами: [`submit()`](https://python-all.ru/3.10/library/concurrent.futures.html#concurrent.futures.Executor.submit) для планирования вызываемого объекта и возврата объекта [`Future`](https://python-all.ru/3.10/library/concurrent.futures.html#concurrent.futures.Future); [`map()`](https://python-all.ru/3.10/library/concurrent.futures.html#concurrent.futures.Executor.map) для планирования нескольких асинхронных вызовов одновременно и [`shutdown()`](https://python-all.ru/3.10/library/concurrent.futures.html#concurrent.futures.Executor.shutdown) для освобождения ресурсов. Класс является [контекстным менеджером](https://python-all.ru/3.10/glossary.html#term-context-manager) и может использоваться в операторе [`with`](https://python-all.ru/3.10/reference/compound_stmts.html#with), чтобы гарантировать автоматическое освобождение ресурсов после завершения всех ожидающих future.178179Простой пример [`ThreadPoolExecutor`](https://python-all.ru/3.10/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) – запуск четырёх параллельных потоков для копирования файлов:180181```python182import concurrent.futures, shutil183with concurrent.futures.ThreadPoolExecutor(max_workers=4) as e:184 e.submit(shutil.copy, 'src1.txt', 'dest1.txt')185 e.submit(shutil.copy, 'src2.txt', 'dest2.txt')186 e.submit(shutil.copy, 'src3.txt', 'dest3.txt')187 e.submit(shutil.copy, 'src3.txt', 'dest4.txt')188```189190> **См. также**191>192> **[**PEP 3148**](https://python-all.ru/3.10/whatsnew/3.2.html) – Futures – асинхронное выполнение вычислений**193>194> PEP написан Брайаном Куинланом.195>196> [Код для параллельного чтения URL в потоках](https://python-all.ru/3.10/library/concurrent.futures.html#threadpoolexecutor-example) – пример использования потоков для параллельной загрузки нескольких веб-страниц.197>198> [Код для параллельного вычисления простых чисел](https://python-all.ru/3.10/library/concurrent.futures.html#processpoolexecutor-example) – пример, демонстрирующий [`ProcessPoolExecutor`](https://python-all.ru/3.10/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor).199200## PEP 3147: Директории репозитория PYC201202Схема кэширования байт-кода Python в файлы *.pyc* плохо работала в средах с несколькими интерпретаторами Python. Если один интерпретатор встречал кэшированный файл, созданный другим, он перекомпилировал исходный код и перезаписывал кэш, теряя преимущества кэширования.203204Проблема «pyc-войн» стала более заметной, поскольку в дистрибутивах Linux стало обычным делом поставлять несколько версий Python. Эти конфликты возникают и с альтернативными реализациями CPython, такими как Unladen Swallow.205206Чтобы решить эту проблему, механизм импорта Python был расширен для использования разных имён файлов для каждого интерпретатора. Вместо того чтобы Python 3.2, Python 3.3 и Unladen Swallow конкурировали за файл с именем «mymodule.pyc», теперь они будут искать «mymodule.cpython-32.pyc», «mymodule.cpython-33.pyc» и «mymodule.unladen10.pyc». А чтобы все эти новые файлы не засоряли исходные каталоги, файлы *pyc* теперь собираются в каталог «\_\_pycache\_\_», расположенный внутри каталога пакета.207208Помимо имён файлов и целевых каталогов, новая схема имеет несколько аспектов, видимых программисту:209210- Импортированные модули теперь имеют атрибут [`__cached__`](https://python-all.ru/3.10/reference/import.html#cached__), хранящий имя файла, который был импортирован:211212 ```python213 >>> import collections214 >>> collections.__cached__ 215 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'216 ```217- Уникальный для каждого интерпретатора тег доступен из модуля [`imp`](https://python-all.ru/3.10/library/imp.html#module-imp):218219 ```python220 >>> import imp221 >>> imp.get_tag() 222 'cpython-32'223 ```224- Скрипты, пытающиеся определить имя исходного файла по импортированному файлу, теперь должны быть умнее. Просто удалить букву «c» из имени файла «.pyc» уже недостаточно. Вместо этого используйте новые функции из модуля [`imp`](https://python-all.ru/3.10/library/imp.html#module-imp):225226 ```python227 >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')228 'c:/py32/lib/collections.py'229 >>> imp.cache_from_source('c:/py32/lib/collections.py') 230 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'231 ```232- Модули [`py_compile`](https://python-all.ru/3.10/library/py_compile.html#module-py_compile) и [`compileall`](https://python-all.ru/3.10/library/compileall.html#module-compileall) были обновлены, чтобы отразить новое соглашение об именовании и целевой каталог. Вызов из командной строки *compileall* получил новые опции: `-i` для указания списка файлов и каталогов для компиляции и `-b`, которая заставляет записывать файлы байт-кода в их прежнее расположение, а не в *\_\_pycache\_\_*.233- Модуль [`importlib.abc`](https://python-all.ru/3.10/library/importlib.html#module-importlib.abc) обновлён новыми [абстрактными базовыми классами](https://python-all.ru/3.10/glossary.html#term-abstract-base-class) для загрузки файлов байт-кода. Устаревшие ABC, `PyLoader` и `PyPycLoader`, объявлены устаревшими (в документацию включены инструкции по сохранению совместимости с Python 3.1).234235> **См. также**236>237> **[**PEP 3147**](https://python-all.ru/3.10/whatsnew/3.2.html) – Директории репозитория PYC**238>239> PEP написан Барри Варшавой.240241## PEP 3149: .so-файлы с тегом версии ABI242243Директория репозитория PYC позволяет размещать несколько кэшированных файлов байт-кода в одном месте. Этот PEP реализует аналогичный механизм для разделяемых объектных файлов, помещая их в общую директорию с разными именами для каждой версии.244245Общая директория называется «pyshared», а имена файлов различаются указанием реализации Python (например, CPython, PyPy, Jython и т.д.), номерами старшей и младшей версии, а также необязательными флагами сборки (например, «d» для отладки, «m» для pymalloc, «u» для wide-unicode). Для произвольного пакета «foo» при установке дистрибутивного пакета можно увидеть такие файлы:246247```python248/usr/share/pyshared/foo.cpython-32m.so249/usr/share/pyshared/foo.cpython-33md.so250```251252В самом Python теги доступны через функции из модуля [`sysconfig`](https://python-all.ru/3.10/library/sysconfig.html#module-sysconfig):253254```python255>>> import sysconfig256>>> sysconfig.get_config_var('SOABI') # найти тег версии257'cpython-32mu'258>>> sysconfig.get_config_var('EXT_SUFFIX') # найти полное расширение имени файла259'.cpython-32mu.so'260```261262> **См. также**263>264> **[**PEP 3149**](https://python-all.ru/3.10/whatsnew/3.2.html) – файлы .so с тегами версии ABI**265>266> PEP написан Барри Варшавой.267268## PEP 3333: Python Web Server Gateway Interface v1.0.1269270Этот информационный PEP разъясняет, как в протоколе WSGI следует обрабатывать вопросы, связанные с байтами и текстом. Сложность в том, что в Python 3 со строками удобнее всего работать через тип [`str`](https://python-all.ru/3.10/library/stdtypes.html#str), хотя сам протокол HTTP ориентирован на байты.271272PEP различает так называемые *нативные строки*, используемые для заголовков и метаданных запросов/ответов, и *байтовые строки*, используемые для тел запросов и ответов.273274*Нативные строки* всегда имеют тип [`str`](https://python-all.ru/3.10/library/stdtypes.html#str), но ограничены кодовыми точками от *U+0000* до *U+00FF*, которые могут быть преобразованы в байты с использованием кодировки *Latin-1*. Эти строки используются для ключей и значений в словаре окружения, а также для заголовков и статусов ответов в функции `start_response()`. Они должны соответствовать [**RFC 2616**](https://python-all.ru/3.10/whatsnew/3.2.html) в отношении кодировки. То есть они должны быть либо символами *ISO-8859-1*, либо использовать кодировку MIME [**RFC 2047**](https://python-all.ru/3.10/whatsnew/3.2.html).275276Для разработчиков, переносящих WSGI-приложения с Python 2, вот ключевые моменты:277278- Если приложение уже использовало строки для заголовков в Python 2, никаких изменений не требуется.279- Если же приложение кодировало выходные заголовки или декодировало входные, то заголовки потребуется перекодировать в Latin-1. Например, выходной заголовок, закодированный в utf-8, использовал `h.encode('utf-8')`, теперь же необходимо преобразовать байты в нативные строки с помощью `h.encode('utf-8').decode('latin-1')`.280- Значения, возвращаемые приложением или отправляемые с помощью метода `write()`, должны быть байтовыми строками. Функция `start_response()` и environ должны использовать нативные строки. Их нельзя смешивать.281282Для разработчиков серверов, пишущих CGI-to-WSGI мосты или другие протоколы в стиле CGI, пользователи должны иметь возможность доступа к окружению через нативные строки, даже если базовая платформа использует другую конвенцию. Для преодоления этого разрыва в модуле [`wsgiref`](https://python-all.ru/3.10/library/wsgiref.html#module-wsgiref) появилась новая функция [`wsgiref.handlers.read_environ()`](https://python-all.ru/3.10/library/wsgiref.html#wsgiref.handlers.read_environ) для перекодирования CGI-переменных из [`os.environ`](https://python-all.ru/3.10/library/os.html#os.environ) в нативные строки и возврата нового словаря.283284> **См. также**285>286> **[**PEP 3333**](https://python-all.ru/3.10/whatsnew/3.2.html) – Python Web Server Gateway Interface v1.0.1**287>288> PEP написан Филлипом Иби.289290## Прочие изменения языка291292Некоторые небольшие изменения, внесённые в ядро языка Python:293294- Форматирование строк для [`format()`](https://python-all.ru/3.10/library/functions.html#format) и [`str.format()`](https://python-all.ru/3.10/library/stdtypes.html#str.format) получило новые возможности для символа формата **#**. Ранее для целых чисел в двоичной, восьмеричной или шестнадцатеричной системе он добавлял префикс «0b», «0o» или «0x» соответственно. Теперь он также может обрабатывать числа с плавающей точкой, комплексные числа и Decimal, при этом вывод всегда содержит десятичную точку, даже если после неё нет цифр.295296 ```python297 >>> format(20, '#o')298 '0o24'299 >>> format(12.34, '#5.0f')300 ' 12.'301 ```302303 (Предложено Марком Дикинсоном и реализовано Эриком Смитом в [bpo-7094](https://python-all.ru/3.10/whatsnew/3.2.html).)304- Также появился новый метод [`str.format_map()`](https://python-all.ru/3.10/library/stdtypes.html#str.format_map), расширяющий возможности существующего метода [`str.format()`](https://python-all.ru/3.10/library/stdtypes.html#str.format) за счёт приёма произвольных [объектов-отображений](https://python-all.ru/3.10/glossary.html#term-mapping). Этот новый метод позволяет использовать форматирование строк с любыми словареподобными объектами Python, такими как [`defaultdict`](https://python-all.ru/3.10/library/collections.html#collections.defaultdict), [`Shelf`](https://python-all.ru/3.10/library/shelve.html#shelve.Shelf), [`ConfigParser`](https://python-all.ru/3.10/library/configparser.html#configparser.ConfigParser) или [`dbm`](https://python-all.ru/3.10/library/dbm.html#module-dbm). Он также полезен с пользовательскими подклассами [`dict`](https://python-all.ru/3.10/library/stdtypes.html#dict), которые нормализуют ключи перед поиском или предоставляют метод `__missing__()` для неизвестных ключей:305306 ```python307 >>> import shelve308 >>> d = shelve.open('tmp.shl')309 >>> 'The {project_name} status is {status} as of {date}'.format_map(d)310 'The testing project status is green as of February 15, 2011'311312 >>> class LowerCasedDict(dict):313 ... def __getitem__(self, key):314 ... return dict.__getitem__(self, key.lower())315 >>> lcd = LowerCasedDict(part='widgets', quantity=10)316 >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd)317 'There are 10 widgets in stock'318319 >>> class PlaceholderDict(dict):320 ... def __missing__(self, key):321 ... return '<{}>'.format(key)322 >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict())323 'Hello <name>, welcome to <location>'324 ```325326> (Предложено Рэймондом Хеттингером и реализовано Эриком Смитом в [bpo-6081](https://python-all.ru/3.10/whatsnew/3.2.html).)327328- Интерпретатор теперь можно запускать с тихим режимом, опцией `-q`, чтобы предотвратить отображение информации об авторских правах и версии в интерактивном режиме. Состояние опции можно проверить через атрибут [`sys.flags`](https://python-all.ru/3.10/library/sys.html#sys.flags):329330 ```console331 $ python -q332 >>> sys.flags333 sys.flags(debug=0, division_warning=0, inspect=0, interactive=0,334 optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0,335 ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)336 ```337338 (Предложено Марчином Войдыром в [bpo-1772833](https://python-all.ru/3.10/whatsnew/3.2.html)).339- Функция [`hasattr()`](https://python-all.ru/3.10/library/functions.html#hasattr) работает, вызывая [`getattr()`](https://python-all.ru/3.10/library/functions.html#getattr) и определяя, было ли возбуждено исключение. Эта техника позволяет ей обнаруживать методы, созданные динамически с помощью `__getattr__()` или `__getattribute__()`, которые иначе отсутствовали бы в словаре класса. Раньше *hasattr* перехватывал любые исключения, что могло маскировать настоящие ошибки. Теперь *hasattr* был ужесточён и перехватывает только [`AttributeError`](https://python-all.ru/3.10/library/exceptions.html#AttributeError), пропуская другие исключения:340341 ```python342 >>> class A:343 ... @property344 ... def f(self):345 ... return 1 // 0346 ...347 >>> a = A()348 >>> hasattr(a, 'f')349 Traceback (most recent call last):350 ...351 ZeroDivisionError: integer division or modulo by zero352 ```353354 (Обнаружено Юрием Селивановым и исправлено Бенджамином Петерсоном; [bpo-9666](https://python-all.ru/3.10/whatsnew/3.2.html).)355- [`str()`](https://python-all.ru/3.10/library/stdtypes.html#str) числа с плавающей точкой или комплексного числа теперь совпадает с его [`repr()`](https://python-all.ru/3.10/library/functions.html#repr). Ранее форма [`str()`](https://python-all.ru/3.10/library/stdtypes.html#str) была короче, но это лишь вызывало путаницу, и теперь в ней больше нет необходимости, поскольку по умолчанию отображается самая короткая возможная [`repr()`](https://python-all.ru/3.10/library/functions.html#repr):356357 ```python358 >>> import math359 >>> repr(math.pi)360 '3.141592653589793'361 >>> str(math.pi)362 '3.141592653589793'363 ```364365 (Предложено и реализовано Марком Дикинсоном; [bpo-9337](https://python-all.ru/3.10/whatsnew/3.2.html).)366- Объекты [`memoryview`](https://python-all.ru/3.10/library/stdtypes.html#memoryview) теперь имеют метод [`release()`](https://python-all.ru/3.10/library/stdtypes.html#memoryview.release), а также поддерживают протокол менеджера контекста. Это позволяет своевременно освобождать любые ресурсы, которые были получены при запросе буфера от исходного объекта.367368 ```python369 >>> with memoryview(b'abcdefgh') as v:370 ... print(v.tolist())371 [97, 98, 99, 100, 101, 102, 103, 104]372 ```373374 (Добавлено Антуаном Питру; [bpo-9757](https://python-all.ru/3.10/whatsnew/3.2.html).)375- Ранее было запрещено удалять имя из локального пространства имён, если оно встречается как свободная переменная во вложенном блоке:376377 ```python378 def outer(x):379 def inner():380 return x381 inner()382 del x383 ```384385 Теперь это разрешено. Помните, что цель (target) в предложении [`except`](https://python-all.ru/3.10/reference/compound_stmts.html#except) очищается, поэтому этот код, который работал в Python 2.6, вызывал [`SyntaxError`](https://python-all.ru/3.10/library/exceptions.html#SyntaxError) в Python 3.1, а теперь снова работает:386387 ```python388 def f():389 def print_error():390 print(e)391 try:392 something393 except Exception as e:394 print_error()395 # неявное "del e" здесь396 ```397398 (См. [bpo-4617](https://python-all.ru/3.10/whatsnew/3.2.html).)399- Внутренний инструмент `structsequence` теперь создаёт подклассы tuple. Это означает, что структуры C, такие как возвращаемые [`os.stat()`](https://python-all.ru/3.10/library/os.html#os.stat), [`time.gmtime()`](https://python-all.ru/3.10/library/time.html#time.gmtime) и [`sys.version_info`](https://python-all.ru/3.10/library/sys.html#sys.version_info), теперь работают как [именованный кортеж](https://python-all.ru/3.10/glossary.html#term-named-tuple) и работают с функциями и методами, ожидающими tuple в качестве аргумента. Это большой шаг вперёд в обеспечении гибкости структур C, сравнимой с их аналогами на чистом Python:400401 ```python402 >>> import sys403 >>> isinstance(sys.version_info, tuple)404 True405 >>> 'Version %d.%d.%d %s(%d)' % sys.version_info 406 'Version 3.2.0 final(0)'407 ```408409 (Предложено Arfrever Frehtes Taifersar Arahesis и реализовано Benjamin Peterson в [bpo-8413](https://python-all.ru/3.10/whatsnew/3.2.html).)410- Теперь предупреждениями проще управлять с помощью переменной окружения [`PYTHONWARNINGS`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONWARNINGS) в качестве альтернативы использованию `-W` в командной строке:411412 ```console413 $ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'414 ```415416 (Предложено Barry Warsaw и реализовано Philip Jenvey в [bpo-7301](https://python-all.ru/3.10/whatsnew/3.2.html).)417- Добавлена новая категория предупреждений [`ResourceWarning`](https://python-all.ru/3.10/library/exceptions.html#ResourceWarning). Она выдаётся при обнаружении потенциальных проблем с потреблением ресурсов или очисткой. По умолчанию она отключена в обычных сборках, но её можно включить средствами модуля [`warnings`](https://python-all.ru/3.10/library/warnings.html#module-warnings) или в командной строке.418419 При завершении интерпретатора выдаётся [`ResourceWarning`](https://python-all.ru/3.10/library/exceptions.html#ResourceWarning), если список [`gc.garbage`](https://python-all.ru/3.10/library/gc.html#gc.garbage) не пуст, и если установлен [`gc.DEBUG_UNCOLLECTABLE`](https://python-all.ru/3.10/library/gc.html#gc.DEBUG_UNCOLLECTABLE), то печатаются все несобираемые объекты. Это сделано для того, чтобы программист знал, что его код содержит проблемы с финализацией объектов.420421 [`ResourceWarning`](https://python-all.ru/3.10/library/exceptions.html#ResourceWarning) также выдаётся, когда [объект файла](https://python-all.ru/3.10/glossary.html#term-file-object) уничтожается без явного закрытия. Хотя деаллокатор такого объекта гарантирует закрытие нижележащего ресурса операционной системы (обычно файлового дескриптора), задержка с деаллокацией объекта может вызывать различные проблемы, особенно в Windows. Вот пример включения предупреждения из командной строки:422423 ```console424 $ python -q -Wdefault425 >>> f = open("foo", "wb")426 >>> del f427 __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>428 ```429430 (Добавлено Antoine Pitrou и Georg Brandl в [bpo-10093](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-477863](https://python-all.ru/3.10/whatsnew/3.2.html).)431- Объекты [`range`](https://python-all.ru/3.10/library/stdtypes.html#range) теперь поддерживают методы *index* и *count*. Это часть усилий по расширению реализации `collections.Sequence` [абстрактного базового класса](https://python-all.ru/3.10/glossary.html#term-abstract-base-class) на большее количество объектов. В результате язык получит более единообразный API. Кроме того, объекты [`range`](https://python-all.ru/3.10/library/stdtypes.html#range) теперь поддерживают срезы и отрицательные индексы, даже со значениями, превышающими [`sys.maxsize`](https://python-all.ru/3.10/library/sys.html#sys.maxsize). Это делает *range* более совместимым со списками:432433 ```python434 >>> range(0, 100, 2).count(10)435 1436 >>> range(0, 100, 2).index(10)437 5438 >>> range(0, 100, 2)[5]439 10440 >>> range(0, 100, 2)[0:5]441 range(0, 10, 2)442 ```443444 (Вклад Daniel Stutzbach в [bpo-9213](https://python-all.ru/3.10/whatsnew/3.2.html), Alexander Belopolsky в [bpo-2690](https://python-all.ru/3.10/whatsnew/3.2.html) и Nick Coghlan в [bpo-10889](https://python-all.ru/3.10/whatsnew/3.2.html).)445- Встроенная функция [`callable()`](https://python-all.ru/3.10/library/functions.html#callable) из Py2.x была восстановлена. Она предоставляет краткую и читаемую альтернативу использованию [абстрактного базового класса](https://python-all.ru/3.10/glossary.html#term-abstract-base-class) в выражении вида `isinstance(x, collections.Callable)`:446447 ```python448 >>> callable(max)449 True450 >>> callable(20)451 False452 ```453454 (См. [bpo-10518](https://python-all.ru/3.10/whatsnew/3.2.html).)455- Механизм импорта Python теперь может загружать модули, установленные в каталогах, в именах путей которых есть не-ASCII символы. Это решило давнюю проблему с домашними каталогами пользователей, имеющих не-ASCII символы в именах.456457> (Потребовало значительной работы от Victor Stinner в [bpo-9425](https://python-all.ru/3.10/whatsnew/3.2.html).)458459## Новые, улучшенные и устаревшие модули460461Стандартная библиотека Python прошла значительную работу по сопровождению и улучшению качества.462463Самая важная новость для Python 3.2: пакет [`email`](https://python-all.ru/3.10/library/email.html#module-email), модуль [`mailbox`](https://python-all.ru/3.10/library/mailbox.html#module-mailbox) и модули [`nntplib`](https://python-all.ru/3.10/library/nntplib.html#module-nntplib) теперь корректно работают с моделью байты/текст в Python 3. Впервые правильно обрабатываются сообщения со смешанными кодировками.464465По всей стандартной библиотеке уделено больше внимания вопросам кодировок и различиям между текстом и байтами. В частности, взаимодействие с операционной системой теперь лучше обменивается не-ASCII данными, используя кодировку Windows MBCS, локаль-зависимые кодировки или UTF-8.466467Ещё одно важное достижение – добавление значительно улучшенной поддержки *SSL*-соединений и сертификатов безопасности.468469Кроме того, больше классов теперь реализуют [менеджер контекста](https://python-all.ru/3.10/glossary.html#term-context-manager) для удобной и надёжной очистки ресурсов с помощью оператора [`with`](https://python-all.ru/3.10/reference/compound_stmts.html#with).470471### email472473Пригодность к использованию пакета [`email`](https://python-all.ru/3.10/library/email.html#module-email) в Python 3 в значительной степени исправлена благодаря масштабной работе R. David Murray. Проблема заключалась в том, что электронные письма обычно читаются и хранятся в виде [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes), а не [`str`](https://python-all.ru/3.10/library/stdtypes.html#str) текста, и могут содержать несколько кодировок в одном письме. Поэтому пакет email пришлось расширить, чтобы разбирать и создавать сообщения в формате байтов.474475- Новые функции [`message_from_bytes()`](https://python-all.ru/3.10/library/email.parser.html#email.message_from_bytes) и [`message_from_binary_file()`](https://python-all.ru/3.10/library/email.parser.html#email.message_from_binary_file), а также новые классы [`BytesFeedParser`](https://python-all.ru/3.10/library/email.parser.html#email.parser.BytesFeedParser) и [`BytesParser`](https://python-all.ru/3.10/library/email.parser.html#email.parser.BytesParser) позволяют разбирать двоичные данные сообщений в объекты модели.476- Если на вход модели подаются байты, [`get_payload()`](https://python-all.ru/3.10/library/email.compat32-message.html#email.message.Message.get_payload) по умолчанию декодирует тело сообщения с *Content-Transfer-Encoding*, равным *8bit*, используя кодировку, указанную в MIME-заголовках, и возвращает результирующую строку.477- Если на вход модели подаются байты, [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator) преобразует тела сообщений, имеющие *Content-Transfer-Encoding* со значением *8bit*, в тела с *7bit* *Content-Transfer-Encoding*.478479 Заголовки с незакодированными не-ASCII байтами считаются закодированными по [**RFC 2047**](https://python-all.ru/3.10/whatsnew/3.2.html) с использованием набора символов *unknown-8bit*.480- Новый класс [`BytesGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator) выводит байты, сохраняя любые неизменённые не-ASCII данные, которые присутствовали во входных данных, использованных для построения модели, включая тела сообщений с *Content-Transfer-Encoding* равным *8bit*.481- Класс [`smtplib`](https://python-all.ru/3.10/library/smtplib.html#module-smtplib) [`SMTP`](https://python-all.ru/3.10/library/smtplib.html#smtplib.SMTP) теперь принимает байтовую строку для аргумента *msg* метода [`sendmail()`](https://python-all.ru/3.10/library/smtplib.html#smtplib.SMTP.sendmail), а новый метод [`send_message()`](https://python-all.ru/3.10/library/smtplib.html#smtplib.SMTP.send_message) принимает объект [`Message`](https://python-all.ru/3.10/library/email.compat32-message.html#email.message.Message) и может опционально получать адреса *from\_addr* и *to\_addrs* непосредственно из объекта.482483(Предложено и реализовано R. David Murray, [bpo-4661](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-10321](https://python-all.ru/3.10/whatsnew/3.2.html).)484485### elementtree486487Пакет [`xml.etree.ElementTree`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) и его аналог `xml.etree.cElementTree` обновлены до версии 1.3.488489Добавлено несколько новых полезных функций и методов:490491- [`xml.etree.ElementTree.fromstringlist()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.fromstringlist) – строит XML-документ из последовательности фрагментов492- [`xml.etree.ElementTree.register_namespace()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.register_namespace) – для регистрации глобального префикса пространства имён493- [`xml.etree.ElementTree.tostringlist()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.tostringlist) для строкового представления, включая все подсписки494- [`xml.etree.ElementTree.Element.extend()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.extend) для добавления последовательности из нуля или более элементов495- [`xml.etree.ElementTree.Element.iterfind()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.iterfind) ищет элемент и подэлементы496- [`xml.etree.ElementTree.Element.itertext()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.itertext) создаёт текстовый итератор по элементу и его подэлементам497- [`xml.etree.ElementTree.TreeBuilder.end()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder.end) закрывает текущий элемент498- [`xml.etree.ElementTree.TreeBuilder.doctype()`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder.doctype) обрабатывает объявление doctype499500Два метода устарели:501502- `xml.etree.ElementTree.getchildren()` используйте `list(elem)`.503- `xml.etree.ElementTree.getiterator()` используйте `Element.iter`.504505Подробнее об обновлении см. [Introducing ElementTree](https://python-all.ru/3.10/whatsnew/3.2.html) на сайте Фредрика Лунда.506507(Авторы: Florent Xicluna и Fredrik Lundh, [bpo-6472](https://python-all.ru/3.10/whatsnew/3.2.html).)508509### functools510511- Модуль [`functools`](https://python-all.ru/3.10/library/functools.html#module-functools) включает новый декоратор для кеширования вызовов функций. [`functools.lru_cache()`](https://python-all.ru/3.10/library/functools.html#functools.lru_cache) позволяет избежать повторных запросов к внешнему ресурсу, когда результаты предположительно одинаковы.512513 Например, добавление декоратора кеширования к функции запроса к базе данных может сократить количество обращений к базе данных для популярных поисковых запросов:514515 ```python516 >>> import functools517 >>> @functools.lru_cache(maxsize=300)518 ... def get_phone_number(name):519 ... c = conn.cursor()520 ... c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))521 ... return c.fetchone()[0]522 ```523524 ```python525 >>> for name in user_requests: 526 ... get_phone_number(name) # кэшированный поиск527 ```528529 Чтобы помочь с выбором эффективного размера кеша, обёрнутая функция оснащается средствами отслеживания статистики кеша:530531 ```python532 >>> get_phone_number.cache_info() 533 CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)534 ```535536 Если таблица phonelist обновляется, устаревшее содержимое кеша можно очистить с помощью:537538 ```python539 >>> get_phone_number.cache_clear()540 ```541542 (Автор: Raymond Hettinger с использованием идей дизайна от Jim Baker, Miki Tebeka и Nick Coghlan; см. [recipe 498245](https://python-all.ru/3.10/whatsnew/3.2.html), [recipe 577479](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-10586](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-10593](https://python-all.ru/3.10/whatsnew/3.2.html).)543- Декоратор [`functools.wraps()`](https://python-all.ru/3.10/library/functools.html#functools.wraps) теперь добавляет атрибут `__wrapped__`, указывающий на исходную вызываемую функцию. Это позволяет проводить интроспекцию обёрнутых функций. Он также копирует `__annotations__`, если тот определён. Кроме того, он корректно пропускает отсутствующие атрибуты, такие как `__doc__`, которые могут быть не определены для обёрнутой вызываемой функции.544545 В приведённом выше примере кеш можно удалить, восстановив исходную функцию:546547 ```python548 >>> get_phone_number = get_phone_number.__wrapped__ # некэшированная функция549 ```550551 (Авторы: Nick Coghlan и Terrence Cole; [bpo-9567](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-3445](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-8814](https://python-all.ru/3.10/whatsnew/3.2.html).)552- Чтобы упростить написание классов с методами полного сравнения, новый декоратор [`functools.total_ordering()`](https://python-all.ru/3.10/library/functools.html#functools.total_ordering) будет использовать существующие методы равенства и неравенства для заполнения остальных методов.553554 Например, указав *\_\_eq\_\_* и *\_\_lt\_\_*, можно позволить [`total_ordering()`](https://python-all.ru/3.10/library/functools.html#functools.total_ordering) заполнить *\_\_le\_\_*, *\_\_gt\_\_* и *\_\_ge\_\_*:555556 ```python557 @total_ordering558 class Student:559 def __eq__(self, other):560 return ((self.lastname.lower(), self.firstname.lower()) ==561 (other.lastname.lower(), other.firstname.lower()))562563 def __lt__(self, other):564 return ((self.lastname.lower(), self.firstname.lower()) <565 (other.lastname.lower(), other.firstname.lower()))566 ```567568 С помощью декоратора *total\_ordering* остальные методы сравнения заполняются автоматически.569570 (Автор: Raymond Hettinger.)571- Чтобы облегчить перенос программ с Python 2, функция [`functools.cmp_to_key()`](https://python-all.ru/3.10/library/functools.html#functools.cmp_to_key) преобразует устаревшую функцию сравнения в современную [функцию ключа](https://python-all.ru/3.10/glossary.html#term-key-function):572573 ```python574 >>> # порядок сортировки с учётом локали575 >>> sorted(iterable, key=cmp_to_key(locale.strcoll)) 576 ```577578 Примеры сортировки и краткое руководство по сортировке см. в руководстве [Sorting HowTo](https://python-all.ru/3.10/whatsnew/3.2.html).579580 (Автор: Raymond Hettinger.)581582### itertools583584- Модуль [`itertools`](https://python-all.ru/3.10/library/itertools.html#module-itertools) содержит новую функцию [`accumulate()`](https://python-all.ru/3.10/library/itertools.html#itertools.accumulate), созданную по образцу оператора *scan* из APL и функции *accumulate* из Numpy:585586 ```python587 >>> from itertools import accumulate588 >>> list(accumulate([8, 2, 50]))589 [8, 10, 60]590 ```591592 ```python593 >>> prob_dist = [0.1, 0.4, 0.2, 0.3]594 >>> list(accumulate(prob_dist)) # кумулятивное распределение вероятностей595 [0.1, 0.5, 0.7, 1.0]596 ```597598 Пример использования [`accumulate()`](https://python-all.ru/3.10/library/itertools.html#itertools.accumulate) см. в [примерах для модуля random](https://python-all.ru/3.10/library/random.html#random-examples).599600 (Автор: Raymond Hettinger с учётом предложений по дизайну от Mark Dickinson.)601602### collections603604- Класс [`collections.Counter`](https://python-all.ru/3.10/library/collections.html#collections.Counter) теперь имеет две формы вычитания на месте: существующий оператор *-=* для [насыщающего вычитания](https://python-all.ru/3.10/whatsnew/3.2.html) и новый метод [`subtract()`](https://python-all.ru/3.10/library/collections.html#collections.Counter.subtract) для обычного вычитания. Первый подходит для [мультимножеств](https://python-all.ru/3.10/whatsnew/3.2.html), которые имеют только положительные счётчики, а второй больше подходит для случаев, допускающих отрицательные счётчики:605606 ```python607 >>> from collections import Counter608 >>> tally = Counter(dogs=5, cats=3)609 >>> tally -= Counter(dogs=2, cats=8) # насыщающее вычитание610 >>> tally611 Counter({'dogs': 3})612 ```613614 ```python615 >>> tally = Counter(dogs=5, cats=3)616 >>> tally.subtract(dogs=2, cats=8) # обычное вычитание617 >>> tally618 Counter({'dogs': 3, 'cats': -5})619 ```620621 (Автор: Raymond Hettinger.)622- Класс [`collections.OrderedDict`](https://python-all.ru/3.10/library/collections.html#collections.OrderedDict) имеет новый метод [`move_to_end()`](https://python-all.ru/3.10/library/collections.html#collections.OrderedDict.move_to_end), который принимает существующий ключ и перемещает его либо в первую, либо в последнюю позицию упорядоченной последовательности.623624 По умолчанию элемент перемещается на последнюю позицию. Это эквивалентно обновлению записи с помощью `od[k] = od.pop(k)`.625626 Быстрая операция перемещения в конец полезна для изменения порядка следования записей. Например, упорядоченный словарь можно использовать для отслеживания порядка доступа, упорядочивая записи от самых старых к самым недавно запрошенным.627628 ```python629 >>> from collections import OrderedDict630 >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e'])631 >>> list(d)632 ['a', 'b', 'X', 'd', 'e']633 >>> d.move_to_end('X')634 >>> list(d)635 ['a', 'b', 'd', 'e', 'X']636 ```637638 (Автор: Raymond Hettinger.)639- У класса [`collections.deque`](https://python-all.ru/3.10/library/collections.html#collections.deque) появилось два новых метода – [`count()`](https://python-all.ru/3.10/library/collections.html#collections.deque.count) и [`reverse()`](https://python-all.ru/3.10/library/collections.html#collections.deque.reverse), которые делают его более взаимозаменяемым с объектами [`list`](https://python-all.ru/3.10/library/stdtypes.html#list):640641 ```python642 >>> from collections import deque643 >>> d = deque('simsalabim')644 >>> d.count('s')645 2646 >>> d.reverse()647 >>> d648 deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])649 ```650651 (Автор: Raymond Hettinger.)652653### threading654655В модуле [`threading`](https://python-all.ru/3.10/library/threading.html#module-threading) появился новый класс синхронизации [`Barrier`](https://python-all.ru/3.10/library/threading.html#threading.Barrier), который заставляет несколько потоков ждать, пока все они не достигнут общей точки барьера. Барьеры полезны для обеспечения того, чтобы задача с несколькими предусловиями не выполнялась до завершения всех предшествующих задач.656657Барьеры могут работать с произвольным числом потоков. Это обобщение механизма [рандеву](https://python-all.ru/3.10/whatsnew/3.2.html), который определён только для двух потоков.658659Реализованный как двухфазный циклический барьер, объект [`Barrier`](https://python-all.ru/3.10/library/threading.html#threading.Barrier) подходит для использования в циклах. Отдельные фазы *заполнения* и *опустошения* гарантируют, что все потоки будут освобождены (опустошены) прежде, чем какой-либо из них сможет вернуться назад и снова войти в барьер. Барьер полностью сбрасывается после каждого цикла.660661Пример использования барьеров:662663```python664from threading import Barrier, Thread665666def get_votes(site):667 ballots = conduct_election(site)668 all_polls_closed.wait() # не подсчитывать, пока все голосования не закрыты669 totals = summarize(ballots)670 publish(site, totals)671672all_polls_closed = Barrier(len(sites))673for site in sites:674 Thread(target=get_votes, args=(site,)).start()675```676677В этом примере барьер обеспечивает соблюдение правила, согласно которому голоса не могут быть подсчитаны на любом избирательном участке, пока все участки не закроются. Обратите внимание, что решение с барьером похоже на решение с [`threading.Thread.join()`](https://python-all.ru/3.10/library/threading.html#threading.Thread.join), но после пересечения точки барьера потоки остаются живыми и продолжают работать (подсчитывать бюллетени).678679Если какая-либо из предшествующих задач может зависнуть или задержаться, барьер можно создать с необязательным параметром *тайм-аут*. Тогда, если период ожидания истекает до того, как все предшествующие задачи достигнут точки барьера, все ожидающие потоки освобождаются и возбуждается исключение [`BrokenBarrierError`](https://python-all.ru/3.10/library/threading.html#threading.BrokenBarrierError):680681```python682def get_votes(site):683 ballots = conduct_election(site)684 try:685 all_polls_closed.wait(timeout=midnight - time.now())686 except BrokenBarrierError:687 lockbox = seal_ballots(ballots)688 queue.put(lockbox)689 else:690 totals = summarize(ballots)691 publish(site, totals)692```693694В этом примере барьер обеспечивает более надежное правило. Если некоторые избирательные участки не заканчивают работу до полуночи, барьер срабатывает по тайм-ауту, и бюллетени опечатываются и помещаются в очередь для последующей обработки.695696Смотрите [Barrier Synchronization Patterns](https://python-all.ru/3.10/whatsnew/3.2.html) для получения дополнительных примеров использования барьеров в параллельных вычислениях. Также простое, но подробное объяснение барьеров даётся в [The Little Book of Semaphores](https://python-all.ru/3.10/whatsnew/3.2.html), *раздел 3.6*.697698(Автор: Kristján Valur Jónsson, рецензирование API: Jeffrey Yasskin, в [bpo-8777](https://python-all.ru/3.10/whatsnew/3.2.html).)699700### datetime and time701702- В модуле [`datetime`](https://python-all.ru/3.10/library/datetime.html#module-datetime) появился новый тип [`timezone`](https://python-all.ru/3.10/library/datetime.html#datetime.timezone), который реализует интерфейс [`tzinfo`](https://python-all.ru/3.10/library/datetime.html#datetime.tzinfo), возвращая фиксированное смещение UTC и название часового пояса. Это упрощает создание объектов datetime с учётом часового пояса:703704 ```python705 >>> from datetime import datetime, timezone706707 >>> datetime.now(timezone.utc)708 datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)709710 >>> datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")711 datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)712 ```713- Кроме того, объекты [`timedelta`](https://python-all.ru/3.10/library/datetime.html#datetime.timedelta) теперь можно умножать на [`float`](https://python-all.ru/3.10/library/functions.html#float) и делить на [`float`](https://python-all.ru/3.10/library/functions.html#float) и [`int`](https://python-all.ru/3.10/library/functions.html#int). А объекты [`timedelta`](https://python-all.ru/3.10/library/datetime.html#datetime.timedelta) теперь можно делить друг на друга.714- Метод [`datetime.date.strftime()`](https://python-all.ru/3.10/library/datetime.html#datetime.date.strftime) больше не ограничен годами после 1900. Новый поддерживаемый диапазон лет – от 1000 до 9999 включительно.715- Всякий раз, когда в кортеже времени используется двузначный год, его интерпретация определяется `time.accept2dyear`. По умолчанию используется `True`, что означает, что для двузначного года век определяется по правилам POSIX, регламентирующим формат `%y` strptime.716717 Начиная с Py3.2, использование эвристики угадывания века будет вызывать предупреждение [`DeprecationWarning`](https://python-all.ru/3.10/library/exceptions.html#DeprecationWarning). Вместо этого рекомендуется установить `time.accept2dyear` в `False`, чтобы можно было использовать большие диапазоны дат без угадывания:718719 ```python720 >>> import time, warnings721 >>> warnings.resetwarnings() # удалить фильтры предупреждений по умолчанию722723 >>> time.accept2dyear = True # угадать, означает ли 11 число 11 или 2011724 >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))725 Warning (from warnings module):726 ...727 DeprecationWarning: Century info guessed for a 2-digit year.728 'Fri Jan 1 12:34:56 2011'729730 >>> time.accept2dyear = False # использовать полный диапазон допустимых дат731 >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))732 'Fri Jan 1 12:34:56 11'733 ```734735 Несколько функций теперь имеют значительно расширенные диапазоны дат. Когда `time.accept2dyear` имеет значение false, функция [`time.asctime()`](https://python-all.ru/3.10/library/time.html#time.asctime) принимает любой год, помещающийся в int в C, а функции [`time.mktime()`](https://python-all.ru/3.10/library/time.html#time.mktime) и [`time.strftime()`](https://python-all.ru/3.10/library/time.html#time.strftime) принимают полный диапазон, поддерживаемый соответствующими функциями операционной системы.736737(Авторы: Alexander Belopolsky и Victor Stinner в [bpo-1289118](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-5094](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-6641](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-2706](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-1777412](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-8013](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-10827](https://python-all.ru/3.10/whatsnew/3.2.html).)738739### math740741Модуль [`math`](https://python-all.ru/3.10/library/math.html#module-math) обновлён и содержит шесть новых функций, вдохновлённых стандартом C99.742743Функция [`isfinite()`](https://python-all.ru/3.10/library/math.html#math.isfinite) предоставляет надёжный и быстрый способ обнаружения особых значений. Она возвращает `True` для обычных чисел и `False` для *NaN* или *бесконечность*:744745```python746>>> from math import isfinite747>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]748[True, True, False, False]749```750751Функция [`expm1()`](https://python-all.ru/3.10/library/math.html#math.expm1) вычисляет `e**x-1` для малых значений *x* без потери точности, которая обычно сопутствует вычитанию почти равных величин:752753```python754>>> from math import expm1755>>> expm1(0.013671875) # более точный способ вычисления e**x-1 для малых x7560.013765762467652909757```758759Функция [`erf()`](https://python-all.ru/3.10/library/math.html#math.erf) вычисляет интеграл вероятности или [функцию ошибок Гаусса](https://python-all.ru/3.10/whatsnew/3.2.html). Дополнительная функция ошибок, [`erfc()`](https://python-all.ru/3.10/library/math.html#math.erfc), равна `1 - erf(x)`:760761```pycon762>>> from math import erf, erfc, sqrt763>>> erf(1.0/sqrt(2.0)) # доля нормального распределения в пределах одного стандартного отклонения7640.682689492137086765>>> erfc(1.0/sqrt(2.0)) # доля нормального распределения за пределами одного стандартного отклонения7660.31731050786291404767>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))7681.0769```770771Функция [`gamma()`](https://python-all.ru/3.10/library/math.html#math.gamma) является непрерывным расширением функции факториала. Подробнее см. [https://en.wikipedia.org/wiki/Gamma\_function](https://python-all.ru/3.10/whatsnew/3.2.html). Поскольку эта функция связана с факториалами, она быстро растёт даже при малых значениях *x*, поэтому существует также функция [`lgamma()`](https://python-all.ru/3.10/library/math.html#math.lgamma) для вычисления натурального логарифма гамма-функции:772773```python774>>> from math import gamma, lgamma775>>> gamma(7.0) # шесть факториал776720.0777>>> lgamma(801.0) # логарифм факториала 8007784551.950730698041779```780781(Автор: Mark Dickinson.)782783### abc784785Модуль [`abc`](https://python-all.ru/3.10/library/abc.html#module-abc) теперь поддерживает [`abstractclassmethod()`](https://python-all.ru/3.10/library/abc.html#abc.abstractclassmethod) и [`abstractstaticmethod()`](https://python-all.ru/3.10/library/abc.html#abc.abstractstaticmethod).786787Эти инструменты позволяют определить [абстрактный базовый класс](https://python-all.ru/3.10/glossary.html#term-abstract-base-class), который требует реализации определённого [`classmethod()`](https://python-all.ru/3.10/library/functions.html#classmethod) или [`staticmethod()`](https://python-all.ru/3.10/library/functions.html#staticmethod):788789```python790class Temperature(metaclass=abc.ABCMeta):791 @abc.abstractclassmethod792 def from_fahrenheit(cls, t):793 ...794 @abc.abstractclassmethod795 def from_celsius(cls, t):796 ...797```798799(Патч предоставлен Daniel Urban; [bpo-5867](https://python-all.ru/3.10/whatsnew/3.2.html).)800801### io802803У [`io.BytesIO`](https://python-all.ru/3.10/library/io.html#io.BytesIO) появился новый метод [`getbuffer()`](https://python-all.ru/3.10/library/io.html#io.BytesIO.getbuffer), функциональность которого похожа на [`memoryview()`](https://python-all.ru/3.10/library/stdtypes.html#memoryview). Он создаёт редактируемое представление данных без копирования. Произвольный доступ и поддержка срезов в буфере хорошо подходят для редактирования на месте:804805```python806>>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11807808>>> def change_location(buffer, record_number, location):809... start = record_number * REC_LEN + LOC_START810... buffer[start: start+LOC_LEN] = location811812>>> import io813814>>> byte_stream = io.BytesIO(815... b'G3805 storeroom Main chassis '816... b'X7899 shipping Reserve cog '817... b'L6988 receiving Primary sprocket'818... )819>>> buffer = byte_stream.getbuffer()820>>> change_location(buffer, 1, b'warehouse ')821>>> change_location(buffer, 0, b'showroom ')822>>> print(byte_stream.getvalue())823b'G3805 showroom Main chassis '824b'X7899 warehouse Reserve cog '825b'L6988 receiving Primary sprocket'826```827828(Предложено Антуаном Питру в [bpo-5506](https://python-all.ru/3.10/whatsnew/3.2.html).)829830### reprlib831832При написании метода `__repr__()` для пользовательского контейнера легко забыть обработать случай, когда элемент ссылается обратно на сам контейнер. Встроенные объекты Python, такие как [`list`](https://python-all.ru/3.10/library/stdtypes.html#list) и [`set`](https://python-all.ru/3.10/library/stdtypes.html#set), обрабатывают самоссылку, отображая «…» в рекурсивной части строки представления.833834Чтобы помочь в написании таких методов `__repr__()`, модуль [`reprlib`](https://python-all.ru/3.10/library/reprlib.html#module-reprlib) получил новый декоратор [`recursive_repr()`](https://python-all.ru/3.10/library/reprlib.html#reprlib.recursive_repr) для обнаружения рекурсивных вызовов `__repr__()` и подстановки вместо них строки-заполнителя:835836```python837>>> class MyList(list):838... @recursive_repr()839... def __repr__(self):840... return '<' + '|'.join(map(repr, self)) + '>'841...842>>> m = MyList('abc')843>>> m.append(m)844>>> m.append('x')845>>> print(m)846<'a'|'b'|'c'|...|'x'>847```848849(Предложено Рэймондом Хеттингером в [bpo-9826](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-9840](https://python-all.ru/3.10/whatsnew/3.2.html).)850851### logging852853В дополнение к конфигурации на основе словаря, описанной выше, пакет [`logging`](https://python-all.ru/3.10/library/logging.html#module-logging) содержит множество других улучшений.854855Документация по logging была дополнена [базовым руководством](https://python-all.ru/3.10/howto/logging.html#logging-basic-tutorial), [продвинутым руководством](https://python-all.ru/3.10/howto/logging.html#logging-advanced-tutorial) и [поваренной книгой](https://python-all.ru/3.10/howto/logging-cookbook.html#logging-cookbook) с рецептами логирования. Эти документы – самый быстрый способ изучить логирование.856857Функция настройки [`logging.basicConfig()`](https://python-all.ru/3.10/library/logging.html#logging.basicConfig) получила аргумент *style* для поддержки трёх различных типов форматирования строк. По умолчанию он равен «%» для традиционного форматирования через %, может быть установлен в «{» для нового стиля [`str.format()`](https://python-all.ru/3.10/library/stdtypes.html#str.format) или в «$» для форматирования в стиле оболочки, предоставляемого [`string.Template`](https://python-all.ru/3.10/library/string.html#string.Template). Следующие три конфигурации эквивалентны:858859```python860>>> from logging import basicConfig861>>> basicConfig(style='%', format="%(name)s -> %(levelname)s: %(message)s")862>>> basicConfig(style='{', format="{name} -> {levelname} {message}")863>>> basicConfig(style='$', format="$name -> $levelname: $message")864```865866Если до возникновения события логирования не настроена конфигурация, теперь используется конфигурация по умолчанию с [`StreamHandler`](https://python-all.ru/3.10/library/logging.handlers.html#logging.StreamHandler), направленным в [`sys.stderr`](https://python-all.ru/3.10/library/sys.html#sys.stderr) для событий уровня `WARNING` и выше. Ранее событие, произошедшее до настройки конфигурации, либо вызывало исключение, либо молча отбрасывалось в зависимости от значения `logging.raiseExceptions`. Новый обработчик по умолчанию хранится в [`logging.lastResort`](https://python-all.ru/3.10/library/logging.html#logging.lastResort).867868Использование фильтров упрощено. Вместо создания объекта [`Filter`](https://python-all.ru/3.10/library/logging.html#logging.Filter) предикатом может быть любой вызываемый объект Python, возвращающий `True` или `False`.869870Было сделано множество других улучшений, повышающих гибкость и упрощающих конфигурацию. Полный список изменений в Python 3.2 смотрите в документации модуля.871872### csv873874Модуль [`csv`](https://python-all.ru/3.10/library/csv.html#module-csv) теперь поддерживает новый диалект [`unix_dialect`](https://python-all.ru/3.10/library/csv.html#csv.unix_dialect), который применяет кавычки для всех полей и традиционный стиль Unix с `'\n'` в качестве завершителя строки. Зарегистрированное имя диалекта – `unix`.875876У [`csv.DictWriter`](https://python-all.ru/3.10/library/csv.html#csv.DictWriter) появился новый метод [`writeheader()`](https://python-all.ru/3.10/library/csv.html#csv.DictWriter.writeheader) для записи начальной строки с именами полей:877878```python879>>> import csv, sys880>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')881>>> w.writeheader()882"name","dept"883>>> w.writerows([884... {'name': 'tom', 'dept': 'accounting'},885... {'name': 'susan', 'dept': 'Salesl'}])886"tom","accounting"887"susan","sales"888```889890(Новый диалект предложен Джеем Талботом в [bpo-5975](https://python-all.ru/3.10/whatsnew/3.2.html), а новый метод предложен Эдом Абрахамом в [bpo-1537721](https://python-all.ru/3.10/whatsnew/3.2.html).)891892### contextlib893894Появился новый и слегка умопомрачительный инструмент [`ContextDecorator`](https://python-all.ru/3.10/library/contextlib.html#contextlib.ContextDecorator), полезный для создания [менеджера контекста](https://python-all.ru/3.10/glossary.html#term-context-manager), который выполняет двойную роль как декоратор функций.895896Для удобства эта новая функциональность используется [`contextmanager()`](https://python-all.ru/3.10/library/contextlib.html#contextlib.contextmanager), так что не требуется дополнительных усилий для поддержки обеих ролей.897898Основная идея в том, что и менеджеры контекста, и декораторы функций могут использоваться как обёртки для действий до и после. Менеджеры контекста оборачивают группу операторов с помощью оператора [`with`](https://python-all.ru/3.10/reference/compound_stmts.html#with), а декораторы функций оборачивают группу операторов, заключённых в функцию. Поэтому иногда возникает необходимость написать обёртку для предварительного или последующего действия, которую можно использовать в любой из этих ролей.899900Например, иногда полезно обернуть функции или группы операторов логгером, который может отслеживать время входа и время выхода. Вместо написания как декоратора функций, так и менеджера контекста для этой задачи, [`contextmanager()`](https://python-all.ru/3.10/library/contextlib.html#contextlib.contextmanager) предоставляет обе возможности в одном определении:901902```python903from contextlib import contextmanager904import logging905906logging.basicConfig(level=logging.INFO)907908@contextmanager909def track_entry_and_exit(name):910 logging.info('Entering: %s', name)911 yield912 logging.info('Exiting: %s', name)913```914915Ранее это можно было использовать только как менеджер контекста:916917```python918with track_entry_and_exit('widget loader'):919 print('Some time consuming activity goes here')920 load_widget()921```922923Теперь его можно использовать и как декоратор:924925```python926@track_entry_and_exit('widget loader')927def activity():928 print('Some time consuming activity goes here')929 load_widget()930```931932Попытка выполнять сразу две роли накладывает некоторые ограничения на технику. Менеджеры контекста обычно имеют возможность вернуть аргумент, который может использоваться оператором [`with`](https://python-all.ru/3.10/reference/compound_stmts.html#with), но для декораторов функции такой параллели нет.933934В приведённом выше примере нет чистого способа для менеджера контекста *track\_entry\_and\_exit* вернуть экземпляр логгера для использования в теле вложенных операторов.935936(Предложено Майклом Фордом в [bpo-9110](https://python-all.ru/3.10/whatsnew/3.2.html).)937938### decimal and fractions939940Марк Дикинсон разработал элегантную и эффективную схему, гарантирующую, что разные числовые типы данных будут иметь одинаковое хеш-значение, когда их фактические значения равны ([bpo-8188](https://python-all.ru/3.10/whatsnew/3.2.html)):941942```python943assert hash(Fraction(3, 2)) == hash(1.5) == \944 hash(Decimal("1.5")) == hash(complex(1.5, 0))945```946947Некоторые детали хеширования доступны через новый атрибут [`sys.hash_info`](https://python-all.ru/3.10/library/sys.html#sys.hash_info), который описывает разрядность хеш-значения, простой модуль, хеш-значения для *бесконечности* и *nan*, а также множитель, используемый для мнимой части числа:948949```python950>>> sys.hash_info 951sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)952```953954Ранее принятое решение ограничить совместимость различных числовых типов было смягчено. По-прежнему не поддерживается (и не рекомендуется) неявное смешивание в арифметических выражениях, таких как `Decimal('1.1') + float('1.1')`, поскольку оно теряет информацию в процессе построения двоичного числа с плавающей запятой. Однако, поскольку существующие значения с плавающей запятой можно без потерь преобразовать как в десятичное, так и в рациональное представление, имеет смысл добавить их в конструктор и поддерживать сравнения смешанных типов.955956- Конструктор [`decimal.Decimal`](https://python-all.ru/3.10/library/decimal.html#decimal.Decimal) теперь принимает объекты [`float`](https://python-all.ru/3.10/library/functions.html#float) напрямую, поэтому больше нет необходимости использовать метод [`from_float()`](https://python-all.ru/3.10/library/decimal.html#decimal.Decimal.from_float) ([bpo-8257](https://python-all.ru/3.10/whatsnew/3.2.html)).957- Сравнения смешанных типов теперь полностью поддерживаются, так что объекты [`Decimal`](https://python-all.ru/3.10/library/decimal.html#decimal.Decimal) можно напрямую сравнивать с [`float`](https://python-all.ru/3.10/library/functions.html#float) и [`fractions.Fraction`](https://python-all.ru/3.10/library/fractions.html#fractions.Fraction) ([bpo-2531](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-8188](https://python-all.ru/3.10/whatsnew/3.2.html)).958959Аналогичные изменения были внесены в [`fractions.Fraction`](https://python-all.ru/3.10/library/fractions.html#fractions.Fraction), так что методы [`from_float()`](https://python-all.ru/3.10/library/fractions.html#fractions.Fraction.from_float) и [`from_decimal()`](https://python-all.ru/3.10/library/fractions.html#fractions.Fraction.from_decimal) больше не нужны ([bpo-8294](https://python-all.ru/3.10/whatsnew/3.2.html)):960961```python962>>> from decimal import Decimal963>>> from fractions import Fraction964>>> Decimal(1.1)965Decimal('1.100000000000000088817841970012523233890533447265625')966>>> Fraction(1.1)967Fraction(2476979795053773, 2251799813685248)968```969970Ещё одно полезное изменение для модуля [`decimal`](https://python-all.ru/3.10/library/decimal.html#module-decimal) заключается в том, что атрибут `Context.clamp` теперь является публичным. Это полезно при создании контекстов, соответствующих десятичным форматам обмена, указанным в IEEE 754 (см. [bpo-8540](https://python-all.ru/3.10/whatsnew/3.2.html)).971972(Авторы: Mark Dickinson и Raymond Hettinger.)973974### ftp975976Класс [`ftplib.FTP`](https://python-all.ru/3.10/library/ftplib.html#ftplib.FTP) теперь поддерживает протокол управления контекстом для безусловного поглощения исключений [`socket.error`](https://python-all.ru/3.10/library/socket.html#socket.error) и закрытия FTP-соединения по завершении:977978```python979>>> from ftplib import FTP980>>> with FTP("ftp1.at.proftpd.org") as ftp:981 ftp.login()982 ftp.dir()983984'230 Anonymous login ok, restrictions apply.'985dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .986dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..987dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS988dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora989```990991Другие файлоподобные объекты, такие как [`mmap.mmap`](https://python-all.ru/3.10/library/mmap.html#mmap.mmap) и [`fileinput.input()`](https://python-all.ru/3.10/library/fileinput.html#fileinput.input), также получили автоматически закрываемые менеджеры контекста:992993```python994with fileinput.input(files=('log1.txt', 'log2.txt')) as f:995 for line in f:996 process(line)997```998999(Авторы: Tarek Ziadé и Giampaolo Rodolà в [bpo-4972](https://python-all.ru/3.10/whatsnew/3.2.html), и Georg Brandl в [bpo-8046](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-1286](https://python-all.ru/3.10/whatsnew/3.2.html).)10001001Класс [`FTP_TLS`](https://python-all.ru/3.10/library/ftplib.html#ftplib.FTP_TLS) теперь принимает параметр *context*, который является объектом [`ssl.SSLContext`](https://python-all.ru/3.10/library/ssl.html#ssl.SSLContext), позволяющим объединять параметры конфигурации SSL, сертификаты и закрытые ключи в единую (потенциально долгоживущую) структуру.10021003(Автор: Giampaolo Rodolà; [bpo-8806](https://python-all.ru/3.10/whatsnew/3.2.html).)10041005### popen10061007Функции [`os.popen()`](https://python-all.ru/3.10/library/os.html#os.popen) и [`subprocess.Popen()`](https://python-all.ru/3.10/library/subprocess.html#subprocess.Popen) теперь поддерживают операторы [`with`](https://python-all.ru/3.10/reference/compound_stmts.html#with) для автоматического закрытия файловых дескрипторов.10081009(Авторы: Antoine Pitrou и Brian Curtin в [bpo-7461](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-10554](https://python-all.ru/3.10/whatsnew/3.2.html).)10101011### select10121013Модуль [`select`](https://python-all.ru/3.10/library/select.html#module-select) теперь предоставляет новый константный атрибут, [`PIPE_BUF`](https://python-all.ru/3.10/library/select.html#select.PIPE_BUF), который указывает минимальное количество байтов, которые гарантированно не будут блокироваться, когда [`select.select()`](https://python-all.ru/3.10/library/select.html#select.select) сообщает, что канал готов к записи.10141015```python1016>>> import select1017>>> select.PIPE_BUF 10185121019```10201021(Доступно в системах Unix. Патч от Sébastien Sablé в [bpo-9862](https://python-all.ru/3.10/whatsnew/3.2.html))10221023### gzip и zipfile10241025[`gzip.GzipFile`](https://python-all.ru/3.10/library/gzip.html#gzip.GzipFile) теперь реализует [`io.BufferedIOBase`](https://python-all.ru/3.10/library/io.html#io.BufferedIOBase) [абстрактный базовый класс](https://python-all.ru/3.10/glossary.html#term-abstract-base-class) (за исключением `truncate()`). Он также имеет метод [`peek()`](https://python-all.ru/3.10/library/gzip.html#gzip.GzipFile.peek) и поддерживает непозиционируемые, а также дополненные нулями файловые объекты.10261027Модуль [`gzip`](https://python-all.ru/3.10/library/gzip.html#module-gzip) также получает функции [`compress()`](https://python-all.ru/3.10/library/gzip.html#gzip.compress) и [`decompress()`](https://python-all.ru/3.10/library/gzip.html#gzip.decompress) для более удобного сжатия и распаковки в памяти. Имейте в виду, что текст необходимо кодировать как [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) перед сжатием и распаковкой:10281029```python1030>>> import gzip1031>>> s = 'Three shall be the number thou shalt count, '1032>>> s += 'and the number of the counting shall be three'1033>>> b = s.encode() # преобразовать в utf-81034>>> len(b)1035891036>>> c = gzip.compress(b)1037>>> len(c)1038771039>>> gzip.decompress(c).decode()[:42] # распаковать и преобразовать в текст1040'Three shall be the number thou shalt count'1041```10421043(Авторы: Anand B. Pillai в [bpo-3488](https://python-all.ru/3.10/whatsnew/3.2.html); и Antoine Pitrou, Nir Aides и Brian Curtin в [bpo-9962](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-1675951](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-7471](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-2846](https://python-all.ru/3.10/whatsnew/3.2.html).)10441045Кроме того, класс `zipfile.ZipExtFile` был внутренне переработан для представления файлов, хранящихся внутри архива. Новая реализация значительно быстрее и может быть обёрнута в объект [`io.BufferedReader`](https://python-all.ru/3.10/library/io.html#io.BufferedReader) для дополнительного ускорения. Она также решает проблему, при которой чередующиеся вызовы *read* и *readline* давали неверные результаты.10461047(Патч предоставлен Nir Aides в [bpo-7610](https://python-all.ru/3.10/whatsnew/3.2.html).)10481049### tarfile10501051Класс [`TarFile`](https://python-all.ru/3.10/library/tarfile.html#tarfile.TarFile) теперь можно использовать как менеджер контекста. Кроме того, его метод [`add()`](https://python-all.ru/3.10/library/tarfile.html#tarfile.TarFile.add) получил новую опцию *filter*, которая управляет тем, какие файлы добавляются в архив, и позволяет редактировать метаданные файлов.10521053Новая опция *filter* заменяет старый, менее гибкий параметр *exclude*, который теперь устарел. Если указан, дополнительный параметр *filter* должен быть [именованным аргументом](https://python-all.ru/3.10/glossary.html#term-keyword-argument). Предоставленная пользователем функция фильтра принимает объект [`TarInfo`](https://python-all.ru/3.10/library/tarfile.html#tarfile.TarInfo) и возвращает обновлённый объект [`TarInfo`](https://python-all.ru/3.10/library/tarfile.html#tarfile.TarInfo), или, если нужно исключить файл, функция может вернуть `None`:10541055```python1056>>> import tarfile, glob10571058>>> def myfilter(tarinfo):1059... if tarinfo.isfile(): # сохранять только реальные файлы1060... tarinfo.uname = 'monty' # отредактировать имя пользователя1061... return tarinfo10621063>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:1064... for filename in glob.glob('*.txt'):1065... tf.add(filename, filter=myfilter)1066... tf.list()1067-rw-r--r-- monty/501 902 2011-01-26 17:59:11 annotations.txt1068-rw-r--r-- monty/501 123 2011-01-26 17:59:11 general_questions.txt1069-rw-r--r-- monty/501 3514 2011-01-26 17:59:11 prion.txt1070-rw-r--r-- monty/501 124 2011-01-26 17:59:11 py_todo.txt1071-rw-r--r-- monty/501 1399 2011-01-26 17:59:11 semaphore_notes.txt1072```10731074(Предложено Tarek Ziadé и реализовано Lars Gustäbel в [bpo-6856](https://python-all.ru/3.10/whatsnew/3.2.html).)10751076### hashlib10771078Модуль [`hashlib`](https://python-all.ru/3.10/library/hashlib.html#module-hashlib) имеет два новых константных атрибута, перечисляющих алгоритмы хеширования, гарантированно присутствующие во всех реализациях, и те, что доступны в текущей реализации:10791080```python1081>>> import hashlib10821083>>> hashlib.algorithms_guaranteed1084{'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}10851086>>> hashlib.algorithms_available1087{'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',1088'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',1089'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',1090'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}1091```10921093(Предложено Carl Chenet в [bpo-7418](https://python-all.ru/3.10/whatsnew/3.2.html).)10941095### ast10961097Модуль [`ast`](https://python-all.ru/3.10/library/ast.html#module-ast) имеет замечательный универсальный инструмент для безопасного вычисления строк выражений с использованием синтаксиса литералов Python. Функция [`ast.literal_eval()`](https://python-all.ru/3.10/library/ast.html#ast.literal_eval) служит безопасной альтернативой встроенной функции [`eval()`](https://python-all.ru/3.10/library/functions.html#eval), которую легко использовать во вред. Python 3.2 добавляет литералы [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) и [`set`](https://python-all.ru/3.10/library/stdtypes.html#set) в список поддерживаемых типов: строки, байты, числа, кортежи, списки, словари, множества, булевы значения и `None`.10981099```python1100>>> from ast import literal_eval11011102>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"1103>>> literal_eval(request)1104{'args': (2, 0.5), 'req': 3, 'func': 'pow'}11051106>>> request = "os.system('do something harmful')"1107>>> literal_eval(request)1108Traceback (most recent call last):1109 ...1110ValueError: malformed node or string: <_ast.Call object at 0x101739a10>1111```11121113(Реализовано Бенджамином Петерсоном и Георгом Брандлем.)11141115### os11161117Разные операционные системы используют различные кодировки для имён файлов и переменных окружения. Модуль [`os`](https://python-all.ru/3.10/library/os.html#module-os) предоставляет две новые функции, [`fsencode()`](https://python-all.ru/3.10/library/os.html#os.fsencode) и [`fsdecode()`](https://python-all.ru/3.10/library/os.html#os.fsdecode), для кодирования и декодирования имён файлов:11181119```python1120>>> import os1121>>> filename = 'Sehenswürdigkeiten'1122>>> os.fsencode(filename)1123b'Sehensw\xc3\xbcrdigkeiten'1124```11251126Некоторые операционные системы разрешают прямой доступ к закодированным байтам в окружении. Если это так, константа [`os.supports_bytes_environ`](https://python-all.ru/3.10/library/os.html#os.supports_bytes_environ) будет истинной.11271128Для прямого доступа к закодированным переменным окружения (если доступно) используйте новую функцию [`os.getenvb()`](https://python-all.ru/3.10/library/os.html#os.getenvb) или [`os.environb`](https://python-all.ru/3.10/library/os.html#os.environb), которая является байтовой версией [`os.environ`](https://python-all.ru/3.10/library/os.html#os.environ).11291130(Автор: Victor Stinner.)11311132### shutil11331134Функция [`shutil.copytree()`](https://python-all.ru/3.10/library/shutil.html#shutil.copytree) теперь имеет две новые опции:11351136- *ignore\_dangling\_symlinks*: когда `symlinks=False`, чтобы функция копировала файл, на который указывает символьная ссылка, а не саму ссылку. Эта опция подавляет ошибку, возникающую, если файл не существует.1137- *copy\_function*: вызываемый объект, используемый для копирования файлов. По умолчанию используется [`shutil.copy2()`](https://python-all.ru/3.10/library/shutil.html#shutil.copy2).11381139(Автор: Tarek Ziadé.)11401141Кроме того, модуль [`shutil`](https://python-all.ru/3.10/library/shutil.html#module-shutil) теперь поддерживает [архивацию](https://python-all.ru/3.10/library/shutil.html#archiving-operations) для zip-архивов, несжатых tar-архивов, tar-архивов со сжатием gzip и tar-архивов со сжатием bzip2. Также появились функции для регистрации дополнительных форматов архивов (например, tar-архивы со сжатием xz или пользовательские форматы).11421143Основные функции – [`make_archive()`](https://python-all.ru/3.10/library/shutil.html#shutil.make_archive) и [`unpack_archive()`](https://python-all.ru/3.10/library/shutil.html#shutil.unpack_archive). По умолчанию обе работают с текущей директорией (которую можно задать через [`os.chdir()`](https://python-all.ru/3.10/library/os.html#os.chdir)) и со всеми поддиректориями. Имя файла архива нужно указывать с полным путём. Архивация не разрушает исходные файлы (они остаются без изменений).11441145```python1146>>> import shutil, pprint11471148>>> os.chdir('mydata') # перейти в каталог исходного кода1149>>> f = shutil.make_archive('/var/backup/mydata',1150... 'zip') # архивировать текущий каталог1151>>> f # показать имя архива1152'/var/backup/mydata.zip'1153>>> os.chdir('tmp') # перейти к распаковке1154>>> shutil.unpack_archive('/var/backup/mydata.zip') # восстановить данные11551156>>> pprint.pprint(shutil.get_archive_formats()) # отобразить известные форматы1157[('bztar', "bzip2'ed tar-file"),1158 ('gztar', "gzip'ed tar-file"),1159 ('tar', 'uncompressed tar file'),1160 ('zip', 'ZIP file')]11611162>>> shutil.register_archive_format( # зарегистрировать новый формат архива1163... name='xz',1164... function=xz.compress, # вызываемая функция архивирования1165... extra_args=[('level', 8)], # аргументы функции1166... description='xz compression'1167... )1168```11691170(Автор: Tarek Ziadé.)11711172### sqlite311731174Модуль [`sqlite3`](https://python-all.ru/3.10/library/sqlite3.html#module-sqlite3) обновлён до версии pysqlite 2.6.0. У него появились две новые возможности.11751176- Атрибут `sqlite3.Connection.in_transit` истинен, если есть активная транзакция для незафиксированных изменений.1177- Методы [`sqlite3.Connection.enable_load_extension()`](https://python-all.ru/3.10/library/sqlite3.html#sqlite3.Connection.enable_load_extension) и [`sqlite3.Connection.load_extension()`](https://python-all.ru/3.10/library/sqlite3.html#sqlite3.Connection.load_extension) позволяют загружать расширения SQLite из файлов «.so». Одним из известных расширений является расширение полнотекстового поиска, распространяемое с SQLite.11781179(Авторы: R. David Murray и Shashwat Anand; [bpo-8845](https://python-all.ru/3.10/whatsnew/3.2.html).)11801181### html11821183Появился новый модуль [`html`](https://python-all.ru/3.10/library/html.html#module-html) с единственной функцией [`escape()`](https://python-all.ru/3.10/library/html.html#html.escape), которая используется для экранирования зарезервированных символов в HTML-разметке:11841185```python1186>>> import html1187>>> html.escape('x > 2 && x < 7')1188'x > 2 && x < 7'1189```11901191### socket11921193В модуль [`socket`](https://python-all.ru/3.10/library/socket.html#module-socket) внесены два улучшения.11941195- У объектов сокетов появился метод [`detach()`](https://python-all.ru/3.10/library/socket.html#socket.socket.detach), который переводит сокет в закрытое состояние, не закрывая фактически базовый файловый дескриптор. Последний затем можно использовать для других целей. (Добавлено Antoine Pitrou; [bpo-8524](https://python-all.ru/3.10/whatsnew/3.2.html).)1196- [`socket.create_connection()`](https://python-all.ru/3.10/library/socket.html#socket.create_connection) теперь поддерживает протокол управления контекстом для безусловного поглощения исключений [`socket.error`](https://python-all.ru/3.10/library/socket.html#socket.error) и закрытия сокета по завершении. (Автор: Giampaolo Rodolà; [bpo-9794](https://python-all.ru/3.10/whatsnew/3.2.html).)11971198### ssl11991200Модуль [`ssl`](https://python-all.ru/3.10/library/ssl.html#module-ssl) добавил ряд возможностей для удовлетворения общих требований к защищённым (шифрованным, аутентифицированным) интернет-соединениям:12011202- Новый класс [`SSLContext`](https://python-all.ru/3.10/library/ssl.html#ssl.SSLContext) служит контейнером для постоянных данных SSL, таких как настройки протокола, сертификаты, закрытые ключи и различные другие параметры. Он включает метод [`wrap_socket()`](https://python-all.ru/3.10/library/ssl.html#ssl.SSLContext.wrap_socket) для создания SSL-сокета из SSL-контекста.1203- Новая функция [`ssl.match_hostname()`](https://python-all.ru/3.10/library/ssl.html#ssl.match_hostname) поддерживает проверку идентичности сервера для протоколов более высокого уровня, реализуя правила HTTPS (из [**RFC 2818**](https://python-all.ru/3.10/whatsnew/3.2.html)), которые также подходят для других протоколов.1204- Функция-конструктор [`ssl.wrap_socket()`](https://python-all.ru/3.10/library/ssl.html#ssl.wrap_socket) теперь принимает аргумент *ciphers*. Строка *ciphers* перечисляет разрешённые алгоритмы шифрования в формате, описанном в [документации OpenSSL](https://python-all.ru/3.10/whatsnew/3.2.html).1205- При компоновке с последними версиями OpenSSL модуль [`ssl`](https://python-all.ru/3.10/library/ssl.html#module-ssl) теперь поддерживает расширение Server Name Indication протокола TLS, что позволяет размещать несколько «виртуальных хостов» с разными сертификатами на одном IP-порту. Это расширение поддерживается только в клиентском режиме и активируется передачей аргумента *server\_hostname* в [`ssl.SSLContext.wrap_socket()`](https://python-all.ru/3.10/library/ssl.html#ssl.SSLContext.wrap_socket).1206- В модуль [`ssl`](https://python-all.ru/3.10/library/ssl.html#module-ssl) добавлены различные опции, такие как [`OP_NO_SSLv2`](https://python-all.ru/3.10/library/ssl.html#ssl.OP_NO_SSLv2), которая отключает небезопасный и устаревший протокол SSLv2.1207- Расширение теперь загружает все шифры и алгоритмы дайджестов OpenSSL. Если некоторые SSL-сертификаты не удаётся проверить, они сообщаются как ошибка «неизвестный алгоритм».1208- Версия используемого OpenSSL теперь доступна через атрибуты модуля [`ssl.OPENSSL_VERSION`](https://python-all.ru/3.10/library/ssl.html#ssl.OPENSSL_VERSION) (строка), [`ssl.OPENSSL_VERSION_INFO`](https://python-all.ru/3.10/library/ssl.html#ssl.OPENSSL_VERSION_INFO) (кортеж из 5 элементов) и [`ssl.OPENSSL_VERSION_NUMBER`](https://python-all.ru/3.10/library/ssl.html#ssl.OPENSSL_VERSION_NUMBER) (целое число).12091210(Предложено Антуаном Питру в [bpo-8850](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-1589](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-8322](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-5639](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-4870](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-8484](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-8321](https://python-all.ru/3.10/whatsnew/3.2.html).)12111212### nntp12131214Модуль [`nntplib`](https://python-all.ru/3.10/library/nntplib.html#module-nntplib) получил переработанную реализацию с улучшенной семантикой байтов и текста, а также более практичными API. Эти изменения нарушают совместимость с версией nntplib из Python 3.1, которая и сама по себе была частично неработоспособна.12151216Также добавлена поддержка защищённых соединений как через неявный (с использованием [`nntplib.NNTP_SSL`](https://python-all.ru/3.10/library/nntplib.html#nntplib.NNTP_SSL)), так и через явный (с использованием [`nntplib.NNTP.starttls()`](https://python-all.ru/3.10/library/nntplib.html#nntplib.NNTP.starttls)) TLS.12171218(Предложено Антуаном Питру в [bpo-9360](https://python-all.ru/3.10/whatsnew/3.2.html) и Эндрю Вантом в [bpo-1926](https://python-all.ru/3.10/whatsnew/3.2.html).)12191220### сертификаты12211222[`http.client.HTTPSConnection`](https://python-all.ru/3.10/library/http.client.html#http.client.HTTPSConnection), [`urllib.request.HTTPSHandler`](https://python-all.ru/3.10/library/urllib.request.html#urllib.request.HTTPSHandler) и [`urllib.request.urlopen()`](https://python-all.ru/3.10/library/urllib.request.html#urllib.request.urlopen) теперь принимают необязательные аргументы, позволяющие проверять сертификаты сервера на соответствие набору центров сертификации, как рекомендуется при публичном использовании HTTPS.12231224(Добавлено Антуаном Питру, [bpo-9003](https://python-all.ru/3.10/whatsnew/3.2.html).)12251226### imaplib12271228Поддержка явного TLS для стандартных IMAP4-соединений была добавлена через новый метод [`imaplib.IMAP4.starttls`](https://python-all.ru/3.10/library/imaplib.html#imaplib.IMAP4.starttls).12291230(Предложено Лоренцо М. Катуччи и Антуаном Питру, [bpo-4471](https://python-all.ru/3.10/whatsnew/3.2.html).)12311232### http.client12331234В модуле [`http.client`](https://python-all.ru/3.10/library/http.client.html#module-http.client) был сделан ряд небольших улучшений API. Простые ответы HTTP 0.9 старого стиля больше не поддерживаются, а параметр *strict* считается устаревшим во всех классах.12351236Классы [`HTTPConnection`](https://python-all.ru/3.10/library/http.client.html#http.client.HTTPConnection) и [`HTTPSConnection`](https://python-all.ru/3.10/library/http.client.html#http.client.HTTPSConnection) теперь имеют параметр *source\_address* – кортеж (host, port), указывающий, откуда устанавливается HTTP-соединение.12371238Поддержка проверки сертификатов и виртуальных хостов HTTPS была добавлена в [`HTTPSConnection`](https://python-all.ru/3.10/library/http.client.html#http.client.HTTPSConnection).12391240Метод [`request()`](https://python-all.ru/3.10/library/http.client.html#http.client.HTTPConnection.request) у объектов соединения допускал необязательный аргумент *body*, чтобы для содержимого запроса можно было использовать [файловый объект](https://python-all.ru/3.10/glossary.html#term-file-object). Удобно, что аргумент *body* теперь также принимает [итерируемый объект](https://python-all.ru/3.10/glossary.html#term-iterable) при условии, что он содержит явный заголовок `Content-Length`. Такой расширенный интерфейс стал гораздо гибче, чем раньше.12411242Для установления HTTPS-соединения через прокси-сервер появился новый метод [`set_tunnel()`](https://python-all.ru/3.10/library/http.client.html#http.client.HTTPConnection.set_tunnel), который задаёт хост и порт для туннелирования HTTP Connect.12431244Для согласованности с поведением [`http.server`](https://python-all.ru/3.10/library/http.server.html#module-http.server) библиотека HTTP-клиента теперь также кодирует заголовки в ISO-8859-1 (Latin-1). Ранее она уже так делала для входящих заголовков, поэтому теперь поведение одинаково для входящего и исходящего трафика. (См. работу Армина Ронахера в [bpo-10980](https://python-all.ru/3.10/whatsnew/3.2.html).)12451246### unittest12471248Модуль unittest получил ряд улучшений: поддержка обнаружения тестов для пакетов, более простое экспериментирование в интерактивной оболочке, новые методы тестовых случаев, улучшенные диагностические сообщения при сбоях тестов и более понятные имена методов.12491250- Командный вызов `python -m unittest` теперь может принимать пути к файлам вместо имён модулей для запуска конкретных тестов ([bpo-10620](https://python-all.ru/3.10/whatsnew/3.2.html)). Новая система обнаружения тестов может находить тесты внутри пакетов, находя любой импортируемый тест из корневого каталога. Корневой каталог можно указать с помощью опции `-t`, шаблон для сопоставления файлов – с помощью `-p`, а каталог для начала поиска – с помощью `-s`:12511252 ```console1253 $ python -m unittest discover -s my_proj_dir -p _test.py1254 ```12551256 (Предложено Michael Foord.)1257- Экспериментирование в интерактивной оболочке стало проще, поскольку класс `unittest.case.TestCase` теперь можно создавать без аргументов:12581259 ```python1260 >>> from unittest import TestCase1261 >>> TestCase().assertEqual(pow(2, 3), 8)1262 ```12631264 (Предложено Michael Foord.)1265- Модуль [`unittest`](https://python-all.ru/3.10/library/unittest.html#module-unittest) содержит два новых метода, [`assertWarns()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertWarns) и [`assertWarnsRegex()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertWarnsRegex), для проверки того, что заданный тип предупреждения вызывается тестируемым кодом:12661267 ```python1268 with self.assertWarns(DeprecationWarning):1269 legacy_function('XYZ')1270 ```12711272 (Предложено Антуаном Питру, [bpo-9754](https://python-all.ru/3.10/whatsnew/3.2.html).)12731274 Ещё один новый метод, [`assertCountEqual()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertCountEqual), используется для сравнения двух итерируемых объектов с целью определить, равны ли их количества элементов (присутствуют ли одни и те же элементы с одинаковым числом вхождений независимо от порядка):12751276 ```python1277 def test_anagram(self):1278 self.assertCountEqual('algorithm', 'logarithm')1279 ```12801281 (Автор: Raymond Hettinger.)1282- Одна из основных особенностей модуля unittest – стремление выдавать содержательные диагностические сообщения при сбое теста. По возможности сбой записывается вместе с diff вывода. Это особенно полезно при анализе журналов неудачных тестовых запусков. Однако, поскольку diff может быть объёмным, появился новый атрибут [`maxDiff`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.maxDiff), задающий максимальную длину отображаемого diff.1283- Кроме того, имена методов в модуле были приведены в порядок.12841285 Например, [`assertRegex()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertRegex) – новое имя для `assertRegexpMatches()`, которое было названо неправильно, потому что тест использует [`re.search()`](https://python-all.ru/3.10/library/re.html#re.search), а не [`re.match()`](https://python-all.ru/3.10/library/re.html#re.match). Другие методы, использующие регулярные выражения, теперь именуются с использованием краткой формы «Regex» вместо «Regexp» – это соответствует именам, используемым в других реализациях unittest, соответствует старому названию модуля [`re`](https://python-all.ru/3.10/library/re.html#module-re) в Python и имеет однозначный верблюжий регистр.12861287 (Предложено Raymond Hettinger; реализовано Ezio Melotti.)1288- Чтобы повысить согласованность, некоторые давно существующие псевдонимы методов объявляются устаревшими; вместо них следует использовать предпочтительные имена:12891290 > | Старое имя | Предпочтительное имя |1291 > | --- | --- |1292 > | `assert_()` | [`assertTrue()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertTrue) |1293 > | `assertEquals()` | [`assertEqual()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertEqual) |1294 > | `assertNotEquals()` | [`assertNotEqual()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertNotEqual) |1295 > | `assertAlmostEquals()` | [`assertAlmostEqual()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertAlmostEqual) |1296 > | `assertNotAlmostEquals()` | [`assertNotAlmostEqual()`](https://python-all.ru/3.10/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) |12971298 Аналогично, методы `TestCase.fail*`, объявленные устаревшими в Python 3.1, предположительно будут удалены в Python 3.3. Также см. раздел [Устаревшие псевдонимы](https://python-all.ru/3.10/library/unittest.html#deprecated-aliases) в документации [`unittest`](https://python-all.ru/3.10/library/unittest.html#module-unittest).12991300 (Предложено Ezio Melotti; [bpo-9424](https://python-all.ru/3.10/whatsnew/3.2.html).)1301- Метод `assertDictContainsSubset()` был объявлен устаревшим, потому что он был реализован с ошибкой: аргументы передавались в неправильном порядке. Это создавало трудно отлаживаемые оптические иллюзии, когда тесты вроде `TestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1})` завершались неудачей.13021303 (Автор: Raymond Hettinger.)13041305### random13061307Целочисленные методы модуля [`random`](https://python-all.ru/3.10/library/random.html#module-random) теперь лучше генерируют равномерные распределения. Раньше они вычисляли выборки с помощью `int(n*random())`, что давало небольшое смещение, когда *n* не было степенью двойки. Теперь производится несколько выборок из диапазона, размер которого равен ближайшей степени двойки, и выборка сохраняется только если она попадает в диапазон `0 <= x < n`. Затронутые функции и методы: [`randrange()`](https://python-all.ru/3.10/library/random.html#random.randrange), [`randint()`](https://python-all.ru/3.10/library/random.html#random.randint), [`choice()`](https://python-all.ru/3.10/library/random.html#random.choice), [`shuffle()`](https://python-all.ru/3.10/library/random.html#random.shuffle) и [`sample()`](https://python-all.ru/3.10/library/random.html#random.sample).13081309(Предложено Raymond Hettinger; [bpo-9025](https://python-all.ru/3.10/whatsnew/3.2.html).)13101311### poplib13121313Класс [`POP3_SSL`](https://python-all.ru/3.10/library/poplib.html#poplib.POP3_SSL) теперь принимает параметр *контекст*, который является объектом [`ssl.SSLContext`](https://python-all.ru/3.10/library/ssl.html#ssl.SSLContext), позволяющим объединять параметры настройки SSL, сертификаты и закрытые ключи в единую (потенциально долгоживущую) структуру.13141315(Предложено Giampaolo Rodolà; [bpo-8807](https://python-all.ru/3.10/whatsnew/3.2.html).)13161317### asyncore13181319[`asyncore.dispatcher`](https://python-all.ru/3.10/library/asyncore.html#asyncore.dispatcher) теперь предоставляет метод [`handle_accepted()`](https://python-all.ru/3.10/library/asyncore.html#asyncore.dispatcher.handle_accepted), возвращающий пару `(sock, addr)`, который вызывается, когда соединение с новой удалённой конечной точкой фактически установлено. Предполагается, что он будет использоваться как замена старому [`handle_accept()`](https://python-all.ru/3.10/library/asyncore.html#asyncore.dispatcher.handle_accept) и избавляет пользователя от необходимости напрямую вызывать [`accept()`](https://python-all.ru/3.10/library/asyncore.html#asyncore.dispatcher.accept).13201321(Предложено Giampaolo Rodolà; [bpo-6706](https://python-all.ru/3.10/whatsnew/3.2.html).)13221323### tempfile13241325Модуль [`tempfile`](https://python-all.ru/3.10/library/tempfile.html#module-tempfile) теперь содержит новый менеджер контекста [`TemporaryDirectory`](https://python-all.ru/3.10/library/tempfile.html#tempfile.TemporaryDirectory), который обеспечивает простое детерминированное удаление временных каталогов:13261327```python1328with tempfile.TemporaryDirectory() as tmpdirname:1329 print('created temporary dir:', tmpdirname)1330```13311332(Предложено Neil Schemenauer и Nick Coghlan; [bpo-5178](https://python-all.ru/3.10/whatsnew/3.2.html).)13331334### inspect13351336- Модуль [`inspect`](https://python-all.ru/3.10/library/inspect.html#module-inspect) содержит новую функцию [`getgeneratorstate()`](https://python-all.ru/3.10/library/inspect.html#inspect.getgeneratorstate) для простого определения текущего состояния генератора-итератора:13371338 ```python1339 >>> from inspect import getgeneratorstate1340 >>> def gen():1341 ... yield 'demo'1342 >>> g = gen()1343 >>> getgeneratorstate(g)1344 'GEN_CREATED'1345 >>> next(g)1346 'demo'1347 >>> getgeneratorstate(g)1348 'GEN_SUSPENDED'1349 >>> next(g, None)1350 >>> getgeneratorstate(g)1351 'GEN_CLOSED'1352 ```13531354 (Предложено Rodolpho Eckhardt и Nick Coghlan; [bpo-10220](https://python-all.ru/3.10/whatsnew/3.2.html).)1355- Для поддержки поиска без возможности активации динамического атрибута в модуле [`inspect`](https://python-all.ru/3.10/library/inspect.html#module-inspect) появилась новая функция [`getattr_static()`](https://python-all.ru/3.10/library/inspect.html#inspect.getattr_static). В отличие от [`hasattr()`](https://python-all.ru/3.10/library/functions.html#hasattr), это настоящий поиск только для чтения, который гарантированно не меняет состояние во время поиска:13561357 ```python1358 >>> class A:1359 ... @property1360 ... def f(self):1361 ... print('Running')1362 ... return 101363 ...1364 >>> a = A()1365 >>> getattr(a, 'f')1366 Running1367 101368 >>> inspect.getattr_static(a, 'f')1369 <property object at 0x1022bd788>1370 ```13711372> (Предложено Michael Foord.)13731374### pydoc13751376Модуль [`pydoc`](https://python-all.ru/3.10/library/pydoc.html#module-pydoc) теперь предоставляет значительно улучшенный интерфейс веб-сервера, а также новый параметр командной строки `-b` для автоматического открытия окна браузера для отображения этого сервера:13771378```console1379$ pydoc3.2 -b1380```13811382(Предложено Ron Adam; [bpo-2001](https://python-all.ru/3.10/whatsnew/3.2.html).)13831384### dis13851386Модуль [`dis`](https://python-all.ru/3.10/library/dis.html#module-dis) пополнился двумя новыми функциями для инспекции кода: [`code_info()`](https://python-all.ru/3.10/library/dis.html#dis.code_info) и [`show_code()`](https://python-all.ru/3.10/library/dis.html#dis.show_code). Обе предоставляют подробную информацию об объекте кода для переданной функции, метода, строки исходного кода или объекта кода. Первая возвращает строку, вторая выводит её:13871388```python1389>>> import dis, random1390>>> dis.show_code(random.choice)1391Name: choice1392Filename: /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py1393Argument count: 21394Kw-only arguments: 01395Number of locals: 31396Stack size: 111397Flags: OPTIMIZED, NEWLOCALS, NOFREE1398Constants:1399 0: 'Choose a random element from a non-empty sequence.'1400 1: 'Cannot choose from an empty sequence'1401Names:1402 0: _randbelow1403 1: len1404 2: ValueError1405 3: IndexError1406Variable names:1407 0: self1408 1: seq1409 2: i1410```14111412Кроме того, функция [`dis()`](https://python-all.ru/3.10/library/dis.html#dis.dis) теперь принимает строковые аргументы, так что распространённую идиому `dis(compile(s, '', 'eval'))` можно сократить до `dis(s)`:14131414```python1415>>> dis('3*x+1 if x%2==1 else x//2')1416 1 0 LOAD_NAME 0 (x)1417 3 LOAD_CONST 0 (2)1418 6 BINARY_MODULO1419 7 LOAD_CONST 1 (1)1420 10 COMPARE_OP 2 (==)1421 13 POP_JUMP_IF_FALSE 281422 16 LOAD_CONST 2 (3)1423 19 LOAD_NAME 0 (x)1424 22 BINARY_MULTIPLY1425 23 LOAD_CONST 1 (1)1426 26 BINARY_ADD1427 27 RETURN_VALUE1428 >> 28 LOAD_NAME 0 (x)1429 31 LOAD_CONST 0 (2)1430 34 BINARY_FLOOR_DIVIDE1431 35 RETURN_VALUE1432```14331434В совокупности эти улучшения упрощают изучение того, как реализован CPython, и позволяют самому увидеть, что делает синтаксис языка «под капотом».14351436(Предложено Nick Coghlan; [bpo-9147](https://python-all.ru/3.10/whatsnew/3.2.html).)14371438### dbm14391440Все модули баз данных теперь поддерживают методы `get()` и `setdefault()`.14411442(Предложено Рэем Алленом в [bpo-9523](https://python-all.ru/3.10/whatsnew/3.2.html).)14431444### ctypes14451446Новый тип [`ctypes.c_ssize_t`](https://python-all.ru/3.10/library/ctypes.html#ctypes.c_ssize_t) представляет тип данных C `ssize_t`.14471448### site14491450Модуль [`site`](https://python-all.ru/3.10/library/site.html#module-site) содержит три новые функции, полезные для вывода подробной информации об установке Python.14511452- [`getsitepackages()`](https://python-all.ru/3.10/library/site.html#site.getsitepackages) выводит список всех глобальных каталогов site-packages.1453- [`getuserbase()`](https://python-all.ru/3.10/library/site.html#site.getuserbase) сообщает базовый каталог пользователя, в котором могут храниться данные.1454- [`getusersitepackages()`](https://python-all.ru/3.10/library/site.html#site.getusersitepackages) показывает путь к каталогу site-packages для конкретного пользователя.14551456```python1457>>> import site1458>>> site.getsitepackages()1459['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',1460 '/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',1461 '/Library/Python/3.2/site-packages']1462>>> site.getuserbase()1463'/Users/raymondhettinger/Library/Python/3.2'1464>>> site.getusersitepackages()1465'/Users/raymondhettinger/Library/Python/3.2/lib/python/site-packages'1466```14671468Удобно, что часть функциональности site доступна напрямую из командной строки:14691470```console1471$ python -m site --user-base1472/Users/raymondhettinger/.local1473$ python -m site --user-site1474/Users/raymondhettinger/.local/lib/python3.2/site-packages1475```14761477(Добавлено Тареком Зиаде в [bpo-6693](https://python-all.ru/3.10/whatsnew/3.2.html).)14781479### sysconfig14801481Новый модуль [`sysconfig`](https://python-all.ru/3.10/library/sysconfig.html#module-sysconfig) упрощает обнаружение путей установки и переменных конфигурации, которые различаются в зависимости от платформы и настроек установки.14821483Модуль предоставляет простые функции доступа для получения информации о платформе и версии:14841485- [`get_platform()`](https://python-all.ru/3.10/library/sysconfig.html#sysconfig.get_platform) возвращает значения наподобие *linux-i586* или *macosx-10.6-ppc*.1486- [`get_python_version()`](https://python-all.ru/3.10/library/sysconfig.html#sysconfig.get_python_version) возвращает строку с номером версии Python, например «3.2».14871488Он также предоставляет доступ к путям и переменным, соответствующим одной из семи именованных схем, используемых в [`distutils`](https://python-all.ru/3.10/library/distutils.html#module-distutils). К ним относятся *posix\_prefix*, *posix\_home*, *posix\_user*, *nt*, *nt\_user*, *os2*, *os2\_home*:14891490- [`get_paths()`](https://python-all.ru/3.10/library/sysconfig.html#sysconfig.get_paths) создаёт словарь, содержащий пути установки для текущей схемы установки.1491- [`get_config_vars()`](https://python-all.ru/3.10/library/sysconfig.html#sysconfig.get_config_vars) возвращает словарь платформенно-зависимых переменных.14921493Также имеется удобный интерфейс командной строки:14941495```doscon1496C:\Python32>python -m sysconfig1497Platform: "win32"1498Python version: "3.2"1499Current installation scheme: "nt"15001501Paths:1502 data = "C:\Python32"1503 include = "C:\Python32\Include"1504 platinclude = "C:\Python32\Include"1505 platlib = "C:\Python32\Lib\site-packages"1506 platstdlib = "C:\Python32\Lib"1507 purelib = "C:\Python32\Lib\site-packages"1508 scripts = "C:\Python32\Scripts"1509 stdlib = "C:\Python32\Lib"15101511Variables:1512 BINDIR = "C:\Python32"1513 BINLIBDEST = "C:\Python32\Lib"1514 EXE = ".exe"1515 INCLUDEPY = "C:\Python32\Include"1516 LIBDEST = "C:\Python32\Lib"1517 SO = ".pyd"1518 VERSION = "32"1519 abiflags = ""1520 base = "C:\Python32"1521 exec_prefix = "C:\Python32"1522 platbase = "C:\Python32"1523 prefix = "C:\Python32"1524 projectbase = "C:\Python32"1525 py_version = "3.2"1526 py_version_nodot = "32"1527 py_version_short = "3.2"1528 srcdir = "C:\Python32"1529 userbase = "C:\Documents and Settings\Raymond\Application Data\Python"1530```15311532(Перенесено из Distutils Тареком Зиаде.)15331534### pdb15351536Модуль отладчика [`pdb`](https://python-all.ru/3.10/library/pdb.html#module-pdb) получил ряд улучшений в удобстве использования:15371538- `pdb.py` теперь имеет опцию `-c`, которая выполняет команды, заданные в файле сценария `.pdbrc`.1539- Файл сценария `.pdbrc` может содержать команды `continue` и `next`, которые продолжают отладку.1540- Конструктор класса `Pdb` теперь принимает аргумент *nosigint*.1541- Новые команды: `l(list)`, `ll(long list)` и `source` для вывода исходного кода.1542- Новые команды: `display` и `undisplay` для показа или скрытия значения выражения, если оно изменилось.1543- Новая команда: `interact` для запуска интерактивного интерпретатора, содержащего глобальные и локальные имена из текущей области видимости.1544- Точки останова можно удалять по номеру.15451546(Добавлено Георгом Брандлем, Антонио Куни и Ильёй Сандлером.)15471548### configparser15491550Модуль [`configparser`](https://python-all.ru/3.10/library/configparser.html#module-configparser) был изменён для повышения удобства использования и предсказуемости парсера по умолчанию и поддерживаемого им синтаксиса INI. Старый класс `ConfigParser` был удалён в пользу `SafeConfigParser`, который, в свою очередь, был переименован в [`ConfigParser`](https://python-all.ru/3.10/library/configparser.html#configparser.ConfigParser). Поддержка inline-комментариев теперь по умолчанию отключена, а дубликаты секций или опций не допускаются в одном источнике конфигурации.15511552Парсеры конфигураций получили новый API на основе протокола отображения:15531554```python1555>>> parser = ConfigParser()1556>>> parser.read_string("""1557... [DEFAULT]1558... location = upper left1559... visible = yes1560... editable = no1561... color = blue1562...1563... [main]1564... title = Main Menu1565... color = green1566...1567... [options]1568... title = Options1569... """)1570>>> parser['main']['color']1571'green'1572>>> parser['main']['editable']1573'no'1574>>> section = parser['options']1575>>> section['title']1576'Options'1577>>> section['title'] = 'Options (editable: %(editable)s)'1578>>> section['title']1579'Options (editable: no)'1580```15811582Новый API реализован поверх классического API, поэтому пользовательские подклассы парсеров должны иметь возможность использовать его без изменений.15831584Структура INI-файла, принимаемая парсерами конфигураций, теперь может быть настроена. Пользователи могут задавать альтернативные разделители опция/значение и префиксы комментариев, изменять имя секции *DEFAULT* или переключать синтаксис интерполяции.15851586Поддерживается подключаемая интерполяция, включая дополнительный обработчик интерполяции [`ExtendedInterpolation`](https://python-all.ru/3.10/library/configparser.html#configparser.ExtendedInterpolation):15871588```python1589>>> parser = ConfigParser(interpolation=ExtendedInterpolation())1590>>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},1591... 'custom': {'prefix': '/usr/local'}})1592>>> parser.read_string("""1593... [buildout]1594... parts =1595... zope91596... instance1597... find-links =1598... ${buildout:directory}/downloads/dist1599...1600... [zope9]1601... recipe = plone.recipe.zope9install1602... location = /opt/zope1603...1604... [instance]1605... recipe = plone.recipe.zope9instance1606... zope9-location = ${zope9:location}1607... zope-conf = ${custom:prefix}/etc/zope.conf1608... """)1609>>> parser['buildout']['find-links']1610'\n/home/ambv/zope9/downloads/dist'1611>>> parser['instance']['zope-conf']1612'/usr/local/etc/zope.conf'1613>>> instance = parser['instance']1614>>> instance['zope-conf']1615'/usr/local/etc/zope.conf'1616>>> instance['zope9-location']1617'/opt/zope'1618```16191620Был также введён ряд небольших возможностей, таких как поддержка указания кодировки в операциях чтения, указание значений по умолчанию для get-функций или чтение напрямую из словарей и строк.16211622(Все изменения предоставлены Łukasz Langa.)16231624### urllib.parse16251626Для модуля [`urllib.parse`](https://python-all.ru/3.10/library/urllib.parse.html#module-urllib.parse) был сделан ряд улучшений удобства использования.16271628Функция [`urlparse()`](https://python-all.ru/3.10/library/urllib.parse.html#urllib.parse.urlparse) теперь поддерживает адреса [IPv6](https://python-all.ru/3.10/whatsnew/3.2.html), как описано в [**RFC 2732**](https://python-all.ru/3.10/whatsnew/3.2.html):16291630```python1631>>> import urllib.parse1632>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') 1633ParseResult(scheme='http',1634 netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',1635 path='/foo/',1636 params='',1637 query='',1638 fragment='')1639```16401641Функция [`urldefrag()`](https://python-all.ru/3.10/library/urllib.parse.html#urllib.parse.urldefrag) теперь возвращает [именованный кортеж](https://python-all.ru/3.10/glossary.html#term-named-tuple):16421643```python1644>>> r = urllib.parse.urldefrag('http://python.org/about/#target')1645>>> r1646DefragResult(url='http://python.org/about/', fragment='target')1647>>> r[0]1648'http://python.org/about/'1649>>> r.fragment1650'target'1651```16521653Кроме того, функция [`urlencode()`](https://python-all.ru/3.10/library/urllib.parse.html#urllib.parse.urlencode) теперь стала гораздо более гибкой, принимая аргумент *query* как строкового, так и байтового типа. Если это строка, то параметры *safe*, *encoding* и *error* передаются в [`quote_plus()`](https://python-all.ru/3.10/library/urllib.parse.html#urllib.parse.quote_plus) для кодирования:16541655```python1656>>> urllib.parse.urlencode([1657... ('type', 'telenovela'),1658... ('name', '¿Dónde Está Elisa?')],1659... encoding='latin-1')1660'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'1661```16621663Как подробно описано в [Parsing ASCII Encoded Bytes](https://python-all.ru/3.10/library/urllib.parse.html#parsing-ascii-encoded-bytes), все функции [`urllib.parse`](https://python-all.ru/3.10/library/urllib.parse.html#module-urllib.parse) теперь принимают на вход ASCII-кодированные байтовые строки, при условии, что они не смешиваются с обычными строками. Если в качестве параметров указаны ASCII-кодированные байтовые строки, возвращаемые типы также будут ASCII-кодированными байтовыми строками:16641665```python1666>>> urllib.parse.urlparse(b'http://www.python.org:80/about/') 1667ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',1668 path=b'/about/', params=b'', query=b'', fragment=b'')1669```16701671(Работа Nick Coghlan, Dan Mahn и Senthil Kumaran в [bpo-2987](https://python-all.ru/3.10/whatsnew/3.2.html), [bpo-5468](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-9873](https://python-all.ru/3.10/whatsnew/3.2.html).)16721673### mailbox16741675Благодаря согласованным усилиям R. David Murray, модуль [`mailbox`](https://python-all.ru/3.10/library/mailbox.html#module-mailbox) был исправлен для Python 3.2. Сложность заключалась в том, что mailbox изначально был спроектирован с текстовым интерфейсом, но email-сообщения лучше представлять с помощью [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes), поскольку различные части сообщения могут иметь разные кодировки.16761677Решение использовало двоичную поддержку пакета [`email`](https://python-all.ru/3.10/library/email.html#module-email) для разбора произвольных email-сообщений. Кроме того, решение потребовало ряда изменений API.16781679Как и ожидалось, метод [`add()`](https://python-all.ru/3.10/library/mailbox.html#mailbox.Mailbox.add) для объектов [`mailbox.Mailbox`](https://python-all.ru/3.10/library/mailbox.html#mailbox.Mailbox) теперь принимает двоичные входные данные.16801681[`StringIO`](https://python-all.ru/3.10/library/io.html#io.StringIO) и ввод из текстового файла устарели. Кроме того, строковый ввод будет выдавать ошибку на раннем этапе, если используются не-ASCII символы. Ранее ошибка возникала при обработке email на более позднем шаге.16821683Также поддерживается двоичный вывод. Метод [`get_file()`](https://python-all.ru/3.10/library/mailbox.html#mailbox.Mailbox.get_file) теперь возвращает файл в двоичном режиме (ранее он некорректно устанавливал файл в текстовый режим). Также появился новый метод [`get_bytes()`](https://python-all.ru/3.10/library/mailbox.html#mailbox.Mailbox.get_bytes), который возвращает [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes)-представление сообщения, соответствующего заданному *ключу*.16841685Всё ещё возможно получить недвоичный вывод, используя метод [`get_string()`](https://python-all.ru/3.10/library/mailbox.html#mailbox.Mailbox.get_string) старого API, но такой подход не очень полезен. Вместо этого лучше извлекать сообщения из объекта [`Message`](https://python-all.ru/3.10/library/mailbox.html#mailbox.Message) или загружать их из двоичного ввода.16861687(Предоставлено R. David Murray, при участии Steffen Daode Nurpmeso и начального патча от Victor Stinner в [bpo-9124](https://python-all.ru/3.10/whatsnew/3.2.html).)16881689### turtledemo16901691Демонстрационный код для модуля [`turtle`](https://python-all.ru/3.10/library/turtle.html#module-turtle) был перенесён из каталога *Demo* в основную библиотеку. Он включает более десятка примеров скриптов с наглядными демонстрациями. Находясь в [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path), его теперь можно запускать напрямую из командной строки:16921693```console1694$ python -m turtledemo1695```16961697(Перенесён из каталога Demo Alexander Belopolsky в [bpo-10199](https://python-all.ru/3.10/whatsnew/3.2.html).)16981699## Многопоточность17001701- Механизм сериализации выполнения одновременно работающих потоков Python (обычно известный как [GIL](https://python-all.ru/3.10/glossary.html#term-GIL) или Global Interpreter Lock) был переписан. Среди целей были более предсказуемые интервалы переключения и снижение накладных расходов из-за конкуренции за блокировку и количества последующих системных вызовов. Понятие «интервал проверки» для разрешения переключения потоков было отброшено и заменено абсолютной длительностью, выраженной в секундах. Этот параметр настраивается через [`sys.setswitchinterval()`](https://python-all.ru/3.10/library/sys.html#sys.setswitchinterval). В настоящее время по умолчанию он составляет 5 миллисекунд.17021703 Дополнительные сведения о реализации можно прочитать в [сообщении в списке рассылки python-dev](https://python-all.ru/3.10/whatsnew/3.2.html) (однако, «приоритетные запросы», как описано в этом сообщении, не были сохранены для включения).17041705 (Предоставлено Antoine Pitrou.)1706- Обычные и рекурсивные блокировки теперь принимают необязательный аргумент *timeout* для своего метода [`acquire()`](https://python-all.ru/3.10/library/threading.html#threading.Lock.acquire). (Предоставлено Antoine Pitrou; [bpo-7316](https://python-all.ru/3.10/whatsnew/3.2.html).)1707- Аналогично, [`threading.Semaphore.acquire()`](https://python-all.ru/3.10/library/threading.html#threading.Semaphore.acquire) также получил аргумент *timeout*. (Предоставлено Torsten Landschoff; [bpo-850728](https://python-all.ru/3.10/whatsnew/3.2.html).)1708- Обычные и рекурсивные захваты блокировки теперь можно прерывать сигналами на платформах, использующих Pthreads. Это означает, что программы Python, которые взаимоблокируются при захвате блокировок, можно успешно завершить, многократно отправляя процессу SIGINT (нажав `Ctrl+C` в большинстве оболочек). (Автор: Reid Kleckner; [bpo-8844](https://python-all.ru/3.10/whatsnew/3.2.html).)17091710## Оптимизации17111712Добавлено несколько небольших улучшений производительности:17131714- Оптимизатор «глазка» Python теперь распознает шаблоны, такие как `x in {1, 2, 3}`, как проверку принадлежности к набору констант. Оптимизатор перестраивает [`set`](https://python-all.ru/3.10/library/stdtypes.html#set) в [`frozenset`](https://python-all.ru/3.10/library/stdtypes.html#frozenset) и сохраняет предварительно построенную константу.17151716 Теперь, когда замедление устранено, стало практичным начать писать проверки принадлежности с использованием set-нотации. Этот стиль одновременно ясен семантически и быстр в работе:17171718 ```python1719 extension = name.rpartition('.')[2]1720 if extension in {'xml', 'html', 'xhtml', 'css'}:1721 handle(name)1722 ```17231724 (Патч и дополнительные тесты предоставлены Дэйвом Малкольмом; [bpo-6690](https://python-all.ru/3.10/whatsnew/3.2.html)).1725- Сериализация и десериализация данных с использованием модуля [`pickle`](https://python-all.ru/3.10/library/pickle.html#module-pickle) теперь работает в несколько раз быстрее.17261727 (Предоставлено Александром Вассалотти, Антуаном Питру и командой Unladen Swallow в [bpo-9410](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-3873](https://python-all.ru/3.10/whatsnew/3.2.html).)1728- Алгоритм [Timsort](https://python-all.ru/3.10/whatsnew/3.2.html), используемый в [`list.sort()`](https://python-all.ru/3.10/library/stdtypes.html#list.sort) и [`sorted()`](https://python-all.ru/3.10/library/functions.html#sorted), теперь работает быстрее и использует меньше памяти при вызове с [функцией ключа](https://python-all.ru/3.10/glossary.html#term-key-function). Ранее каждый элемент списка оборачивался временным объектом, который запоминал значение ключа для каждого элемента. Теперь два массива ключей и значений сортируются параллельно. Это экономит память, потребляемую обёртками сортировки, и время, затрачиваемое на делегирование сравнений.17291730 (Патч от Дэниела Штуцбаха в [bpo-9915](https://python-all.ru/3.10/whatsnew/3.2.html).)1731- Производительность декодирования JSON улучшена, а потребление памяти снижено, когда одна и та же строка повторяется для нескольких ключей. Кроме того, кодирование JSON теперь использует ускорения на C, когда аргумент `sort_keys` равен true.17321733 (Предоставлено Антуаном Питру в [bpo-7451](https://python-all.ru/3.10/whatsnew/3.2.html) и Рэймондом Хеттингером и Антуаном Питру в [bpo-10314](https://python-all.ru/3.10/whatsnew/3.2.html).)1734- Рекурсивные блокировки (созданные с помощью API [`threading.RLock()`](https://python-all.ru/3.10/library/threading.html#threading.RLock)) теперь выигрывают от реализации на C, которая делает их такими же быстрыми, как обычные блокировки, и в 10–15 раз быстрее, чем их предыдущая чистая реализация на Python.17351736 (Предоставлено Антуаном Питру; [bpo-3001](https://python-all.ru/3.10/whatsnew/3.2.html).)1737- Алгоритм быстрого поиска в stringlib теперь используется методами `split()`, `rsplit()`, `splitlines()` и `replace()` на объектах [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes), [`bytearray`](https://python-all.ru/3.10/library/stdtypes.html#bytearray) и [`str`](https://python-all.ru/3.10/library/stdtypes.html#str). Аналогично, алгоритм используется и в `rfind()`, `rindex()`, `rsplit()` и `rpartition()`.17381739 (Патч от Флорана Ксиклуна в [bpo-7622](https://python-all.ru/3.10/whatsnew/3.2.html) и [bpo-7462](https://python-all.ru/3.10/whatsnew/3.2.html).)1740- Преобразования целых чисел в строки теперь работают с двумя «цифрами» за раз, сокращая количество операций деления и взятия остатка.17411742 ([bpo-6713](https://python-all.ru/3.10/whatsnew/3.2.html) от Гавейна Болтона, Марка Дикинсона и Виктора Стиннера.)17431744Было сделано несколько других незначительных оптимизаций. Разность множеств теперь работает быстрее, когда один операнд намного больше другого (патч от Андреса Беннетта в [bpo-8685](https://python-all.ru/3.10/whatsnew/3.2.html)). Метод `array.repeat()` получил более быструю реализацию ([bpo-1569291](https://python-all.ru/3.10/whatsnew/3.2.html) от Александра Белопольского). `BaseHTTPRequestHandler` имеет более эффективную буферизацию ([bpo-3709](https://python-all.ru/3.10/whatsnew/3.2.html) от Эндрю Шаафа). Функция [`operator.attrgetter()`](https://python-all.ru/3.10/library/operator.html#operator.attrgetter) была ускорена ([bpo-10160](https://python-all.ru/3.10/whatsnew/3.2.html) от Христоса Георгиу). И `ConfigParser` загружает многострочные аргументы немного быстрее ([bpo-7113](https://python-all.ru/3.10/whatsnew/3.2.html) от Лукаша Ланги).17451746## Юникод17471748Python был обновлён до [Unicode 6.0.0](https://python-all.ru/3.10/whatsnew/3.2.html). Обновление стандарта добавляет более 2000 новых символов, включая [эмодзи](https://python-all.ru/3.10/whatsnew/3.2.html), которые важны для мобильных телефонов.17491750Кроме того, обновлённый стандарт изменил свойства символов для двух символов каннада (U+0CF1, U+0CF2) и одного числового символа New Tai Lue (U+19DA), сделав первые допустимыми для использования в идентификаторах, а последний – недопустимым. Подробнее см. [Unicode Character Database Changes](https://python-all.ru/3.10/whatsnew/3.2.html).17511752## Кодеки17531754Добавлена поддержка арабской DOS-кодировки *cp720* ([bpo-1616979](https://python-all.ru/3.10/whatsnew/3.2.html)).17551756Кодировка MBCS больше не игнорирует аргумент обработчика ошибок. В режиме строгой обработки по умолчанию она возбуждает [`UnicodeDecodeError`](https://python-all.ru/3.10/library/exceptions.html#UnicodeDecodeError) при обнаружении не декодируемой последовательности байтов и [`UnicodeEncodeError`](https://python-all.ru/3.10/library/exceptions.html#UnicodeEncodeError) для не кодируемого символа.17571758Кодек MBCS поддерживает обработчики ошибок `'strict'` и `'ignore'` для декодирования, и `'strict'` и `'replace'` для кодирования.17591760Для эмуляции кодировки MBCS Python 3.1 выберите обработчик `'ignore'` для декодирования и `'replace'` для кодирования.17611762На Mac OS X Python декодирует аргументы командной строки с помощью `'utf-8'`, а не кодировки локали.17631764По умолчанию [`tarfile`](https://python-all.ru/3.10/library/tarfile.html#module-tarfile) использует кодировку `'utf-8'` в Windows (вместо `'mbcs'`) и обработчик ошибок `'surrogateescape'` на всех операционных системах.17651766## Документация17671768Документация продолжает улучшаться.17691770- Таблица быстрых ссылок добавлена в начало длинных разделов, таких как [Встроенные функции](https://python-all.ru/3.10/library/functions.html#built-in-funcs). В случае с [`itertools`](https://python-all.ru/3.10/library/itertools.html#module-itertools) ссылки сопровождаются таблицами сводок в стиле шпаргалок, чтобы дать обзор и освежить память без необходимости читать всю документацию.1771- В некоторых случаях чистый исходный код на Python может быть полезным дополнением к документации, поэтому теперь многие модули имеют быстрые ссылки на последнюю версию исходного кода. Например, документация модуля [`functools`](https://python-all.ru/3.10/library/functools.html#module-functools) имеет быструю ссылку вверху с пометкой:17721773 > **Исходный код** [Lib/functools.py](https://python-all.ru/src/3.10/Lib/functools.py).17741775 (Автор: Raymond Hettinger; см. [обоснование](https://python-all.ru/3.10/whatsnew/3.2.html).)1776- Документация теперь содержит больше примеров и рецептов. В частности, в модуле [`re`](https://python-all.ru/3.10/library/re.html#module-re) есть обширный раздел [«Примеры регулярных выражений»](https://python-all.ru/3.10/library/re.html#re-examples). Точно так же модуль [`itertools`](https://python-all.ru/3.10/library/itertools.html#module-itertools) продолжает пополняться новыми [«Рецептами itertools»](https://python-all.ru/3.10/library/itertools.html#itertools-recipes).1777- Модуль [`datetime`](https://python-all.ru/3.10/library/datetime.html#module-datetime) теперь имеет вспомогательную реализацию на чистом Python. Функциональность не изменилась. Это просто предоставляет более читабельную альтернативную реализацию.17781779 (Автор: Alexander Belopolsky; [bpo-9528](https://python-all.ru/3.10/whatsnew/3.2.html).)1780- Необслуживаемый каталог `Demo` был удалён. Некоторые демонстрационные примеры были включены в документацию, некоторые перемещены в каталог `Tools/demo`, а остальные удалены полностью.17811782 (Автор: Georg Brandl; [bpo-7962](https://python-all.ru/3.10/whatsnew/3.2.html).)17831784## IDLE17851786- Меню «Формат» теперь содержит опцию для очистки исходных файлов путём удаления замыкающих пробелов.17871788 (Автор: Raymond Hettinger; [bpo-5150](https://python-all.ru/3.10/whatsnew/3.2.html).)1789- IDLE на Mac OS X теперь работает как с Carbon AquaTk, так и с Cocoa AquaTk.17901791 (Авторы: Kevin Walzer, Ned Deily и Ronald Oussoren; [bpo-6075](https://python-all.ru/3.10/whatsnew/3.2.html).)17921793## Репозиторий кода17941795В дополнение к существующему репозиторию Subversion по адресу [https://svn.python.org](https://python-all.ru/3.10/whatsnew/3.2.html) теперь доступен репозиторий [Mercurial](https://python-all.ru/3.10/whatsnew/3.2.html) по адресу [https://hg.python.org/](https://python-all.ru/3.10/whatsnew/3.2.html).17961797После выхода версии 3.2 планируется перейти на Mercurial в качестве основного репозитория. Эта распределённая система управления версиями должна упростить членам сообщества создание и обмен внешними наборами изменений. Подробнее см. [**PEP 385**](https://python-all.ru/3.10/whatsnew/3.2.html).17981799Чтобы научиться пользоваться новой системой управления версиями, см. [«Быстрый старт»](https://python-all.ru/3.10/whatsnew/3.2.html) или [«Руководство по рабочим процессам Mercurial»](https://python-all.ru/3.10/whatsnew/3.2.html).18001801## Изменения в сборке и C API18021803Изменения процесса сборки Python и C API включают:18041805- Сценарии *idle*, *pydoc* и *2to3* теперь устанавливаются с суффиксом, соответствующим версии, на `make altinstall` ([bpo-10679](https://python-all.ru/3.10/whatsnew/3.2.html)).1806- C-функции, обращающиеся к базе данных Unicode, теперь принимают и возвращают символы из всего диапазона Unicode, даже в сборках с узкими юникодными строками (Py\_UNICODE\_TOLOWER, Py\_UNICODE\_ISDECIMAL и другие). Видимое различие в Python заключается в том, что [`unicodedata.numeric()`](https://python-all.ru/3.10/library/unicodedata.html#unicodedata.numeric) теперь возвращает корректное значение для больших кодовых точек, а [`repr()`](https://python-all.ru/3.10/library/functions.html#repr) может считать больше символов печатаемыми.18071808 (Сообщил Bupjoe Lee, исправил Amaury Forgeot D’Arc; [bpo-5127](https://python-all.ru/3.10/whatsnew/3.2.html).)1809- Вычисляемые переходы (computed gotos) теперь включены по умолчанию на поддерживаемых компиляторах (которые обнаруживаются сценарием configure). Их по-прежнему можно выборочно отключить, указав `--without-computed-gotos`.18101811 (Автор: Antoine Pitrou; [bpo-9203](https://python-all.ru/3.10/whatsnew/3.2.html).)1812- Опция `--with-wctype-functions` была удалена. Встроенная база данных Unicode теперь используется для всех функций.18131814 (Автор: Amaury Forgeot D’Arc; [bpo-9210](https://python-all.ru/3.10/whatsnew/3.2.html).)1815- Хеш-значения теперь являются значениями нового типа, `Py_hash_t`, который определён как имеющий тот же размер, что и указатель. Ранее они были типа long, который на некоторых 64-битных операционных системах всё ещё имеет длину всего 32 бита. В результате этого исправления [`set`](https://python-all.ru/3.10/library/stdtypes.html#set) и [`dict`](https://python-all.ru/3.10/library/stdtypes.html#dict) теперь могут содержать более `2**32` записей в сборках с 64-битными указателями (ранее они могли вырасти до такого размера, но их производительность катастрофически падала).18161817 (Предложено Raymond Hettinger, реализовано Benjamin Peterson; [bpo-9778](https://python-all.ru/3.10/whatsnew/3.2.html).)1818- Новый макрос `Py_VA_COPY` копирует состояние списка аргументов переменной длины. Он эквивалентен *va\_copy* из C99, но доступен на всех платформах Python ([bpo-2443](https://python-all.ru/3.10/whatsnew/3.2.html)).1819- Новая функция C API [`PySys_SetArgvEx()`](https://python-all.ru/3.10/c-api/init.html#c.PySys_SetArgvEx) позволяет встроенному интерпретатору устанавливать [`sys.argv`](https://python-all.ru/3.10/library/sys.html#sys.argv) без изменения [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path) ([bpo-5753](https://python-all.ru/3.10/whatsnew/3.2.html)).1820- `PyEval_CallObject` теперь доступен только в форме макроса. Объявление функции, которое сохранялось по причинам обратной совместимости, теперь удалено – макрос был введён в 1997 году ([bpo-8276](https://python-all.ru/3.10/whatsnew/3.2.html)).1821- Появилась новая функция [`PyLong_AsLongLongAndOverflow()`](https://python-all.ru/3.10/c-api/long.html#c.PyLong_AsLongLongAndOverflow), которая аналогична [`PyLong_AsLongAndOverflow()`](https://python-all.ru/3.10/c-api/long.html#c.PyLong_AsLongAndOverflow). Обе служат для преобразования Python [`int`](https://python-all.ru/3.10/library/functions.html#int) в нативный тип фиксированной ширины, с обнаружением случаев, когда преобразование не помещается ([bpo-7767](https://python-all.ru/3.10/whatsnew/3.2.html)).1822- Функция [`PyUnicode_CompareWithASCIIString()`](https://python-all.ru/3.10/c-api/unicode.html#c.PyUnicode_CompareWithASCIIString) теперь возвращает *не равно*, если Python-строка завершается *NUL*.1823- Появилась новая функция [`PyErr_NewExceptionWithDoc()`](https://python-all.ru/3.10/c-api/exceptions.html#c.PyErr_NewExceptionWithDoc), которая подобна [`PyErr_NewException()`](https://python-all.ru/3.10/c-api/exceptions.html#c.PyErr_NewException), но позволяет указать строку документации. Это даёт исключениям на C те же возможности самодокументирования, что и их аналогам на чистом Python ([bpo-7033](https://python-all.ru/3.10/whatsnew/3.2.html)).1824- При компиляции с опцией `--with-valgrind` распределитель pymalloc будет автоматически отключаться при работе под Valgrind. Это обеспечивает улучшенное обнаружение утечек памяти при работе под Valgrind, сохраняя преимущества pymalloc в остальное время ([bpo-2422](https://python-all.ru/3.10/whatsnew/3.2.html)).1825- Удалён формат `O?` из функций *PyArg\_Parse*. Формат больше не используется и никогда не был документирован ([bpo-8837](https://python-all.ru/3.10/whatsnew/3.2.html)).18261827Был внесён ряд других небольших изменений в C-API. Полный список приведён в файле [Misc/NEWS](https://python-all.ru/3.10/whatsnew/3.2.html).18281829Кроме того, были обновлены сборочные файлы для Mac OS X; подробности см. в [Mac/BuildScript/README.txt](https://python-all.ru/3.10/whatsnew/3.2.html). Для пользователей, работающих в 32/64-разрядной сборке, существует известная проблема со стандартным Tcl/Tk в Mac OS X 10.6. Поэтому рекомендуется установить обновлённую альтернативу, например [ActiveState Tcl/Tk 8.5.9](https://python-all.ru/3.10/whatsnew/3.2.html). Дополнительные сведения доступны на странице [https://www.python.org/download/mac/tcltk/](https://python-all.ru/3.10/whatsnew/3.2.html).18301831## Переход на Python 3.218321833В этом разделе перечислены описанные ранее изменения и другие исправления ошибок, которые могут потребовать доработки вашего кода:18341835- Модуль [`configparser`](https://python-all.ru/3.10/library/configparser.html#module-configparser) претерпел ряд исправлений. Самое существенное изменение – замена старого класса `ConfigParser` на давно рекомендуемую альтернативу `SafeConfigParser`. Кроме того, имеется ряд более мелких несовместимостей:18361837 - Синтаксис интерполяции теперь проверяется при операциях [`get()`](https://python-all.ru/3.10/library/configparser.html#configparser.ConfigParser.get) и [`set()`](https://python-all.ru/3.10/library/configparser.html#configparser.ConfigParser.set). В схеме интерполяции по умолчанию допустимы только два токена с символом процента: `%(name)s` и `%%` (последний – экранированный знак процента).1838 - Методы [`set()`](https://python-all.ru/3.10/library/configparser.html#configparser.ConfigParser.set) и [`add_section()`](https://python-all.ru/3.10/library/configparser.html#configparser.ConfigParser.add_section) теперь проверяют, что значения являются строками. Раньше неподдерживаемые типы могли быть вставлены непреднамеренно.1839 - Повторяющиеся секции или параметры из одного источника теперь вызывают [`DuplicateSectionError`](https://python-all.ru/3.10/library/configparser.html#configparser.DuplicateSectionError) или [`DuplicateOptionError`](https://python-all.ru/3.10/library/configparser.html#configparser.DuplicateOptionError). Раньше дубликаты молча перезаписывали предыдущую запись.1840 - Встрочные комментарии теперь по умолчанию отключены, поэтому символ **;** теперь можно безопасно использовать в значениях.1841 - Комментарии теперь можно располагать с отступом. Следовательно, чтобы **;** или **#** оказались в начале строки в многострочных значениях, их нужно интерполировать. Это предотвращает ошибочную интерпретацию префиксных символов комментариев в значениях как комментариев.1842 - `""` теперь является допустимым значением и больше не преобразуется автоматически в пустую строку. Для пустых строк используйте `"option ="` в строке.1843- Модуль [`nntplib`](https://python-all.ru/3.10/library/nntplib.html#module-nntplib) был существенно переработан, поэтому его API часто несовместимы с API версии 3.1.1844- Объекты [`bytearray`](https://python-all.ru/3.10/library/stdtypes.html#bytearray) больше нельзя использовать в качестве имён файлов; вместо этого их следует преобразовывать в [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes).1845- `array.tostring()` и `array.fromstring()` переименованы в `array.tobytes()` и `array.frombytes()` для ясности. Старые названия признаны устаревшими. (См. [bpo-8990](https://python-all.ru/3.10/whatsnew/3.2.html).)1846- Функции `PyArg_Parse*()`:18471848 - Формат «t#» удалён: используйте «s#» или «s\*»1849 - Форматы «w» и «w#» удалены: используйте «w\*»1850- Тип `PyCObject`, объявленный устаревшим в 3.1, удалён. Для обёртывания непрозрачных C-указателей в объекты Python следует использовать API [`PyCapsule`](https://python-all.ru/3.10/c-api/capsule.html#c.PyCapsule); новый тип имеет чётко определённый интерфейс для передачи информации о типобезопасности и менее сложную сигнатуру вызова деструктора.1851- Функция `sys.setfilesystemencoding()` удалена, так как имела ошибочную архитектуру.1852- Функция и метод [`random.seed()`](https://python-all.ru/3.10/library/random.html#random.seed) теперь солят строковые начальные значения с помощью хеш-функции sha512. Чтобы получить доступ к предыдущей версии *seed* для воспроизведения последовательностей Python 3.1, установите аргумент *version* в *1*, `random.seed(s, version=1)`.1853- Ранее объявленная устаревшей функция `string.maketrans()` удалена в пользу статических методов [`bytes.maketrans()`](https://python-all.ru/3.10/library/stdtypes.html#bytes.maketrans) и [`bytearray.maketrans()`](https://python-all.ru/3.10/library/stdtypes.html#bytearray.maketrans). Это изменение устраняет путаницу с тем, какие типы поддерживаются модулем [`string`](https://python-all.ru/3.10/library/string.html#module-string). Теперь [`str`](https://python-all.ru/3.10/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) и [`bytearray`](https://python-all.ru/3.10/library/stdtypes.html#bytearray) имеют собственные методы **maketrans** и **translate** с промежуточными таблицами перевода соответствующего типа.18541855 (Предложено Georg Brandl; [bpo-5675](https://python-all.ru/3.10/whatsnew/3.2.html).)1856- Ранее объявленная устаревшей функция `contextlib.nested()` удалена в пользу обычного оператора [`with`](https://python-all.ru/3.10/reference/compound_stmts.html#with), который может принимать несколько менеджеров контекста. Последний способ быстрее (поскольку встроен) и лучше завершает несколько менеджеров контекста, если один из них вызывает исключение:18571858 ```python1859 with open('mylog.txt') as infile, open('a.out', 'w') as outfile:1860 for line in infile:1861 if '<critical>' in line:1862 outfile.write(line)1863 ```18641865 (Предложено Georg Brandl и Mattias Brändström; [appspot issue 53094](https://python-all.ru/3.10/whatsnew/3.2.html).)1866- [`struct.pack()`](https://python-all.ru/3.10/library/struct.html#struct.pack) теперь допускает только байты для кода упаковки строк `s`. Раньше он принимал текстовые аргументы и неявно кодировал их в байты через UTF-8. Это было проблематично, так как строило предположения о верной кодировке и потому что кодировка с переменной длиной может дать сбой при записи в сегмент структуры фиксированной длины.18671868 Код вида `struct.pack('<6sHHBBB', 'GIF87a', x, y)` следует переписать с использованием байтов вместо текста: `struct.pack('<6sHHBBB', b'GIF87a', x, y)`.18691870 (Обнаружено David Beazley, исправлено Victor Stinner; [bpo-10783](https://python-all.ru/3.10/whatsnew/3.2.html).)1871- Класс [`xml.etree.ElementTree`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) теперь вызывает [`xml.etree.ElementTree.ParseError`](https://python-all.ru/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.ParseError) при неудачном разборе. Ранее вызывалось [`xml.parsers.expat.ExpatError`](https://python-all.ru/3.10/library/pyexpat.html#xml.parsers.expat.ExpatError).1872- Новое, более длинное значение [`str()`](https://python-all.ru/3.10/library/stdtypes.html#str) для чисел с плавающей точкой может нарушить doctest-тесты, которые полагаются на старый формат вывода.1873- В [`subprocess.Popen`](https://python-all.ru/3.10/library/subprocess.html#subprocess.Popen) значение по умолчанию для *close\_fds* теперь равно `True` в Unix; в Windows оно равно `True`, если три стандартных потока установлены в `None`, и `False` в противном случае. Раньше *close\_fds* всегда было `False` по умолчанию, что приводило к трудноуловимым ошибкам или состояниям гонки, когда открытые файловые дескрипторы просачивались в дочерний процесс.1874- Поддержка устаревшего HTTP 0.9 удалена из [`urllib.request`](https://python-all.ru/3.10/library/urllib.request.html#module-urllib.request) и [`http.client`](https://python-all.ru/3.10/library/http.client.html#module-http.client). Такая поддержка по-прежнему присутствует на стороне сервера (в [`http.server`](https://python-all.ru/3.10/library/http.server.html#module-http.server)).18751876 (Предложено Antoine Pitrou, [bpo-10711](https://python-all.ru/3.10/whatsnew/3.2.html).)1877- SSL-сокеты в режиме тайм-аута теперь вызывают [`socket.timeout`](https://python-all.ru/3.10/library/socket.html#socket.timeout) при возникновении тайм-аута, а не общее [`SSLError`](https://python-all.ru/3.10/library/ssl.html#ssl.SSLError).18781879 (Автор: Антуан Питу, [bpo-10272](https://python-all.ru/3.10/whatsnew/3.2.html).)1880- Вводящие в заблуждение функции [`PyEval_AcquireLock()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_AcquireLock) и [`PyEval_ReleaseLock()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_ReleaseLock) официально устарели. Вместо них следует использовать API, учитывающие состояние потока (например, [`PyEval_SaveThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_SaveThread) и [`PyEval_RestoreThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_RestoreThread)).1881- Из соображений безопасности `asyncore.handle_accept()` объявлен устаревшим, и добавлена новая функция `asyncore.handle_accepted()` для его замены.18821883 (Автор: Джампаоло Родола, [bpo-6706](https://python-all.ru/3.10/whatsnew/3.2.html).)1884- Из-за новой реализации [GIL](https://python-all.ru/3.10/glossary.html#term-GIL) [`PyEval_InitThreads()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_InitThreads) больше нельзя вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).1885