3.2.md
1> **Источник:** https://python-all.ru/3.14/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.14/whatsnew/3.2.html) файлу.1415> **См. также**16>17> [**PEP 392**](https://python-all.ru/3.14/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.14/whatsnew/3.2.html) - Определение стабильного ABI**28>29> PEP написан Мартином фон Лёвисом.3031## PEP 389: Модуль разбора командной строки argparse3233Новый модуль для разбора командной строки, [`argparse`](https://python-all.ru/3.14/library/argparse.html#module-argparse), был представлен, чтобы преодолеть ограничения [`optparse`](https://python-all.ru/3.14/library/optparse.html#module-optparse), который не поддерживал позиционные аргументы (не только опции), подкоманды, обязательные опции и другие типовые паттерны задания и проверки опций.3435Этот модуль уже получил широкое распространение в сообществе как сторонний модуль. Будучи более функциональным, чем его предшественник, модуль [`argparse`](https://python-all.ru/3.14/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.14/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.14/whatsnew/3.2.html) - Новый модуль разбора командной строки**117>118> PEP написан Стивеном Бетардом.119>120> [Переход с optparse на argparse](https://python-all.ru/3.14/howto/argparse-optparse.html#upgrading-optparse-code) – подробнее о различиях с [`optparse`](https://python-all.ru/3.14/library/optparse.html#module-optparse).121122## PEP 391: Конфигурация логирования на основе словарей123124Модуль [`logging`](https://python-all.ru/3.14/library/logging.html#module-logging) предоставлял два вида конфигурации: один строится на вызовах функций для каждого параметра, другой – на внешнем файле в формате [`configparser`](https://python-all.ru/3.14/library/configparser.html#module-configparser). Эти варианты не давали гибкости для создания конфигураций из файлов JSON или YAML, а также не поддерживали инкрементальную настройку, необходимую для задания параметров логгера из командной строки.125126Для поддержки более гибкого подхода модуль теперь предлагает [`logging.config.dictConfig()`](https://python-all.ru/3.14/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.14/whatsnew/3.2.html) – Конфигурация логирования на основе словарей**164>165> PEP написан Винаем Саджипом.166167## PEP 3148: Модуль `concurrent.futures`168169Код для создания параллельного выполнения и управления им собирается в новом пространстве имён верхнего уровня *concurrent*. Первый его компонент – пакет *futures*, предоставляющий единый высокоуровневый интерфейс для управления потоками и процессами.170171Дизайн [`concurrent.futures`](https://python-all.ru/3.14/library/concurrent.futures.html#module-concurrent.futures) был вдохновлён пакетом *java.util.concurrent*. В этой модели выполняющийся вызов и его результат представлены объектом [`Future`](https://python-all.ru/3.14/library/concurrent.futures.html#concurrent.futures.Future), который абстрагирует общие для потоков, процессов и удалённых вызовов возможности. Этот объект поддерживает проверку состояния (выполняется или завершён), таймауты, отмены, добавление колбэков и доступ к результатам или исключениям.172173Основная часть нового модуля – два класса исполнителей для запуска и управления вызовами. Цель исполнителей – упростить использование существующих инструментов для параллельных вызовов. Они избавляют от необходимости настраивать пул ресурсов, запускать вызовы, создавать очередь результатов, добавлять обработку таймаутов и ограничивать общее количество потоков, процессов или удалённых вызовов.174175В идеале каждое приложение должно использовать один общий исполнитель для нескольких компонентов, чтобы ограничения на процессы и потоки управлялись централизованно. Это решает проблему проектирования, возникающую, когда у каждого компонента своя конкурирующая стратегия управления ресурсами.176177Оба класса имеют общий интерфейс с тремя методами: [`submit()`](https://python-all.ru/3.14/library/concurrent.futures.html#concurrent.futures.Executor.submit) для планирования вызываемого объекта и возврата объекта [`Future`](https://python-all.ru/3.14/library/concurrent.futures.html#concurrent.futures.Future); [`map()`](https://python-all.ru/3.14/library/concurrent.futures.html#concurrent.futures.Executor.map) для планирования нескольких асинхронных вызовов одновременно и [`shutdown()`](https://python-all.ru/3.14/library/concurrent.futures.html#concurrent.futures.Executor.shutdown) для освобождения ресурсов. Класс является [контекстным менеджером](https://python-all.ru/3.14/glossary.html#term-context-manager) и может использоваться в операторе [`with`](https://python-all.ru/3.14/reference/compound_stmts.html#with), чтобы гарантировать автоматическое освобождение ресурсов после завершения всех ожидающих future.178179Простой пример [`ThreadPoolExecutor`](https://python-all.ru/3.14/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.14/whatsnew/3.2.html) – Futures – асинхронное выполнение вычислений**193>194> PEP написан Брайаном Куинланом.195>196> [Код для параллельного чтения URL в потоках](https://python-all.ru/3.14/library/concurrent.futures.html#threadpoolexecutor-example) – пример использования потоков для параллельной загрузки нескольких веб-страниц.197>198> [Код для параллельного вычисления простых чисел](https://python-all.ru/3.14/library/concurrent.futures.html#processpoolexecutor-example) – пример, демонстрирующий [`ProcessPoolExecutor`](https://python-all.ru/3.14/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.14/reference/datamodel.html#module.__cached__), который хранит имя фактически импортированного файла:211212 ```python213 >>> import collections214 >>> collections.__cached__215 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'216 ```217- Уникальный для каждого интерпретатора тег доступен из модуля `imp`:218219 ```python220 >>> import imp221 >>> imp.get_tag()222 'cpython-32'223 ```224- Скрипты, пытающиеся определить имя исходного файла по импортированному файлу, теперь должны быть умнее. Просто удалить букву «c» из имени файла «.pyc» уже недостаточно. Вместо этого используйте новые функции из модуля `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.14/library/py_compile.html#module-py_compile) и [`compileall`](https://python-all.ru/3.14/library/compileall.html#module-compileall) были обновлены, чтобы отразить новое соглашение об именовании и целевой каталог. Вызов из командной строки *compileall* получил новые опции: `-i` для указания списка файлов и каталогов для компиляции и `-b`, которая заставляет записывать файлы байт-кода в их прежнее расположение, а не в *\_\_pycache\_\_*.233- Модуль [`importlib.abc`](https://python-all.ru/3.14/library/importlib.html#module-importlib.abc) обновлён новыми [абстрактными базовыми классами](https://python-all.ru/3.14/glossary.html#term-abstract-base-class) для загрузки файлов байт-кода. Устаревшие ABC, `PyLoader` и `PyPycLoader`, объявлены устаревшими (в документацию включены инструкции по сохранению совместимости с Python 3.1).234235> **См. также**236>237> **[**PEP 3147**](https://python-all.ru/3.14/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.14/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.14/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.14/library/stdtypes.html#str), хотя сам протокол HTTP ориентирован на байты.271272PEP различает так называемые *нативные строки*, используемые для заголовков и метаданных запросов/ответов, и *байтовые строки*, используемые для тел запросов и ответов.273274*Нативные строки* всегда имеют тип [`str`](https://python-all.ru/3.14/library/stdtypes.html#str), но ограничены кодовыми точками от *U+0000* до *U+00FF*, которые могут быть преобразованы в байты с использованием кодировки *Latin-1*. Эти строки используются для ключей и значений в словаре окружения, а также для заголовков и статусов ответов в функции `start_response()`. Они должны соответствовать [**RFC 2616**](https://python-all.ru/3.14/whatsnew/3.2.html) в отношении кодировки. То есть они должны быть либо символами *ISO-8859-1*, либо использовать кодировку MIME [**RFC 2047**](https://python-all.ru/3.14/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.14/library/wsgiref.html#module-wsgiref) появилась новая функция [`wsgiref.handlers.read_environ()`](https://python-all.ru/3.14/library/wsgiref.html#wsgiref.handlers.read_environ) для перекодирования CGI-переменных из [`os.environ`](https://python-all.ru/3.14/library/os.html#os.environ) в нативные строки и возврата нового словаря.283284> **См. также**285>286> **[**PEP 3333**](https://python-all.ru/3.14/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.14/library/functions.html#format) и [`str.format()`](https://python-all.ru/3.14/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.14/whatsnew/3.2.html).)304- Также появился новый метод [`str.format_map()`](https://python-all.ru/3.14/library/stdtypes.html#str.format_map), расширяющий возможности существующего метода [`str.format()`](https://python-all.ru/3.14/library/stdtypes.html#str.format) за счёт приёма произвольных [объектов-отображений](https://python-all.ru/3.14/glossary.html#term-mapping). Этот новый метод позволяет использовать форматирование строк с любыми словареподобными объектами Python, такими как [`defaultdict`](https://python-all.ru/3.14/library/collections.html#collections.defaultdict), [`Shelf`](https://python-all.ru/3.14/library/shelve.html#shelve.Shelf), [`ConfigParser`](https://python-all.ru/3.14/library/configparser.html#configparser.ConfigParser) или [`dbm`](https://python-all.ru/3.14/library/dbm.html#module-dbm). Он также полезен с пользовательскими подклассами [`dict`](https://python-all.ru/3.14/library/stdtypes.html#dict), которые нормализуют ключи перед поиском или предоставляют метод [`__missing__()`](https://python-all.ru/3.14/reference/datamodel.html#object.__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 ...316 >>> lcd = LowerCasedDict(part='widgets', quantity=10)317 >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd)318 'There are 10 widgets in stock'319320 >>> class PlaceholderDict(dict):321 ... def __missing__(self, key):322 ... return '<{}>'.format(key)323 ...324 >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict())325 'Hello <name>, welcome to <location>'326 ```327328> (Предложено Рэймондом Хеттингером и реализовано Эриком Смитом в [bpo-6081](https://python-all.ru/3.14/whatsnew/3.2.html).)329330- Интерпретатор теперь можно запускать с тихим режимом, опцией `-q`, чтобы предотвратить отображение информации об авторских правах и версии в интерактивном режиме. Состояние опции можно проверить через атрибут [`sys.flags`](https://python-all.ru/3.14/library/sys.html#sys.flags):331332 ```console333 $ python -q334 >>> sys.flags335 sys.flags(debug=0, division_warning=0, inspect=0, interactive=0,336 optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0,337 ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)338 ```339340 (Предложено Марчином Войдыром в [bpo-1772833](https://python-all.ru/3.14/whatsnew/3.2.html)).341- Функция [`hasattr()`](https://python-all.ru/3.14/library/functions.html#hasattr) работает, вызывая [`getattr()`](https://python-all.ru/3.14/library/functions.html#getattr) и определяя, было ли возбуждено исключение. Эта техника позволяет ей обнаруживать методы, созданные динамически с помощью [`__getattr__()`](https://python-all.ru/3.14/reference/datamodel.html#object.__getattr__) или [`__getattribute__()`](https://python-all.ru/3.14/reference/datamodel.html#object.__getattribute__), которые иначе отсутствовали бы в словаре класса. Раньше *hasattr* перехватывал любые исключения, что могло маскировать настоящие ошибки. Теперь *hasattr* был ужесточён и перехватывает только [`AttributeError`](https://python-all.ru/3.14/library/exceptions.html#AttributeError), пропуская другие исключения:342343 ```python344 >>> class A:345 ... @property346 ... def f(self):347 ... return 1 // 0348 ...349 >>> a = A()350 >>> hasattr(a, 'f')351 Traceback (most recent call last):352 ...353 ZeroDivisionError: integer division or modulo by zero354 ```355356 (Обнаружено Юрием Селивановым и исправлено Бенджамином Петерсоном; [bpo-9666](https://python-all.ru/3.14/whatsnew/3.2.html).)357- [`str()`](https://python-all.ru/3.14/library/stdtypes.html#str) числа с плавающей точкой или комплексного числа теперь совпадает с его [`repr()`](https://python-all.ru/3.14/library/functions.html#repr). Ранее форма `str()` была короче, но это лишь вызывало путаницу, и теперь в ней больше нет необходимости, поскольку по умолчанию отображается самая короткая возможная `repr()`:358359 ```python360 >>> import math361 >>> repr(math.pi)362 '3.141592653589793'363 >>> str(math.pi)364 '3.141592653589793'365 ```366367 (Предложено и реализовано Марком Дикинсоном; [bpo-9337](https://python-all.ru/3.14/whatsnew/3.2.html).)368- Объекты [`memoryview`](https://python-all.ru/3.14/library/stdtypes.html#memoryview) теперь имеют метод [`release()`](https://python-all.ru/3.14/library/stdtypes.html#memoryview.release), а также поддерживают протокол менеджера контекста. Это позволяет своевременно освобождать любые ресурсы, которые были получены при запросе буфера от исходного объекта.369370 ```python371 >>> with memoryview(b'abcdefgh') as v:372 ... print(v.tolist())373 [97, 98, 99, 100, 101, 102, 103, 104]374 ```375376 (Добавлено Антуаном Питру; [bpo-9757](https://python-all.ru/3.14/whatsnew/3.2.html).)377- Ранее было запрещено удалять имя из локального пространства имён, если оно встречается как свободная переменная во вложенном блоке:378379 ```python380 def outer(x):381 def inner():382 return x383 inner()384 del x385 ```386387 Теперь это разрешено. Помните, что цель (target) в предложении [`except`](https://python-all.ru/3.14/reference/compound_stmts.html#except) очищается, поэтому этот код, который работал в Python 2.6, вызывал [`SyntaxError`](https://python-all.ru/3.14/library/exceptions.html#SyntaxError) в Python 3.1, а теперь снова работает:388389 ```python390 def f():391 def print_error():392 print(e)393 try:394 something395 except Exception as e:396 print_error()397 # неявное "del e" здесь398 ```399400 (См. [bpo-4617](https://python-all.ru/3.14/whatsnew/3.2.html).)401- [Типы структурных последовательностей](https://python-all.ru/3.14/c-api/tuple.html#struct-sequence-objects) теперь являются подклассами кортежа. Это означает, что C-структуры, такие как возвращаемые [`os.stat()`](https://python-all.ru/3.14/library/os.html#os.stat), [`time.gmtime()`](https://python-all.ru/3.14/library/time.html#time.gmtime) и [`sys.version_info`](https://python-all.ru/3.14/library/sys.html#sys.version_info), теперь работают как [именованный кортеж](https://python-all.ru/3.14/glossary.html#term-named-tuple) и могут использоваться с функциями и методами, ожидающими кортеж в качестве аргумента. Это большой шаг вперёд в придании C-структурам такой же гибкости, как у их аналогов на чистом Python:402403 ```python404 >>> import sys405 >>> isinstance(sys.version_info, tuple)406 True407 >>> 'Version %d.%d.%d %s(%d)' % sys.version_info408 'Version 3.2.0 final(0)'409 ```410411 (Предложено Arfrever Frehtes Taifersar Arahesis и реализовано Benjamin Peterson в [bpo-8413](https://python-all.ru/3.14/whatsnew/3.2.html).)412- Теперь предупреждениями проще управлять с помощью переменной окружения [`PYTHONWARNINGS`](https://python-all.ru/3.14/using/cmdline.html#envvar-PYTHONWARNINGS) в качестве альтернативы использованию `-W` в командной строке:413414 ```console415 $ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'416 ```417418 (Предложено Barry Warsaw и реализовано Philip Jenvey в [bpo-7301](https://python-all.ru/3.14/whatsnew/3.2.html).)419- Добавлена новая категория предупреждений [`ResourceWarning`](https://python-all.ru/3.14/library/exceptions.html#ResourceWarning). Она выдаётся при обнаружении потенциальных проблем с потреблением ресурсов или очисткой. По умолчанию она отключена в обычных сборках, но её можно включить средствами модуля [`warnings`](https://python-all.ru/3.14/library/warnings.html#module-warnings) или в командной строке.420421 При завершении интерпретатора выдаётся [`ResourceWarning`](https://python-all.ru/3.14/library/exceptions.html#ResourceWarning), если список [`gc.garbage`](https://python-all.ru/3.14/library/gc.html#gc.garbage) не пуст, и если установлен [`gc.DEBUG_UNCOLLECTABLE`](https://python-all.ru/3.14/library/gc.html#gc.DEBUG_UNCOLLECTABLE), то печатаются все несобираемые объекты. Это сделано для того, чтобы программист знал, что его код содержит проблемы с финализацией объектов.422423 [`ResourceWarning`](https://python-all.ru/3.14/library/exceptions.html#ResourceWarning) также выдаётся, когда [объект файла](https://python-all.ru/3.14/glossary.html#term-file-object) уничтожается без явного закрытия. Хотя деаллокатор такого объекта гарантирует закрытие нижележащего ресурса операционной системы (обычно файлового дескриптора), задержка с деаллокацией объекта может вызывать различные проблемы, особенно в Windows. Вот пример включения предупреждения из командной строки:424425 ```console426 $ python -q -Wdefault427 >>> f = open("foo", "wb")428 >>> del f429 __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>430 ```431432 (Добавлено Antoine Pitrou и Georg Brandl в [bpo-10093](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-477863](https://python-all.ru/3.14/whatsnew/3.2.html).)433- Объекты [`range`](https://python-all.ru/3.14/library/stdtypes.html#range) теперь поддерживают методы *index* и *count*. Это часть усилий по расширению реализации [`collections.Sequence`](https://python-all.ru/3.14/library/collections.abc.html#collections.abc.Sequence) [абстрактного базового класса](https://python-all.ru/3.14/glossary.html#term-abstract-base-class) на большее количество объектов. В результате язык получит более единообразный API. Кроме того, объекты `range` теперь поддерживают срезы и отрицательные индексы, даже со значениями, превышающими [`sys.maxsize`](https://python-all.ru/3.14/library/sys.html#sys.maxsize). Это делает *range* более совместимым со списками:434435 ```python436 >>> range(0, 100, 2).count(10)437 1438 >>> range(0, 100, 2).index(10)439 5440 >>> range(0, 100, 2)[5]441 10442 >>> range(0, 100, 2)[0:5]443 range(0, 10, 2)444 ```445446 (Вклад Daniel Stutzbach в [bpo-9213](https://python-all.ru/3.14/whatsnew/3.2.html), Alexander Belopolsky в [bpo-2690](https://python-all.ru/3.14/whatsnew/3.2.html) и Nick Coghlan в [bpo-10889](https://python-all.ru/3.14/whatsnew/3.2.html).)447- Встроенная функция [`callable()`](https://python-all.ru/3.14/library/functions.html#callable) из Py2.x была восстановлена. Она предоставляет краткую и читаемую альтернативу использованию [абстрактного базового класса](https://python-all.ru/3.14/glossary.html#term-abstract-base-class) в выражении вида `isinstance(x, collections.Callable)`:448449 ```python450 >>> callable(max)451 True452 >>> callable(20)453 False454 ```455456 (См. [bpo-10518](https://python-all.ru/3.14/whatsnew/3.2.html).)457- Механизм импорта Python теперь может загружать модули, установленные в каталогах, в именах путей которых есть не-ASCII символы. Это решило давнюю проблему с домашними каталогами пользователей, имеющих не-ASCII символы в именах.458459> (Потребовало значительной работы от Victor Stinner в [bpo-9425](https://python-all.ru/3.14/whatsnew/3.2.html).)460461## Новые, улучшенные и устаревшие модули462463Стандартная библиотека Python прошла значительную работу по сопровождению и улучшению качества.464465Самая важная новость для Python 3.2: пакет [`email`](https://python-all.ru/3.14/library/email.html#module-email), модуль [`mailbox`](https://python-all.ru/3.14/library/mailbox.html#module-mailbox) и модули `nntplib` теперь корректно работают с моделью байты/текст в Python 3. Впервые правильно обрабатываются сообщения со смешанными кодировками.466467По всей стандартной библиотеке уделено больше внимания вопросам кодировок и различиям между текстом и байтами. В частности, взаимодействие с операционной системой теперь лучше обменивается не-ASCII данными, используя кодировку Windows MBCS, локаль-зависимые кодировки или UTF-8.468469Ещё одно важное достижение – добавление значительно улучшенной поддержки *SSL*-соединений и сертификатов безопасности.470471Кроме того, больше классов теперь реализуют [менеджер контекста](https://python-all.ru/3.14/glossary.html#term-context-manager) для удобной и надёжной очистки ресурсов с помощью оператора [`with`](https://python-all.ru/3.14/reference/compound_stmts.html#with).472473### email474475Пригодность к использованию пакета [`email`](https://python-all.ru/3.14/library/email.html#module-email) в Python 3 в значительной степени исправлена благодаря масштабной работе R. David Murray. Проблема заключалась в том, что электронные письма обычно читаются и хранятся в виде [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes), а не [`str`](https://python-all.ru/3.14/library/stdtypes.html#str) текста, и могут содержать несколько кодировок в одном письме. Поэтому пакет email пришлось расширить, чтобы разбирать и создавать сообщения в формате байтов.476477- Новые функции [`message_from_bytes()`](https://python-all.ru/3.14/library/email.parser.html#email.message_from_bytes) и [`message_from_binary_file()`](https://python-all.ru/3.14/library/email.parser.html#email.message_from_binary_file), а также новые классы [`BytesFeedParser`](https://python-all.ru/3.14/library/email.parser.html#email.parser.BytesFeedParser) и [`BytesParser`](https://python-all.ru/3.14/library/email.parser.html#email.parser.BytesParser) позволяют разбирать двоичные данные сообщений в объекты модели.478- Если на вход модели подаются байты, [`get_payload()`](https://python-all.ru/3.14/library/email.compat32-message.html#email.message.Message.get_payload) по умолчанию декодирует тело сообщения с *Content-Transfer-Encoding*, равным *8bit*, используя кодировку, указанную в MIME-заголовках, и возвращает результирующую строку.479- Если на вход модели подаются байты, [`Generator`](https://python-all.ru/3.14/library/email.generator.html#email.generator.Generator) преобразует тела сообщений, имеющие *Content-Transfer-Encoding* со значением *8bit*, в тела с *7bit* *Content-Transfer-Encoding*.480481 Заголовки с незакодированными не-ASCII байтами считаются закодированными по [**RFC 2047**](https://python-all.ru/3.14/whatsnew/3.2.html) с использованием набора символов *unknown-8bit*.482- Новый класс [`BytesGenerator`](https://python-all.ru/3.14/library/email.generator.html#email.generator.BytesGenerator) выводит байты, сохраняя любые неизменённые не-ASCII данные, которые присутствовали во входных данных, использованных для построения модели, включая тела сообщений с *Content-Transfer-Encoding* равным *8bit*.483- Класс [`smtplib`](https://python-all.ru/3.14/library/smtplib.html#module-smtplib) [`SMTP`](https://python-all.ru/3.14/library/smtplib.html#smtplib.SMTP) теперь принимает байтовую строку для аргумента *msg* метода [`sendmail()`](https://python-all.ru/3.14/library/smtplib.html#smtplib.SMTP.sendmail), а новый метод [`send_message()`](https://python-all.ru/3.14/library/smtplib.html#smtplib.SMTP.send_message) принимает объект [`Message`](https://python-all.ru/3.14/library/email.compat32-message.html#email.message.Message) и может опционально получать адреса *from\_addr* и *to\_addrs* непосредственно из объекта.484485(Предложено и реализовано R. David Murray, [bpo-4661](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-10321](https://python-all.ru/3.14/whatsnew/3.2.html).)486487### elementtree488489Пакет [`xml.etree.ElementTree`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) и его аналог `xml.etree.cElementTree` обновлены до версии 1.3.490491Добавлено несколько новых полезных функций и методов:492493- [`xml.etree.ElementTree.fromstringlist()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.fromstringlist) – строит XML-документ из последовательности фрагментов494- [`xml.etree.ElementTree.register_namespace()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.register_namespace) – для регистрации глобального префикса пространства имён495- [`xml.etree.ElementTree.tostringlist()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.tostringlist) для строкового представления, включая все подсписки496- [`xml.etree.ElementTree.Element.extend()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.extend) для добавления последовательности из нуля или более элементов497- [`xml.etree.ElementTree.Element.iterfind()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.iterfind) ищет элемент и подэлементы498- [`xml.etree.ElementTree.Element.itertext()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.itertext) создаёт текстовый итератор по элементу и его подэлементам499- [`xml.etree.ElementTree.TreeBuilder.end()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder.end) закрывает текущий элемент500- [`xml.etree.ElementTree.TreeBuilder.doctype()`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder.doctype) обрабатывает объявление doctype501502Два метода устарели:503504- `xml.etree.ElementTree.getchildren()` используйте `list(elem)`.505- `xml.etree.ElementTree.getiterator()` используйте `Element.iter`.506507Подробнее об обновлении см. [Introducing ElementTree](https://python-all.ru/3.14/whatsnew/3.2.html) на сайте Фредрика Лунда.508509(Авторы: Florent Xicluna и Fredrik Lundh, [bpo-6472](https://python-all.ru/3.14/whatsnew/3.2.html).)510511### functools512513- Модуль [`functools`](https://python-all.ru/3.14/library/functools.html#module-functools) включает новый декоратор для кеширования вызовов функций. [`functools.lru_cache()`](https://python-all.ru/3.14/library/functools.html#functools.lru_cache) позволяет избежать повторных запросов к внешнему ресурсу, когда результаты предположительно одинаковы.514515 Например, добавление декоратора кеширования к функции запроса к базе данных может сократить количество обращений к базе данных для популярных поисковых запросов:516517 ```python518 >>> import functools519 >>> @functools.lru_cache(maxsize=300)520 ... def get_phone_number(name):521 ... c = conn.cursor()522 ... c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))523 ... return c.fetchone()[0]524 ```525526 ```python527 >>> for name in user_requests:528 ... get_phone_number(name) # кэшированный поиск529 ```530531 Чтобы помочь с выбором эффективного размера кеша, обёрнутая функция оснащается средствами отслеживания статистики кеша:532533 ```python534 >>> get_phone_number.cache_info()535 CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)536 ```537538 Если таблица phonelist обновляется, устаревшее содержимое кеша можно очистить с помощью:539540 ```python541 >>> get_phone_number.cache_clear()542 ```543544 (Автор: Raymond Hettinger с использованием идей дизайна от Jim Baker, Miki Tebeka и Nick Coghlan; см. [recipe 498245](https://python-all.ru/3.14/whatsnew/3.2.html), [recipe 577479](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-10586](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-10593](https://python-all.ru/3.14/whatsnew/3.2.html).)545- Декоратор [`functools.wraps()`](https://python-all.ru/3.14/library/functools.html#functools.wraps) теперь добавляет атрибут `__wrapped__`, указывающий на исходную вызываемую функцию. Это позволяет проводить интроспекцию обёрнутых функций. Он также копирует [`__annotations__`](https://python-all.ru/3.14/reference/datamodel.html#function.__annotations__), если он определён. Кроме того, он корректно пропускает отсутствующие атрибуты, такие как [`__doc__`](https://python-all.ru/3.14/reference/datamodel.html#function.__doc__), которые могут не быть определены для обёрнутого вызываемого объекта.546547 В приведённом выше примере кеш можно удалить, восстановив исходную функцию:548549 ```python550 >>> get_phone_number = get_phone_number.__wrapped__ # некэшированная функция551 ```552553 (Авторы: Nick Coghlan и Terrence Cole; [bpo-9567](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-3445](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-8814](https://python-all.ru/3.14/whatsnew/3.2.html).)554- Чтобы упростить написание классов с методами полного сравнения, новый декоратор [`functools.total_ordering()`](https://python-all.ru/3.14/library/functools.html#functools.total_ordering) будет использовать существующие методы равенства и неравенства для заполнения остальных методов.555556 Например, указав *\_\_eq\_\_* и *\_\_lt\_\_*, можно позволить [`total_ordering()`](https://python-all.ru/3.14/library/functools.html#functools.total_ordering) заполнить *\_\_le\_\_*, *\_\_gt\_\_* и *\_\_ge\_\_*:557558 ```python559 @total_ordering560 class Student:561 def __eq__(self, other):562 return ((self.lastname.lower(), self.firstname.lower()) ==563 (other.lastname.lower(), other.firstname.lower()))564565 def __lt__(self, other):566 return ((self.lastname.lower(), self.firstname.lower()) <567 (other.lastname.lower(), other.firstname.lower()))568 ```569570 С помощью декоратора *total\_ordering* остальные методы сравнения заполняются автоматически.571572 (Автор: Raymond Hettinger.)573- Чтобы облегчить перенос программ с Python 2, функция [`functools.cmp_to_key()`](https://python-all.ru/3.14/library/functools.html#functools.cmp_to_key) преобразует устаревшую функцию сравнения в современную [функцию ключа](https://python-all.ru/3.14/glossary.html#term-key-function):574575 ```python576 >>> # порядок сортировки с учётом локали577 >>> sorted(iterable, key=cmp_to_key(locale.strcoll))578 ```579580 Примеры сортировки и краткое руководство по сортировке см. в руководстве [Sorting HowTo](https://python-all.ru/3.14/whatsnew/3.2.html).581582 (Автор: Raymond Hettinger.)583584### itertools585586- Модуль [`itertools`](https://python-all.ru/3.14/library/itertools.html#module-itertools) содержит новую функцию [`accumulate()`](https://python-all.ru/3.14/library/itertools.html#itertools.accumulate), созданную по образцу оператора *scan* из APL и функции *accumulate* из Numpy:587588 ```python589 >>> from itertools import accumulate590 >>> list(accumulate([8, 2, 50]))591 [8, 10, 60]592 ```593594 ```python595 >>> prob_dist = [0.1, 0.4, 0.2, 0.3]596 >>> list(accumulate(prob_dist)) # кумулятивное распределение вероятностей597 [0.1, 0.5, 0.7, 1.0]598 ```599600 Пример использования [`accumulate()`](https://python-all.ru/3.14/library/itertools.html#itertools.accumulate) см. в [примерах для модуля random](https://python-all.ru/3.14/library/random.html#random-examples).601602 (Автор: Raymond Hettinger с учётом предложений по дизайну от Mark Dickinson.)603604### collections605606- Класс [`collections.Counter`](https://python-all.ru/3.14/library/collections.html#collections.Counter) теперь имеет две формы вычитания на месте: существующий оператор *-=* для [насыщающего вычитания](https://python-all.ru/3.14/whatsnew/3.2.html) и новый метод [`subtract()`](https://python-all.ru/3.14/library/collections.html#collections.Counter.subtract) для обычного вычитания. Первый подходит для [мультимножеств](https://python-all.ru/3.14/whatsnew/3.2.html), которые имеют только положительные счётчики, а второй больше подходит для случаев, допускающих отрицательные счётчики:607608 ```python609 >>> from collections import Counter610 >>> tally = Counter(dogs=5, cats=3)611 >>> tally -= Counter(dogs=2, cats=8) # насыщающее вычитание612 >>> tally613 Counter({'dogs': 3})614 ```615616 ```python617 >>> tally = Counter(dogs=5, cats=3)618 >>> tally.subtract(dogs=2, cats=8) # обычное вычитание619 >>> tally620 Counter({'dogs': 3, 'cats': -5})621 ```622623 (Автор: Raymond Hettinger.)624- Класс [`collections.OrderedDict`](https://python-all.ru/3.14/library/collections.html#collections.OrderedDict) имеет новый метод [`move_to_end()`](https://python-all.ru/3.14/library/collections.html#collections.OrderedDict.move_to_end), который принимает существующий ключ и перемещает его либо в первую, либо в последнюю позицию упорядоченной последовательности.625626 По умолчанию элемент перемещается на последнюю позицию. Это эквивалентно обновлению записи с помощью `od[k] = od.pop(k)`.627628 Быстрая операция перемещения в конец полезна для изменения порядка следования записей. Например, упорядоченный словарь можно использовать для отслеживания порядка доступа, упорядочивая записи от самых старых к самым недавно запрошенным.629630 ```python631 >>> from collections import OrderedDict632 >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e'])633 >>> list(d)634 ['a', 'b', 'X', 'd', 'e']635 >>> d.move_to_end('X')636 >>> list(d)637 ['a', 'b', 'd', 'e', 'X']638 ```639640 (Автор: Raymond Hettinger.)641- У класса [`collections.deque`](https://python-all.ru/3.14/library/collections.html#collections.deque) появилось два новых метода – [`count()`](https://python-all.ru/3.14/library/collections.html#collections.deque.count) и [`reverse()`](https://python-all.ru/3.14/library/collections.html#collections.deque.reverse), которые делают его более взаимозаменяемым с объектами [`list`](https://python-all.ru/3.14/library/stdtypes.html#list):642643 ```python644 >>> from collections import deque645 >>> d = deque('simsalabim')646 >>> d.count('s')647 2648 >>> d.reverse()649 >>> d650 deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])651 ```652653 (Автор: Raymond Hettinger.)654655### threading656657В модуле [`threading`](https://python-all.ru/3.14/library/threading.html#module-threading) появился новый класс синхронизации [`Barrier`](https://python-all.ru/3.14/library/threading.html#threading.Barrier), который заставляет несколько потоков ждать, пока все они не достигнут общей точки барьера. Барьеры полезны для обеспечения того, чтобы задача с несколькими предусловиями не выполнялась до завершения всех предшествующих задач.658659Барьеры могут работать с произвольным числом потоков. Это обобщение механизма [рандеву](https://python-all.ru/3.14/whatsnew/3.2.html), который определён только для двух потоков.660661Реализованный как двухфазный циклический барьер, объект [`Barrier`](https://python-all.ru/3.14/library/threading.html#threading.Barrier) подходит для использования в циклах. Отдельные фазы *заполнения* и *опустошения* гарантируют, что все потоки будут освобождены (опустошены) прежде, чем какой-либо из них сможет вернуться назад и снова войти в барьер. Барьер полностью сбрасывается после каждого цикла.662663Пример использования барьеров:664665```python666from threading import Barrier, Thread667668def get_votes(site):669 ballots = conduct_election(site)670 all_polls_closed.wait() # не подсчитывать, пока все голосования не закрыты671 totals = summarize(ballots)672 publish(site, totals)673674all_polls_closed = Barrier(len(sites))675for site in sites:676 Thread(target=get_votes, args=(site,)).start()677```678679В этом примере барьер обеспечивает соблюдение правила, согласно которому голоса не могут быть подсчитаны на любом избирательном участке, пока все участки не закроются. Обратите внимание, что решение с барьером похоже на решение с [`threading.Thread.join()`](https://python-all.ru/3.14/library/threading.html#threading.Thread.join), но после пересечения точки барьера потоки остаются живыми и продолжают работать (подсчитывать бюллетени).680681Если какая-либо из предшествующих задач может зависнуть или задержаться, барьер можно создать с необязательным параметром *тайм-аут*. Тогда, если период ожидания истекает до того, как все предшествующие задачи достигнут точки барьера, все ожидающие потоки освобождаются и возбуждается исключение [`BrokenBarrierError`](https://python-all.ru/3.14/library/threading.html#threading.BrokenBarrierError):682683```python684def get_votes(site):685 ballots = conduct_election(site)686 try:687 all_polls_closed.wait(timeout=midnight - time.now())688 except BrokenBarrierError:689 lockbox = seal_ballots(ballots)690 queue.put(lockbox)691 else:692 totals = summarize(ballots)693 publish(site, totals)694```695696В этом примере барьер обеспечивает более надежное правило. Если некоторые избирательные участки не заканчивают работу до полуночи, барьер срабатывает по тайм-ауту, и бюллетени опечатываются и помещаются в очередь для последующей обработки.697698Смотрите [Barrier Synchronization Patterns](https://python-all.ru/3.14/whatsnew/3.2.html) для получения дополнительных примеров использования барьеров в параллельных вычислениях. Также простое, но подробное объяснение барьеров даётся в [The Little Book of Semaphores](https://python-all.ru/3.14/whatsnew/3.2.html), *раздел 3.6*.699700(Автор: Kristján Valur Jónsson, рецензирование API: Jeffrey Yasskin, в [bpo-8777](https://python-all.ru/3.14/whatsnew/3.2.html).)701702### datetime and time703704- В модуле [`datetime`](https://python-all.ru/3.14/library/datetime.html#module-datetime) появился новый тип [`timezone`](https://python-all.ru/3.14/library/datetime.html#datetime.timezone), который реализует интерфейс [`tzinfo`](https://python-all.ru/3.14/library/datetime.html#datetime.tzinfo), возвращая фиксированное смещение UTC и название часового пояса. Это упрощает создание объектов datetime с учётом часового пояса:705706 ```python707 >>> import datetime as dt708709 >>> dt.datetime.now(dt.timezone.utc)710 datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)711712 >>> dt.datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")713 datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)714 ```715- Кроме того, объекты [`timedelta`](https://python-all.ru/3.14/library/datetime.html#datetime.timedelta) теперь можно умножать на [`float`](https://python-all.ru/3.14/library/functions.html#float) и делить на `float` и [`int`](https://python-all.ru/3.14/library/functions.html#int). А объекты `timedelta` теперь можно делить друг на друга.716- Метод [`datetime.date.strftime()`](https://python-all.ru/3.14/library/datetime.html#datetime.date.strftime) больше не ограничен годами после 1900. Новый поддерживаемый диапазон лет – от 1000 до 9999 включительно.717- Всякий раз, когда в кортеже времени используется двузначный год, его интерпретация определяется `time.accept2dyear`. По умолчанию используется `True`, что означает, что для двузначного года век определяется по правилам POSIX, регламентирующим формат `%y` strptime.718719 Начиная с Py3.2, использование эвристики угадывания века будет вызывать предупреждение [`DeprecationWarning`](https://python-all.ru/3.14/library/exceptions.html#DeprecationWarning). Вместо этого рекомендуется установить `time.accept2dyear` в `False`, чтобы можно было использовать большие диапазоны дат без угадывания:720721 ```python722 >>> import time, warnings723 >>> warnings.resetwarnings() # удалить фильтры предупреждений по умолчанию724725 >>> time.accept2dyear = True # угадать, означает ли 11 число 11 или 2011726 >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))727 Warning (from warnings module):728 ...729 DeprecationWarning: Century info guessed for a 2-digit year.730 'Fri Jan 1 12:34:56 2011'731732 >>> time.accept2dyear = False # использовать полный диапазон допустимых дат733 >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))734 'Fri Jan 1 12:34:56 11'735 ```736737 Несколько функций теперь имеют значительно расширенные диапазоны дат. Когда `time.accept2dyear` имеет значение false, функция [`time.asctime()`](https://python-all.ru/3.14/library/time.html#time.asctime) принимает любой год, помещающийся в int в C, а функции [`time.mktime()`](https://python-all.ru/3.14/library/time.html#time.mktime) и [`time.strftime()`](https://python-all.ru/3.14/library/time.html#time.strftime) принимают полный диапазон, поддерживаемый соответствующими функциями операционной системы.738739(Авторы: Alexander Belopolsky и Victor Stinner в [bpo-1289118](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-5094](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-6641](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-2706](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-1777412](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-8013](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-10827](https://python-all.ru/3.14/whatsnew/3.2.html).)740741### math742743Модуль [`math`](https://python-all.ru/3.14/library/math.html#module-math) обновлён и содержит шесть новых функций, вдохновлённых стандартом C99.744745Функция [`isfinite()`](https://python-all.ru/3.14/library/math.html#math.isfinite) предоставляет надёжный и быстрый способ обнаружения особых значений. Она возвращает `True` для обычных чисел и `False` для *NaN* или *бесконечность*:746747```python748>>> from math import isfinite749>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]750[True, True, False, False]751```752753Функция [`expm1()`](https://python-all.ru/3.14/library/math.html#math.expm1) вычисляет `e**x-1` для малых значений *x* без потери точности, которая обычно сопутствует вычитанию почти равных величин:754755```python756>>> from math import expm1757>>> expm1(0.013671875) # более точный способ вычисления e**x-1 для малых x7580.013765762467652909759```760761Функция [`erf()`](https://python-all.ru/3.14/library/math.html#math.erf) вычисляет интеграл вероятности или [функцию ошибок Гаусса](https://python-all.ru/3.14/whatsnew/3.2.html). Дополнительная функция ошибок, [`erfc()`](https://python-all.ru/3.14/library/math.html#math.erfc), равна `1 - erf(x)`:762763```pycon764>>> from math import erf, erfc, sqrt765>>> erf(1.0/sqrt(2.0)) # доля нормального распределения в пределах одного стандартного отклонения7660.682689492137086767>>> erfc(1.0/sqrt(2.0)) # доля нормального распределения за пределами одного стандартного отклонения7680.31731050786291404769>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))7701.0771```772773Функция [`gamma()`](https://python-all.ru/3.14/library/math.html#math.gamma) является непрерывным расширением функции факториала. Подробнее см. [https://en.wikipedia.org/wiki/Gamma\_function](https://python-all.ru/3.14/whatsnew/3.2.html). Поскольку эта функция связана с факториалами, она быстро растёт даже при малых значениях *x*, поэтому существует также функция [`lgamma()`](https://python-all.ru/3.14/library/math.html#math.lgamma) для вычисления натурального логарифма гамма-функции:774775```python776>>> from math import gamma, lgamma777>>> gamma(7.0) # шесть факториал778720.0779>>> lgamma(801.0) # логарифм факториала 8007804551.950730698041781```782783(Автор: Mark Dickinson.)784785### abc786787Модуль [`abc`](https://python-all.ru/3.14/library/abc.html#module-abc) теперь поддерживает [`abstractclassmethod()`](https://python-all.ru/3.14/library/abc.html#abc.abstractclassmethod) и [`abstractstaticmethod()`](https://python-all.ru/3.14/library/abc.html#abc.abstractstaticmethod).788789Эти инструменты позволяют определить [абстрактный базовый класс](https://python-all.ru/3.14/glossary.html#term-abstract-base-class), который требует реализации определённого [`classmethod()`](https://python-all.ru/3.14/library/functions.html#classmethod) или [`staticmethod()`](https://python-all.ru/3.14/library/functions.html#staticmethod):790791```python792class Temperature(metaclass=abc.ABCMeta):793 @abc.abstractclassmethod794 def from_fahrenheit(cls, t):795 ...796 @abc.abstractclassmethod797 def from_celsius(cls, t):798 ...799```800801(Патч предоставлен Daniel Urban; [bpo-5867](https://python-all.ru/3.14/whatsnew/3.2.html).)802803### io804805У [`io.BytesIO`](https://python-all.ru/3.14/library/io.html#io.BytesIO) появился новый метод [`getbuffer()`](https://python-all.ru/3.14/library/io.html#io.BytesIO.getbuffer), функциональность которого похожа на [`memoryview()`](https://python-all.ru/3.14/library/stdtypes.html#memoryview). Он создаёт редактируемое представление данных без копирования. Произвольный доступ и поддержка срезов в буфере хорошо подходят для редактирования на месте:806807```python808>>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11809810>>> def change_location(buffer, record_number, location):811... start = record_number * REC_LEN + LOC_START812... buffer[start: start+LOC_LEN] = location813814>>> import io815816>>> byte_stream = io.BytesIO(817... b'G3805 storeroom Main chassis '818... b'X7899 shipping Reserve cog '819... b'L6988 receiving Primary sprocket'820... )821>>> buffer = byte_stream.getbuffer()822>>> change_location(buffer, 1, b'warehouse ')823>>> change_location(buffer, 0, b'showroom ')824>>> print(byte_stream.getvalue())825b'G3805 showroom Main chassis '826b'X7899 warehouse Reserve cog '827b'L6988 receiving Primary sprocket'828```829830(Предложено Антуаном Питру в [bpo-5506](https://python-all.ru/3.14/whatsnew/3.2.html).)831832### reprlib833834При написании метода [`__repr__()`](https://python-all.ru/3.14/reference/datamodel.html#object.__repr__) для пользовательского контейнера легко забыть обработать случай, когда элемент ссылается обратно на сам контейнер. Встроенные объекты Python, такие как [`list`](https://python-all.ru/3.14/library/stdtypes.html#list) и [`set`](https://python-all.ru/3.14/library/stdtypes.html#set), обрабатывают самоссылку, отображая «…» в рекурсивной части строки представления.835836Чтобы помочь в написании таких методов [`__repr__()`](https://python-all.ru/3.14/reference/datamodel.html#object.__repr__), модуль [`reprlib`](https://python-all.ru/3.14/library/reprlib.html#module-reprlib) получил новый декоратор [`recursive_repr()`](https://python-all.ru/3.14/library/reprlib.html#reprlib.recursive_repr) для обнаружения рекурсивных вызовов `__repr__()` и подстановки вместо них строки-заполнителя:837838```python839>>> class MyList(list):840... @recursive_repr()841... def __repr__(self):842... return '<' + '|'.join(map(repr, self)) + '>'843...844>>> m = MyList('abc')845>>> m.append(m)846>>> m.append('x')847>>> print(m)848<'a'|'b'|'c'|...|'x'>849```850851(Предложено Рэймондом Хеттингером в [bpo-9826](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-9840](https://python-all.ru/3.14/whatsnew/3.2.html).)852853### logging854855В дополнение к конфигурации на основе словаря, описанной выше, пакет [`logging`](https://python-all.ru/3.14/library/logging.html#module-logging) содержит множество других улучшений.856857Документация по logging была дополнена [базовым руководством](https://python-all.ru/3.14/howto/logging.html#logging-basic-tutorial), [продвинутым руководством](https://python-all.ru/3.14/howto/logging.html#logging-advanced-tutorial) и [поваренной книгой](https://python-all.ru/3.14/howto/logging-cookbook.html#logging-cookbook) с рецептами логирования. Эти документы – самый быстрый способ изучить логирование.858859Функция настройки [`logging.basicConfig()`](https://python-all.ru/3.14/library/logging.html#logging.basicConfig) получила аргумент *style* для поддержки трёх различных типов форматирования строк. По умолчанию он равен «%» для традиционного форматирования через %, может быть установлен в «{» для нового стиля [`str.format()`](https://python-all.ru/3.14/library/stdtypes.html#str.format) или в «$» для форматирования в стиле оболочки, предоставляемого [`string.Template`](https://python-all.ru/3.14/library/string.html#string.Template). Следующие три конфигурации эквивалентны:860861```python862>>> from logging import basicConfig863>>> basicConfig(style='%', format="%(name)s -> %(levelname)s: %(message)s")864>>> basicConfig(style='{', format="{name} -> {levelname} {message}")865>>> basicConfig(style='$', format="$name -> $levelname: $message")866```867868Если до возникновения события логирования не настроена конфигурация, теперь используется конфигурация по умолчанию с [`StreamHandler`](https://python-all.ru/3.14/library/logging.handlers.html#logging.StreamHandler), направленным в [`sys.stderr`](https://python-all.ru/3.14/library/sys.html#sys.stderr) для событий уровня `WARNING` и выше. Ранее событие, произошедшее до настройки конфигурации, либо вызывало исключение, либо молча отбрасывалось в зависимости от значения [`logging.raiseExceptions`](https://python-all.ru/3.14/library/logging.html#logging.raiseExceptions). Новый обработчик по умолчанию хранится в [`logging.lastResort`](https://python-all.ru/3.14/library/logging.html#logging.lastResort).869870Использование фильтров упрощено. Вместо создания объекта [`Filter`](https://python-all.ru/3.14/library/logging.html#logging.Filter) предикатом может быть любой вызываемый объект Python, возвращающий `True` или `False`.871872Было сделано множество других улучшений, повышающих гибкость и упрощающих конфигурацию. Полный список изменений в Python 3.2 смотрите в документации модуля.873874### csv875876Модуль [`csv`](https://python-all.ru/3.14/library/csv.html#module-csv) теперь поддерживает новый диалект [`unix_dialect`](https://python-all.ru/3.14/library/csv.html#csv.unix_dialect), который применяет кавычки для всех полей и традиционный стиль Unix с `'\n'` в качестве завершителя строки. Зарегистрированное имя диалекта – `unix`.877878У [`csv.DictWriter`](https://python-all.ru/3.14/library/csv.html#csv.DictWriter) появился новый метод [`writeheader()`](https://python-all.ru/3.14/library/csv.html#csv.DictWriter.writeheader) для записи начальной строки с именами полей:879880```python881>>> import csv, sys882>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')883>>> w.writeheader()884"name","dept"885>>> w.writerows([886... {'name': 'tom', 'dept': 'accounting'},887... {'name': 'susan', 'dept': 'Salesl'}])888"tom","accounting"889"susan","sales"890```891892(Новый диалект предложен Джеем Талботом в [bpo-5975](https://python-all.ru/3.14/whatsnew/3.2.html), а новый метод предложен Эдом Абрахамом в [bpo-1537721](https://python-all.ru/3.14/whatsnew/3.2.html).)893894### contextlib895896Появился новый и слегка умопомрачительный инструмент [`ContextDecorator`](https://python-all.ru/3.14/library/contextlib.html#contextlib.ContextDecorator), полезный для создания [менеджера контекста](https://python-all.ru/3.14/glossary.html#term-context-manager), который выполняет двойную роль как декоратор функций.897898Для удобства эта новая функциональность используется [`contextmanager()`](https://python-all.ru/3.14/library/contextlib.html#contextlib.contextmanager), так что не требуется дополнительных усилий для поддержки обеих ролей.899900Основная идея в том, что и менеджеры контекста, и декораторы функций могут использоваться как обёртки для действий до и после. Менеджеры контекста оборачивают группу операторов с помощью оператора [`with`](https://python-all.ru/3.14/reference/compound_stmts.html#with), а декораторы функций оборачивают группу операторов, заключённых в функцию. Поэтому иногда возникает необходимость написать обёртку для предварительного или последующего действия, которую можно использовать в любой из этих ролей.901902Например, иногда полезно обернуть функции или группы операторов логгером, который может отслеживать время входа и время выхода. Вместо написания как декоратора функций, так и менеджера контекста для этой задачи, [`contextmanager()`](https://python-all.ru/3.14/library/contextlib.html#contextlib.contextmanager) предоставляет обе возможности в одном определении:903904```python905from contextlib import contextmanager906import logging907908logging.basicConfig(level=logging.INFO)909910@contextmanager911def track_entry_and_exit(name):912 logging.info('Entering: %s', name)913 yield914 logging.info('Exiting: %s', name)915```916917Ранее это можно было использовать только как менеджер контекста:918919```python920with track_entry_and_exit('widget loader'):921 print('Some time consuming activity goes here')922 load_widget()923```924925Теперь его можно использовать и как декоратор:926927```python928@track_entry_and_exit('widget loader')929def activity():930 print('Some time consuming activity goes here')931 load_widget()932```933934Попытка выполнять сразу две роли накладывает некоторые ограничения на технику. Менеджеры контекста обычно имеют возможность вернуть аргумент, который может использоваться оператором [`with`](https://python-all.ru/3.14/reference/compound_stmts.html#with), но для декораторов функции такой параллели нет.935936В приведённом выше примере нет чистого способа для менеджера контекста *track\_entry\_and\_exit* вернуть экземпляр логгера для использования в теле вложенных операторов.937938(Предложено Майклом Фордом в [bpo-9110](https://python-all.ru/3.14/whatsnew/3.2.html).)939940### decimal and fractions941942Марк Дикинсон разработал элегантную и эффективную схему, гарантирующую, что разные числовые типы данных будут иметь одинаковое хеш-значение, когда их фактические значения равны ([bpo-8188](https://python-all.ru/3.14/whatsnew/3.2.html)):943944```python945assert hash(Fraction(3, 2)) == hash(1.5) == \946 hash(Decimal("1.5")) == hash(complex(1.5, 0))947```948949Некоторые детали хеширования доступны через новый атрибут [`sys.hash_info`](https://python-all.ru/3.14/library/sys.html#sys.hash_info), который описывает разрядность хеш-значения, простой модуль, хеш-значения для *бесконечности* и *nan*, а также множитель, используемый для мнимой части числа:950951```python952>>> sys.hash_info953sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)954```955956Раннее решение ограничить совместимость различных числовых типов было смягчено. По-прежнему не поддерживается (и не рекомендуется) неявное смешивание в арифметических выражениях, таких как `Decimal('1.1') + float('1.1')`, поскольку последнее теряет информацию в процессе построения двоичного числа с плавающей запятой. Однако, поскольку существующее значение с плавающей запятой может быть без потерь преобразовано как в десятичное, так и в рациональное представление, имеет смысл добавить их в конструктор и поддерживать сравнения смешанных типов.957958- Конструктор [`decimal.Decimal`](https://python-all.ru/3.14/library/decimal.html#decimal.Decimal) теперь принимает объекты [`float`](https://python-all.ru/3.14/library/functions.html#float) напрямую, поэтому больше нет необходимости использовать метод [`from_float()`](https://python-all.ru/3.14/library/decimal.html#decimal.Decimal.from_float) ([bpo-8257](https://python-all.ru/3.14/whatsnew/3.2.html)).959- Сравнения смешанных типов теперь полностью поддерживаются, так что объекты [`Decimal`](https://python-all.ru/3.14/library/decimal.html#decimal.Decimal) можно напрямую сравнивать с [`float`](https://python-all.ru/3.14/library/functions.html#float) и [`fractions.Fraction`](https://python-all.ru/3.14/library/fractions.html#fractions.Fraction) ([bpo-2531](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-8188](https://python-all.ru/3.14/whatsnew/3.2.html)).960961Аналогичные изменения были внесены в [`fractions.Fraction`](https://python-all.ru/3.14/library/fractions.html#fractions.Fraction), так что методы [`from_float()`](https://python-all.ru/3.14/library/fractions.html#fractions.Fraction.from_float) и [`from_decimal()`](https://python-all.ru/3.14/library/fractions.html#fractions.Fraction.from_decimal) больше не нужны ([bpo-8294](https://python-all.ru/3.14/whatsnew/3.2.html)):962963```python964>>> from decimal import Decimal965>>> from fractions import Fraction966>>> Decimal(1.1)967Decimal('1.100000000000000088817841970012523233890533447265625')968>>> Fraction(1.1)969Fraction(2476979795053773, 2251799813685248)970```971972Ещё одно полезное изменение для модуля [`decimal`](https://python-all.ru/3.14/library/decimal.html#module-decimal) заключается в том, что атрибут [`Context.clamp`](https://python-all.ru/3.14/library/decimal.html#decimal.Context.clamp) теперь является публичным. Это полезно при создании контекстов, соответствующих десятичным форматам обмена, указанным в IEEE 754 (см. [bpo-8540](https://python-all.ru/3.14/whatsnew/3.2.html)).973974(Авторы: Mark Dickinson и Raymond Hettinger.)975976### ftp977978Класс [`ftplib.FTP`](https://python-all.ru/3.14/library/ftplib.html#ftplib.FTP) теперь поддерживает протокол управления контекстом для безусловного поглощения исключений [`socket.error`](https://python-all.ru/3.14/library/socket.html#socket.error) и закрытия FTP-соединения по завершении:979980```python981>>> from ftplib import FTP982>>> with FTP("ftp1.at.proftpd.org") as ftp:983 ftp.login()984 ftp.dir()985986'230 Anonymous login ok, restrictions apply.'987dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .988dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..989dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS990dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora991```992993Другие файлоподобные объекты, такие как [`mmap.mmap`](https://python-all.ru/3.14/library/mmap.html#mmap.mmap) и [`fileinput.input()`](https://python-all.ru/3.14/library/fileinput.html#fileinput.input), также получили автоматически закрываемые менеджеры контекста:994995```python996with fileinput.input(files=('log1.txt', 'log2.txt')) as f:997 for line in f:998 process(line)999```10001001(Авторы: Tarek Ziadé и Giampaolo Rodolà в [bpo-4972](https://python-all.ru/3.14/whatsnew/3.2.html), и Georg Brandl в [bpo-8046](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-1286](https://python-all.ru/3.14/whatsnew/3.2.html).)10021003Класс [`FTP_TLS`](https://python-all.ru/3.14/library/ftplib.html#ftplib.FTP_TLS) теперь принимает параметр *context*, который является объектом [`ssl.SSLContext`](https://python-all.ru/3.14/library/ssl.html#ssl.SSLContext), позволяющим объединять параметры конфигурации SSL, сертификаты и закрытые ключи в единую (потенциально долгоживущую) структуру.10041005(Автор: Giampaolo Rodolà; [bpo-8806](https://python-all.ru/3.14/whatsnew/3.2.html).)10061007### popen10081009Функции [`os.popen()`](https://python-all.ru/3.14/library/os.html#os.popen) и [`subprocess.Popen()`](https://python-all.ru/3.14/library/subprocess.html#subprocess.Popen) теперь поддерживают операторы [`with`](https://python-all.ru/3.14/reference/compound_stmts.html#with) для автоматического закрытия файловых дескрипторов.10101011(Авторы: Antoine Pitrou и Brian Curtin в [bpo-7461](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-10554](https://python-all.ru/3.14/whatsnew/3.2.html).)10121013### select10141015Модуль [`select`](https://python-all.ru/3.14/library/select.html#module-select) теперь предоставляет новый константный атрибут, [`PIPE_BUF`](https://python-all.ru/3.14/library/select.html#select.PIPE_BUF), который указывает минимальное количество байтов, которые гарантированно не будут блокироваться, когда [`select.select()`](https://python-all.ru/3.14/library/select.html#select.select) сообщает, что канал готов к записи.10161017```python1018>>> import select1019>>> select.PIPE_BUF10205121021```10221023(Доступно в системах Unix. Патч от Sébastien Sablé в [bpo-9862](https://python-all.ru/3.14/whatsnew/3.2.html))10241025### gzip и zipfile10261027[`gzip.GzipFile`](https://python-all.ru/3.14/library/gzip.html#gzip.GzipFile) теперь реализует [`io.BufferedIOBase`](https://python-all.ru/3.14/library/io.html#io.BufferedIOBase) [абстрактный базовый класс](https://python-all.ru/3.14/glossary.html#term-abstract-base-class) (за исключением `truncate()`). Он также имеет метод [`peek()`](https://python-all.ru/3.14/library/gzip.html#gzip.GzipFile.peek) и поддерживает непозиционируемые, а также дополненные нулями файловые объекты.10281029Модуль [`gzip`](https://python-all.ru/3.14/library/gzip.html#module-gzip) также получает функции [`compress()`](https://python-all.ru/3.14/library/gzip.html#gzip.compress) и [`decompress()`](https://python-all.ru/3.14/library/gzip.html#gzip.decompress) для более удобного сжатия и распаковки в памяти. Имейте в виду, что текст необходимо кодировать как [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes) перед сжатием и распаковкой:10301031```python1032>>> import gzip1033>>> s = 'Three shall be the number thou shalt count, '1034>>> s += 'and the number of the counting shall be three'1035>>> b = s.encode() # преобразовать в utf-81036>>> len(b)1037891038>>> c = gzip.compress(b)1039>>> len(c)1040771041>>> gzip.decompress(c).decode()[:42] # распаковать и преобразовать в текст1042'Three shall be the number thou shalt count'1043```10441045(Авторы: Anand B. Pillai в [bpo-3488](https://python-all.ru/3.14/whatsnew/3.2.html); и Antoine Pitrou, Nir Aides и Brian Curtin в [bpo-9962](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-1675951](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-7471](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-2846](https://python-all.ru/3.14/whatsnew/3.2.html).)10461047Кроме того, класс [`zipfile.ZipExtFile`](https://python-all.ru/3.14/library/zipfile.html#zipfile.ZipFile.open) был внутренне переработан для представления файлов, хранящихся внутри архива. Новая реализация значительно быстрее и может быть обёрнута в объект [`io.BufferedReader`](https://python-all.ru/3.14/library/io.html#io.BufferedReader) для дополнительного ускорения. Она также решает проблему, при которой чередующиеся вызовы *read* и *readline* давали неверные результаты.10481049(Патч предоставлен Nir Aides в [bpo-7610](https://python-all.ru/3.14/whatsnew/3.2.html).)10501051### tarfile10521053Класс [`TarFile`](https://python-all.ru/3.14/library/tarfile.html#tarfile.TarFile) теперь можно использовать как менеджер контекста. Кроме того, его метод [`add()`](https://python-all.ru/3.14/library/tarfile.html#tarfile.TarFile.add) получил новую опцию *filter*, которая управляет тем, какие файлы добавляются в архив, и позволяет редактировать метаданные файлов.10541055Новая опция *filter* заменяет старый, менее гибкий параметр *exclude*, который теперь устарел. Если указан, дополнительный параметр *filter* должен быть [именованным аргументом](https://python-all.ru/3.14/glossary.html#term-keyword-argument). Предоставленная пользователем функция фильтра принимает объект [`TarInfo`](https://python-all.ru/3.14/library/tarfile.html#tarfile.TarInfo) и возвращает обновлённый объект `TarInfo`, или, если нужно исключить файл, функция может вернуть `None`:10561057```python1058>>> import tarfile, glob10591060>>> def myfilter(tarinfo):1061... if tarinfo.isfile(): # сохранять только реальные файлы1062... tarinfo.uname = 'monty' # отредактировать имя пользователя1063... return tarinfo10641065>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:1066... for filename in glob.glob('*.txt'):1067... tf.add(filename, filter=myfilter)1068... tf.list()1069-rw-r--r-- monty/501 902 2011-01-26 17:59:11 annotations.txt1070-rw-r--r-- monty/501 123 2011-01-26 17:59:11 general_questions.txt1071-rw-r--r-- monty/501 3514 2011-01-26 17:59:11 prion.txt1072-rw-r--r-- monty/501 124 2011-01-26 17:59:11 py_todo.txt1073-rw-r--r-- monty/501 1399 2011-01-26 17:59:11 semaphore_notes.txt1074```10751076(Предложено Tarek Ziadé и реализовано Lars Gustäbel в [bpo-6856](https://python-all.ru/3.14/whatsnew/3.2.html).)10771078### hashlib10791080Модуль [`hashlib`](https://python-all.ru/3.14/library/hashlib.html#module-hashlib) имеет два новых константных атрибута, перечисляющих алгоритмы хеширования, гарантированно присутствующие во всех реализациях, и те, что доступны в текущей реализации:10811082```python1083>>> import hashlib10841085>>> hashlib.algorithms_guaranteed1086{'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}10871088>>> hashlib.algorithms_available1089{'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',1090'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',1091'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',1092'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}1093```10941095(Предложено Carl Chenet в [bpo-7418](https://python-all.ru/3.14/whatsnew/3.2.html).)10961097### ast10981099Модуль [`ast`](https://python-all.ru/3.14/library/ast.html#module-ast) имеет замечательный универсальный инструмент для безопасного вычисления строк выражений с использованием синтаксиса литералов Python. Функция [`ast.literal_eval()`](https://python-all.ru/3.14/library/ast.html#ast.literal_eval) служит безопасной альтернативой встроенной функции [`eval()`](https://python-all.ru/3.14/library/functions.html#eval), которую легко использовать во вред. Python 3.2 добавляет литералы [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes) и [`set`](https://python-all.ru/3.14/library/stdtypes.html#set) в список поддерживаемых типов: строки, байты, числа, кортежи, списки, словари, множества, булевы значения и `None`.11001101```python1102>>> from ast import literal_eval11031104>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"1105>>> literal_eval(request)1106{'args': (2, 0.5), 'req': 3, 'func': 'pow'}11071108>>> request = "os.system('do something harmful')"1109>>> literal_eval(request)1110Traceback (most recent call last):1111 ...1112ValueError: malformed node or string: <_ast.Call object at 0x101739a10>1113```11141115(Реализовано Бенджамином Петерсоном и Георгом Брандлем.)11161117### os11181119Разные операционные системы используют различные кодировки для имён файлов и переменных окружения. Модуль [`os`](https://python-all.ru/3.14/library/os.html#module-os) предоставляет две новые функции, [`fsencode()`](https://python-all.ru/3.14/library/os.html#os.fsencode) и [`fsdecode()`](https://python-all.ru/3.14/library/os.html#os.fsdecode), для кодирования и декодирования имён файлов:11201121```python1122>>> import os1123>>> filename = 'Sehenswürdigkeiten'1124>>> os.fsencode(filename)1125b'Sehensw\xc3\xbcrdigkeiten'1126```11271128Некоторые операционные системы разрешают прямой доступ к закодированным байтам в окружении. Если это так, константа [`os.supports_bytes_environ`](https://python-all.ru/3.14/library/os.html#os.supports_bytes_environ) будет истинной.11291130Для прямого доступа к закодированным переменным окружения (если доступно) используйте новую функцию [`os.getenvb()`](https://python-all.ru/3.14/library/os.html#os.getenvb) или [`os.environb`](https://python-all.ru/3.14/library/os.html#os.environb), которая является байтовой версией [`os.environ`](https://python-all.ru/3.14/library/os.html#os.environ).11311132(Автор: Victor Stinner.)11331134### shutil11351136Функция [`shutil.copytree()`](https://python-all.ru/3.14/library/shutil.html#shutil.copytree) теперь имеет две новые опции:11371138- *ignore\_dangling\_symlinks*: когда `symlinks=False`, чтобы функция копировала файл, на который указывает символьная ссылка, а не саму ссылку. Эта опция подавляет ошибку, возникающую, если файл не существует.1139- *copy\_function*: вызываемый объект, используемый для копирования файлов. По умолчанию используется [`shutil.copy2()`](https://python-all.ru/3.14/library/shutil.html#shutil.copy2).11401141(Автор: Tarek Ziadé.)11421143Кроме того, модуль [`shutil`](https://python-all.ru/3.14/library/shutil.html#module-shutil) теперь поддерживает [архивацию](https://python-all.ru/3.14/library/shutil.html#archiving-operations) для zip-архивов, несжатых tar-архивов, tar-архивов со сжатием gzip и tar-архивов со сжатием bzip2. Также появились функции для регистрации дополнительных форматов архивов (например, tar-архивы со сжатием xz или пользовательские форматы).11441145Основные функции – [`make_archive()`](https://python-all.ru/3.14/library/shutil.html#shutil.make_archive) и [`unpack_archive()`](https://python-all.ru/3.14/library/shutil.html#shutil.unpack_archive). По умолчанию обе работают с текущей директорией (которую можно задать через [`os.chdir()`](https://python-all.ru/3.14/library/os.html#os.chdir)) и со всеми поддиректориями. Имя файла архива нужно указывать с полным путём. Архивация не разрушает исходные файлы (они остаются без изменений).11461147```python1148>>> import shutil, pprint11491150>>> os.chdir('mydata') # перейти в каталог исходного кода1151>>> f = shutil.make_archive('/var/backup/mydata',1152... 'zip') # архивировать текущий каталог1153>>> f # показать имя архива1154'/var/backup/mydata.zip'1155>>> os.chdir('tmp') # перейти к распаковке1156>>> shutil.unpack_archive('/var/backup/mydata.zip') # восстановить данные11571158>>> pprint.pprint(shutil.get_archive_formats()) # отобразить известные форматы1159[('bztar', "bzip2'ed tar-file"),1160 ('gztar', "gzip'ed tar-file"),1161 ('tar', 'uncompressed tar file'),1162 ('zip', 'ZIP file')]11631164>>> shutil.register_archive_format( # зарегистрировать новый формат архива1165... name='xz',1166... function=xz.compress, # вызываемая функция архивирования1167... extra_args=[('level', 8)], # аргументы функции1168... description='xz compression'1169... )1170```11711172(Автор: Tarek Ziadé.)11731174### sqlite311751176Модуль [`sqlite3`](https://python-all.ru/3.14/library/sqlite3.html#module-sqlite3) обновлён до версии pysqlite 2.6.0. У него появились две новые возможности.11771178- Атрибут `sqlite3.Connection.in_transit` истинен, если есть активная транзакция для незафиксированных изменений.1179- Методы [`sqlite3.Connection.enable_load_extension()`](https://python-all.ru/3.14/library/sqlite3.html#sqlite3.Connection.enable_load_extension) и [`sqlite3.Connection.load_extension()`](https://python-all.ru/3.14/library/sqlite3.html#sqlite3.Connection.load_extension) позволяют загружать расширения SQLite из файлов «.so». Одним из известных расширений является расширение полнотекстового поиска, распространяемое с SQLite.11801181(Авторы: R. David Murray и Shashwat Anand; [bpo-8845](https://python-all.ru/3.14/whatsnew/3.2.html).)11821183### html11841185Появился новый модуль [`html`](https://python-all.ru/3.14/library/html.html#module-html) с единственной функцией [`escape()`](https://python-all.ru/3.14/library/html.html#html.escape), которая используется для экранирования зарезервированных символов в HTML-разметке:11861187```python1188>>> import html1189>>> html.escape('x > 2 && x < 7')1190'x > 2 && x < 7'1191```11921193### socket11941195В модуль [`socket`](https://python-all.ru/3.14/library/socket.html#module-socket) внесены два улучшения.11961197- У объектов сокетов появился метод [`detach()`](https://python-all.ru/3.14/library/socket.html#socket.socket.detach), который переводит сокет в закрытое состояние, не закрывая фактически базовый файловый дескриптор. Последний затем можно использовать для других целей. (Добавлено Antoine Pitrou; [bpo-8524](https://python-all.ru/3.14/whatsnew/3.2.html).)1198- [`socket.create_connection()`](https://python-all.ru/3.14/library/socket.html#socket.create_connection) теперь поддерживает протокол управления контекстом для безусловного поглощения исключений [`socket.error`](https://python-all.ru/3.14/library/socket.html#socket.error) и закрытия сокета по завершении. (Автор: Giampaolo Rodolà; [bpo-9794](https://python-all.ru/3.14/whatsnew/3.2.html).)11991200### ssl12011202Модуль [`ssl`](https://python-all.ru/3.14/library/ssl.html#module-ssl) добавил ряд возможностей для удовлетворения общих требований к защищённым (шифрованным, аутентифицированным) интернет-соединениям:12031204- Новый класс [`SSLContext`](https://python-all.ru/3.14/library/ssl.html#ssl.SSLContext) служит контейнером для постоянных данных SSL, таких как настройки протокола, сертификаты, закрытые ключи и различные другие параметры. Он включает метод [`wrap_socket()`](https://python-all.ru/3.14/library/ssl.html#ssl.SSLContext.wrap_socket) для создания SSL-сокета из SSL-контекста.1205- Новая функция `ssl.match_hostname()` поддерживает проверку идентичности сервера для протоколов более высокого уровня, реализуя правила HTTPS (из [**RFC 2818**](https://python-all.ru/3.14/whatsnew/3.2.html)), которые также подходят для других протоколов.1206- Функция-конструктор [`ssl.wrap_socket()`](https://python-all.ru/3.14/library/ssl.html#ssl.SSLContext.wrap_socket) теперь принимает аргумент *ciphers*. Строка *ciphers* перечисляет разрешённые алгоритмы шифрования в формате, описанном в [документации OpenSSL](https://python-all.ru/3.14/whatsnew/3.2.html).1207- При компоновке с последними версиями OpenSSL модуль [`ssl`](https://python-all.ru/3.14/library/ssl.html#module-ssl) теперь поддерживает расширение Server Name Indication протокола TLS, что позволяет размещать несколько «виртуальных хостов» с разными сертификатами на одном IP-порту. Это расширение поддерживается только в клиентском режиме и активируется передачей аргумента *server\_hostname* в [`ssl.SSLContext.wrap_socket()`](https://python-all.ru/3.14/library/ssl.html#ssl.SSLContext.wrap_socket).1208- В модуль [`ssl`](https://python-all.ru/3.14/library/ssl.html#module-ssl) добавлены различные опции, такие как [`OP_NO_SSLv2`](https://python-all.ru/3.14/library/ssl.html#ssl.OP_NO_SSLv2), которая отключает небезопасный и устаревший протокол SSLv2.1209- Расширение теперь загружает все шифры и алгоритмы дайджестов OpenSSL. Если некоторые SSL-сертификаты не удаётся проверить, они сообщаются как ошибка «неизвестный алгоритм».1210- Версия используемого OpenSSL теперь доступна через атрибуты модуля [`ssl.OPENSSL_VERSION`](https://python-all.ru/3.14/library/ssl.html#ssl.OPENSSL_VERSION) (строка), [`ssl.OPENSSL_VERSION_INFO`](https://python-all.ru/3.14/library/ssl.html#ssl.OPENSSL_VERSION_INFO) (кортеж из 5 элементов) и [`ssl.OPENSSL_VERSION_NUMBER`](https://python-all.ru/3.14/library/ssl.html#ssl.OPENSSL_VERSION_NUMBER) (целое число).12111212(Предложено Антуаном Питру в [bpo-8850](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-1589](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-8322](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-5639](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-4870](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-8484](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-8321](https://python-all.ru/3.14/whatsnew/3.2.html).)12131214### nntp12151216Модуль `nntplib` получил переработанную реализацию с улучшенной семантикой байтов и текста, а также более практичными API. Эти изменения нарушают совместимость с версией nntplib из Python 3.1, которая и сама по себе была частично неработоспособна.12171218Также добавлена поддержка защищённых соединений как через неявный (с использованием `nntplib.NNTP_SSL`), так и через явный (с использованием `nntplib.NNTP.starttls()`) TLS.12191220(Предложено Антуаном Питру в [bpo-9360](https://python-all.ru/3.14/whatsnew/3.2.html) и Эндрю Вантом в [bpo-1926](https://python-all.ru/3.14/whatsnew/3.2.html).)12211222### сертификаты12231224[`http.client.HTTPSConnection`](https://python-all.ru/3.14/library/http.client.html#http.client.HTTPSConnection), [`urllib.request.HTTPSHandler`](https://python-all.ru/3.14/library/urllib.request.html#urllib.request.HTTPSHandler) и [`urllib.request.urlopen()`](https://python-all.ru/3.14/library/urllib.request.html#urllib.request.urlopen) теперь принимают необязательные аргументы, позволяющие проверять сертификаты сервера на соответствие набору центров сертификации, как рекомендуется при публичном использовании HTTPS.12251226(Добавлено Антуаном Питру, [bpo-9003](https://python-all.ru/3.14/whatsnew/3.2.html).)12271228### imaplib12291230Поддержка явного TLS для стандартных IMAP4-соединений была добавлена через новый метод [`imaplib.IMAP4.starttls`](https://python-all.ru/3.14/library/imaplib.html#imaplib.IMAP4.starttls).12311232(Предложено Лоренцо М. Катуччи и Антуаном Питру, [bpo-4471](https://python-all.ru/3.14/whatsnew/3.2.html).)12331234### http.client12351236В модуле [`http.client`](https://python-all.ru/3.14/library/http.client.html#module-http.client) был сделан ряд небольших улучшений API. Простые ответы HTTP 0.9 старого стиля больше не поддерживаются, а параметр *strict* считается устаревшим во всех классах.12371238Классы [`HTTPConnection`](https://python-all.ru/3.14/library/http.client.html#http.client.HTTPConnection) и [`HTTPSConnection`](https://python-all.ru/3.14/library/http.client.html#http.client.HTTPSConnection) теперь имеют параметр *source\_address* – кортеж (host, port), указывающий, откуда устанавливается HTTP-соединение.12391240Поддержка проверки сертификатов и виртуальных хостов HTTPS была добавлена в [`HTTPSConnection`](https://python-all.ru/3.14/library/http.client.html#http.client.HTTPSConnection).12411242Метод [`request()`](https://python-all.ru/3.14/library/http.client.html#http.client.HTTPConnection.request) у объектов соединения допускал необязательный аргумент *body*, чтобы для содержимого запроса можно было использовать [файловый объект](https://python-all.ru/3.14/glossary.html#term-file-object). Удобно, что аргумент *body* теперь также принимает [итерируемый объект](https://python-all.ru/3.14/glossary.html#term-iterable) при условии, что он содержит явный заголовок `Content-Length`. Такой расширенный интерфейс стал гораздо гибче, чем раньше.12431244Для установления HTTPS-соединения через прокси-сервер появился новый метод [`set_tunnel()`](https://python-all.ru/3.14/library/http.client.html#http.client.HTTPConnection.set_tunnel), который задаёт хост и порт для туннелирования HTTP Connect.12451246Для согласованности с поведением [`http.server`](https://python-all.ru/3.14/library/http.server.html#module-http.server) библиотека HTTP-клиента теперь также кодирует заголовки в ISO-8859-1 (Latin-1). Ранее она уже так делала для входящих заголовков, поэтому теперь поведение одинаково для входящего и исходящего трафика. (См. работу Армина Ронахера в [bpo-10980](https://python-all.ru/3.14/whatsnew/3.2.html).)12471248### unittest12491250Модуль unittest получил ряд улучшений: поддержка обнаружения тестов для пакетов, более простое экспериментирование в интерактивной оболочке, новые методы тестовых случаев, улучшенные диагностические сообщения при сбоях тестов и более понятные имена методов.12511252- Командный вызов `python -m unittest` теперь может принимать пути к файлам вместо имён модулей для запуска конкретных тестов ([bpo-10620](https://python-all.ru/3.14/whatsnew/3.2.html)). Новая система обнаружения тестов может находить тесты внутри пакетов, находя любой импортируемый тест из корневого каталога. Корневой каталог можно указать с помощью опции `-t`, шаблон для сопоставления файлов – с помощью `-p`, а каталог для начала поиска – с помощью `-s`:12531254 ```console1255 $ python -m unittest discover -s my_proj_dir -p _test.py1256 ```12571258 (Предложено Michael Foord.)1259- Экспериментирование в интерактивной оболочке стало проще, поскольку класс [`unittest.TestCase`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase) теперь можно создавать без аргументов:12601261 ```python1262 >>> from unittest import TestCase1263 >>> TestCase().assertEqual(pow(2, 3), 8)1264 ```12651266 (Предложено Michael Foord.)1267- Модуль [`unittest`](https://python-all.ru/3.14/library/unittest.html#module-unittest) содержит два новых метода, [`assertWarns()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertWarns) и [`assertWarnsRegex()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertWarnsRegex), для проверки того, что заданный тип предупреждения вызывается тестируемым кодом:12681269 ```python1270 with self.assertWarns(DeprecationWarning):1271 legacy_function('XYZ')1272 ```12731274 (Предложено Антуаном Питру, [bpo-9754](https://python-all.ru/3.14/whatsnew/3.2.html).)12751276 Ещё один новый метод, [`assertCountEqual()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertCountEqual), используется для сравнения двух итерируемых объектов с целью определить, равны ли их количества элементов (присутствуют ли одни и те же элементы с одинаковым числом вхождений независимо от порядка):12771278 ```python1279 def test_anagram(self):1280 self.assertCountEqual('algorithm', 'logarithm')1281 ```12821283 (Автор: Raymond Hettinger.)1284- Одна из основных особенностей модуля unittest – стремление выдавать содержательные диагностические сообщения при сбое теста. По возможности сбой записывается вместе с diff вывода. Это особенно полезно при анализе журналов неудачных тестовых запусков. Однако, поскольку diff может быть объёмным, появился новый атрибут [`maxDiff`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.maxDiff), задающий максимальную длину отображаемого diff.1285- Кроме того, имена методов в модуле были приведены в порядок.12861287 Например, [`assertRegex()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertRegex) – новое имя для `assertRegexpMatches()`, которое было названо неправильно, потому что тест использует [`re.search()`](https://python-all.ru/3.14/library/re.html#re.search), а не [`re.match()`](https://python-all.ru/3.14/library/re.html#re.match). Другие методы, использующие регулярные выражения, теперь именуются с использованием краткой формы «Regex» вместо «Regexp» – это соответствует именам, используемым в других реализациях unittest, соответствует старому названию модуля [`re`](https://python-all.ru/3.14/library/re.html#module-re) в Python и имеет однозначный верблюжий регистр.12881289 (Предложено Raymond Hettinger; реализовано Ezio Melotti.)1290- Чтобы повысить согласованность, некоторые давно существующие псевдонимы методов объявляются устаревшими; вместо них следует использовать предпочтительные имена:12911292 > | Старое имя | Предпочтительное имя |1293 > | --- | --- |1294 > | `assert_()` | [`assertTrue()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertTrue) |1295 > | `assertEquals()` | [`assertEqual()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertEqual) |1296 > | `assertNotEquals()` | [`assertNotEqual()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertNotEqual) |1297 > | `assertAlmostEquals()` | [`assertAlmostEqual()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertAlmostEqual) |1298 > | `assertNotAlmostEquals()` | [`assertNotAlmostEqual()`](https://python-all.ru/3.14/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) |12991300 Аналогично, методы `TestCase.fail*`, помеченные как устаревшие в Python 3.1, будут удалены в Python 3.3.13011302 (Предложено Ezio Melotti; [bpo-9424](https://python-all.ru/3.14/whatsnew/3.2.html).)1303- Метод `assertDictContainsSubset()` был объявлен устаревшим, потому что он был реализован с ошибкой: аргументы передавались в неправильном порядке. Это создавало трудно отлаживаемые оптические иллюзии, когда тесты вроде `TestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1})` завершались неудачей.13041305 (Автор: Raymond Hettinger.)13061307### random13081309Целочисленные методы модуля [`random`](https://python-all.ru/3.14/library/random.html#module-random) теперь лучше генерируют равномерные распределения. Раньше они вычисляли выборки с помощью `int(n*random())`, что давало небольшое смещение, когда *n* не было степенью двойки. Теперь производится несколько выборок из диапазона, размер которого равен ближайшей степени двойки, и выборка сохраняется только если она попадает в диапазон `0 <= x < n`. Затронутые функции и методы: [`randrange()`](https://python-all.ru/3.14/library/random.html#random.randrange), [`randint()`](https://python-all.ru/3.14/library/random.html#random.randint), [`choice()`](https://python-all.ru/3.14/library/random.html#random.choice), [`shuffle()`](https://python-all.ru/3.14/library/random.html#random.shuffle) и [`sample()`](https://python-all.ru/3.14/library/random.html#random.sample).13101311(Предложено Raymond Hettinger; [bpo-9025](https://python-all.ru/3.14/whatsnew/3.2.html).)13121313### poplib13141315Класс [`POP3_SSL`](https://python-all.ru/3.14/library/poplib.html#poplib.POP3_SSL) теперь принимает параметр *контекст*, который является объектом [`ssl.SSLContext`](https://python-all.ru/3.14/library/ssl.html#ssl.SSLContext), позволяющим объединять параметры настройки SSL, сертификаты и закрытые ключи в единую (потенциально долгоживущую) структуру.13161317(Предложено Giampaolo Rodolà; [bpo-8807](https://python-all.ru/3.14/whatsnew/3.2.html).)13181319### asyncore13201321`asyncore.dispatcher` теперь предоставляет метод `handle_accepted()`, возвращающий пару `(sock, addr)`, который вызывается, когда соединение с новой удалённой конечной точкой фактически установлено. Предполагается, что он будет использоваться как замена старому `handle_accept()` и избавляет пользователя от необходимости напрямую вызывать `accept()`.13221323(Предложено Giampaolo Rodolà; [bpo-6706](https://python-all.ru/3.14/whatsnew/3.2.html).)13241325### tempfile13261327Модуль [`tempfile`](https://python-all.ru/3.14/library/tempfile.html#module-tempfile) теперь содержит новый менеджер контекста [`TemporaryDirectory`](https://python-all.ru/3.14/library/tempfile.html#tempfile.TemporaryDirectory), который обеспечивает простое детерминированное удаление временных каталогов:13281329```python1330with tempfile.TemporaryDirectory() as tmpdirname:1331 print('created temporary dir:', tmpdirname)1332```13331334(Предложено Neil Schemenauer и Nick Coghlan; [bpo-5178](https://python-all.ru/3.14/whatsnew/3.2.html).)13351336### inspect13371338- Модуль [`inspect`](https://python-all.ru/3.14/library/inspect.html#module-inspect) содержит новую функцию [`getgeneratorstate()`](https://python-all.ru/3.14/library/inspect.html#inspect.getgeneratorstate) для простого определения текущего состояния генератора-итератора:13391340 ```python1341 >>> from inspect import getgeneratorstate1342 >>> def gen():1343 ... yield 'demo'1344 ...1345 >>> g = gen()1346 >>> getgeneratorstate(g)1347 'GEN_CREATED'1348 >>> next(g)1349 'demo'1350 >>> getgeneratorstate(g)1351 'GEN_SUSPENDED'1352 >>> next(g, None)1353 >>> getgeneratorstate(g)1354 'GEN_CLOSED'1355 ```13561357 (Предложено Rodolpho Eckhardt и Nick Coghlan; [bpo-10220](https://python-all.ru/3.14/whatsnew/3.2.html).)1358- Для поддержки поиска без возможности активации динамического атрибута в модуле [`inspect`](https://python-all.ru/3.14/library/inspect.html#module-inspect) появилась новая функция [`getattr_static()`](https://python-all.ru/3.14/library/inspect.html#inspect.getattr_static). В отличие от [`hasattr()`](https://python-all.ru/3.14/library/functions.html#hasattr), это настоящий поиск только для чтения, который гарантированно не меняет состояние во время поиска:13591360 ```python1361 >>> class A:1362 ... @property1363 ... def f(self):1364 ... print('Running')1365 ... return 101366 ...1367 >>> a = A()1368 >>> getattr(a, 'f')1369 Running1370 101371 >>> inspect.getattr_static(a, 'f')1372 <property object at 0x1022bd788>1373 ```13741375> (Предложено Michael Foord.)13761377### pydoc13781379Модуль [`pydoc`](https://python-all.ru/3.14/library/pydoc.html#module-pydoc) теперь предоставляет значительно улучшенный интерфейс веб-сервера, а также новый параметр командной строки `-b` для автоматического открытия окна браузера для отображения этого сервера:13801381```console1382$ pydoc3.2 -b1383```13841385(Предложено Ron Adam; [bpo-2001](https://python-all.ru/3.14/whatsnew/3.2.html).)13861387### dis13881389Модуль [`dis`](https://python-all.ru/3.14/library/dis.html#module-dis) пополнился двумя новыми функциями для инспекции кода: [`code_info()`](https://python-all.ru/3.14/library/dis.html#dis.code_info) и [`show_code()`](https://python-all.ru/3.14/library/dis.html#dis.show_code). Обе предоставляют подробную информацию об объекте кода для переданной функции, метода, строки исходного кода или объекта кода. Первая возвращает строку, вторая выводит её:13901391```python1392>>> import dis, random1393>>> dis.show_code(random.choice)1394Name: choice1395Filename: /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py1396Argument count: 21397Kw-only arguments: 01398Number of locals: 31399Stack size: 111400Flags: OPTIMIZED, NEWLOCALS, NOFREE1401Constants:1402 0: 'Choose a random element from a non-empty sequence.'1403 1: 'Cannot choose from an empty sequence'1404Names:1405 0: _randbelow1406 1: len1407 2: ValueError1408 3: IndexError1409Variable names:1410 0: self1411 1: seq1412 2: i1413```14141415Кроме того, функция [`dis()`](https://python-all.ru/3.14/library/dis.html#dis.dis) теперь принимает строковые аргументы, так что распространённую идиому `dis(compile(s, '', 'eval'))` можно сократить до `dis(s)`:14161417```python1418>>> dis('3*x+1 if x%2==1 else x//2')1419 1 0 LOAD_NAME 0 (x)1420 3 LOAD_CONST 0 (2)1421 6 BINARY_MODULO1422 7 LOAD_CONST 1 (1)1423 10 COMPARE_OP 2 (==)1424 13 POP_JUMP_IF_FALSE 281425 16 LOAD_CONST 2 (3)1426 19 LOAD_NAME 0 (x)1427 22 BINARY_MULTIPLY1428 23 LOAD_CONST 1 (1)1429 26 BINARY_ADD1430 27 RETURN_VALUE1431 >> 28 LOAD_NAME 0 (x)1432 31 LOAD_CONST 0 (2)1433 34 BINARY_FLOOR_DIVIDE1434 35 RETURN_VALUE1435```14361437В совокупности эти улучшения упрощают изучение того, как реализован CPython, и позволяют самому увидеть, что делает синтаксис языка «под капотом».14381439(Предложено Nick Coghlan; [bpo-9147](https://python-all.ru/3.14/whatsnew/3.2.html).)14401441### dbm14421443Все модули баз данных теперь поддерживают методы `get()` и `setdefault()`.14441445(Предложено Рэем Алленом в [bpo-9523](https://python-all.ru/3.14/whatsnew/3.2.html).)14461447### ctypes14481449Новый тип [`ctypes.c_ssize_t`](https://python-all.ru/3.14/library/ctypes.html#ctypes.c_ssize_t) представляет тип данных C `ssize_t`.14501451### site14521453Модуль [`site`](https://python-all.ru/3.14/library/site.html#module-site) содержит три новые функции, полезные для вывода подробной информации об установке Python.14541455- [`getsitepackages()`](https://python-all.ru/3.14/library/site.html#site.getsitepackages) выводит список всех глобальных каталогов site-packages.1456- [`getuserbase()`](https://python-all.ru/3.14/library/site.html#site.getuserbase) сообщает базовый каталог пользователя, в котором могут храниться данные.1457- [`getusersitepackages()`](https://python-all.ru/3.14/library/site.html#site.getusersitepackages) показывает путь к каталогу site-packages для конкретного пользователя.14581459```python1460>>> import site1461>>> site.getsitepackages()1462['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',1463 '/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',1464 '/Library/Python/3.2/site-packages']1465>>> site.getuserbase()1466'/Users/raymondhettinger/Library/Python/3.2'1467>>> site.getusersitepackages()1468'/Users/raymondhettinger/Library/Python/3.2/lib/python/site-packages'1469```14701471Удобно, что часть функциональности site доступна напрямую из командной строки:14721473```console1474$ python -m site --user-base1475/Users/raymondhettinger/.local1476$ python -m site --user-site1477/Users/raymondhettinger/.local/lib/python3.2/site-packages1478```14791480(Добавлено Тареком Зиаде в [bpo-6693](https://python-all.ru/3.14/whatsnew/3.2.html).)14811482### sysconfig14831484Новый модуль [`sysconfig`](https://python-all.ru/3.14/library/sysconfig.html#module-sysconfig) упрощает обнаружение путей установки и переменных конфигурации, которые различаются в зависимости от платформы и настроек установки.14851486Модуль предоставляет простые функции доступа для получения информации о платформе и версии:14871488- [`get_platform()`](https://python-all.ru/3.14/library/sysconfig.html#sysconfig.get_platform) возвращает значения наподобие *linux-i586* или *macosx-10.6-ppc*.1489- [`get_python_version()`](https://python-all.ru/3.14/library/sysconfig.html#sysconfig.get_python_version) возвращает строку с номером версии Python, например «3.2».14901491Он также предоставляет доступ к путям и переменным, соответствующим одной из семи именованных схем, используемых в `distutils`. К ним относятся *posix\_prefix*, *posix\_home*, *posix\_user*, *nt*, *nt\_user*, *os2*, *os2\_home*:14921493- [`get_paths()`](https://python-all.ru/3.14/library/sysconfig.html#sysconfig.get_paths) создаёт словарь, содержащий пути установки для текущей схемы установки.1494- [`get_config_vars()`](https://python-all.ru/3.14/library/sysconfig.html#sysconfig.get_config_vars) возвращает словарь платформенно-зависимых переменных.14951496Также имеется удобный интерфейс командной строки:14971498```doscon1499C:\Python32>python -m sysconfig1500Platform: "win32"1501Python version: "3.2"1502Current installation scheme: "nt"15031504Paths:1505 data = "C:\Python32"1506 include = "C:\Python32\Include"1507 platinclude = "C:\Python32\Include"1508 platlib = "C:\Python32\Lib\site-packages"1509 platstdlib = "C:\Python32\Lib"1510 purelib = "C:\Python32\Lib\site-packages"1511 scripts = "C:\Python32\Scripts"1512 stdlib = "C:\Python32\Lib"15131514Variables:1515 BINDIR = "C:\Python32"1516 BINLIBDEST = "C:\Python32\Lib"1517 EXE = ".exe"1518 INCLUDEPY = "C:\Python32\Include"1519 LIBDEST = "C:\Python32\Lib"1520 SO = ".pyd"1521 VERSION = "32"1522 abiflags = ""1523 base = "C:\Python32"1524 exec_prefix = "C:\Python32"1525 platbase = "C:\Python32"1526 prefix = "C:\Python32"1527 projectbase = "C:\Python32"1528 py_version = "3.2"1529 py_version_nodot = "32"1530 py_version_short = "3.2"1531 srcdir = "C:\Python32"1532 userbase = "C:\Documents and Settings\Raymond\Application Data\Python"1533```15341535(Перенесено из Distutils Тареком Зиаде.)15361537### pdb15381539Модуль отладчика [`pdb`](https://python-all.ru/3.14/library/pdb.html#module-pdb) получил ряд улучшений в удобстве использования:15401541- `pdb.py` теперь имеет опцию `-c`, которая выполняет команды, заданные в файле сценария `.pdbrc`.1542- Файл сценария `.pdbrc` может содержать команды `continue` и `next`, которые продолжают отладку.1543- Конструктор класса [`Pdb`](https://python-all.ru/3.14/library/pdb.html#pdb.Pdb) теперь принимает аргумент *nosigint*.1544- Новые команды: `l(list)`, `ll(long list)` и `source` для вывода исходного кода.1545- Новые команды: `display` и `undisplay` для показа или скрытия значения выражения, если оно изменилось.1546- Новая команда: `interact` для запуска интерактивного интерпретатора, содержащего глобальные и локальные имена из текущей области видимости.1547- Точки останова можно удалять по номеру.15481549(Добавлено Георгом Брандлем, Антонио Куни и Ильёй Сандлером.)15501551### configparser15521553Модуль [`configparser`](https://python-all.ru/3.14/library/configparser.html#module-configparser) был изменён для повышения удобства использования и предсказуемости парсера по умолчанию и поддерживаемого им синтаксиса INI. Старый класс `ConfigParser` был удалён в пользу `SafeConfigParser`, который, в свою очередь, был переименован в [`ConfigParser`](https://python-all.ru/3.14/library/configparser.html#configparser.ConfigParser). Поддержка inline-комментариев теперь по умолчанию отключена, а дубликаты секций или опций не допускаются в одном источнике конфигурации.15541555Парсеры конфигураций получили новый API на основе протокола отображения:15561557```python1558>>> parser = ConfigParser()1559>>> parser.read_string("""1560... [DEFAULT]1561... location = upper left1562... visible = yes1563... editable = no1564... color = blue1565...1566... [main]1567... title = Main Menu1568... color = green1569...1570... [options]1571... title = Options1572... """)1573>>> parser['main']['color']1574'green'1575>>> parser['main']['editable']1576'no'1577>>> section = parser['options']1578>>> section['title']1579'Options'1580>>> section['title'] = 'Options (editable: %(editable)s)'1581>>> section['title']1582'Options (editable: no)'1583```15841585Новый API реализован поверх классического API, поэтому пользовательские подклассы парсеров должны иметь возможность использовать его без изменений.15861587Структура INI-файла, принимаемая парсерами конфигураций, теперь может быть настроена. Пользователи могут задавать альтернативные разделители опция/значение и префиксы комментариев, изменять имя секции *DEFAULT* или переключать синтаксис интерполяции.15881589Поддерживается подключаемая интерполяция, включая дополнительный обработчик интерполяции [`ExtendedInterpolation`](https://python-all.ru/3.14/library/configparser.html#configparser.ExtendedInterpolation):15901591```python1592>>> parser = ConfigParser(interpolation=ExtendedInterpolation())1593>>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},1594... 'custom': {'prefix': '/usr/local'}})1595>>> parser.read_string("""1596... [buildout]1597... parts =1598... zope91599... instance1600... find-links =1601... ${buildout:directory}/downloads/dist1602...1603... [zope9]1604... recipe = plone.recipe.zope9install1605... location = /opt/zope1606...1607... [instance]1608... recipe = plone.recipe.zope9instance1609... zope9-location = ${zope9:location}1610... zope-conf = ${custom:prefix}/etc/zope.conf1611... """)1612>>> parser['buildout']['find-links']1613'\n/home/ambv/zope9/downloads/dist'1614>>> parser['instance']['zope-conf']1615'/usr/local/etc/zope.conf'1616>>> instance = parser['instance']1617>>> instance['zope-conf']1618'/usr/local/etc/zope.conf'1619>>> instance['zope9-location']1620'/opt/zope'1621```16221623Был также введён ряд небольших возможностей, таких как поддержка указания кодировки в операциях чтения, указание значений по умолчанию для get-функций или чтение напрямую из словарей и строк.16241625(Все изменения предоставлены Łukasz Langa.)16261627### urllib.parse16281629Для модуля [`urllib.parse`](https://python-all.ru/3.14/library/urllib.parse.html#module-urllib.parse) был сделан ряд улучшений удобства использования.16301631Функция [`urlparse()`](https://python-all.ru/3.14/library/urllib.parse.html#urllib.parse.urlparse) теперь поддерживает адреса [IPv6](https://python-all.ru/3.14/whatsnew/3.2.html), как описано в [**RFC 2732**](https://python-all.ru/3.14/whatsnew/3.2.html):16321633```python1634>>> import urllib.parse1635>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')1636ParseResult(scheme='http',1637 netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',1638 path='/foo/',1639 params='',1640 query='',1641 fragment='')1642```16431644Функция [`urldefrag()`](https://python-all.ru/3.14/library/urllib.parse.html#urllib.parse.urldefrag) теперь возвращает [именованный кортеж](https://python-all.ru/3.14/glossary.html#term-named-tuple):16451646```python1647>>> r = urllib.parse.urldefrag('http://python.org/about/#target')1648>>> r1649DefragResult(url='http://python.org/about/', fragment='target')1650>>> r[0]1651'http://python.org/about/'1652>>> r.fragment1653'target'1654```16551656Кроме того, функция [`urlencode()`](https://python-all.ru/3.14/library/urllib.parse.html#urllib.parse.urlencode) теперь стала гораздо более гибкой, принимая аргумент *query* как строкового, так и байтового типа. Если это строка, то параметры *safe*, *encoding* и *error* передаются в [`quote_plus()`](https://python-all.ru/3.14/library/urllib.parse.html#urllib.parse.quote_plus) для кодирования:16571658```python1659>>> urllib.parse.urlencode([1660... ('type', 'telenovela'),1661... ('name', '¿Dónde Está Elisa?')],1662... encoding='latin-1')1663'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'1664```16651666Как подробно описано в [Parsing ASCII Encoded Bytes](https://python-all.ru/3.14/library/urllib.parse.html#parsing-ascii-encoded-bytes), все функции [`urllib.parse`](https://python-all.ru/3.14/library/urllib.parse.html#module-urllib.parse) теперь принимают на вход ASCII-кодированные байтовые строки, при условии, что они не смешиваются с обычными строками. Если в качестве параметров указаны ASCII-кодированные байтовые строки, возвращаемые типы также будут ASCII-кодированными байтовыми строками:16671668```python1669>>> urllib.parse.urlparse(b'http://www.python.org:80/about/')1670ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',1671 path=b'/about/', params=b'', query=b'', fragment=b'')1672```16731674(Работа Nick Coghlan, Dan Mahn и Senthil Kumaran в [bpo-2987](https://python-all.ru/3.14/whatsnew/3.2.html), [bpo-5468](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-9873](https://python-all.ru/3.14/whatsnew/3.2.html).)16751676### mailbox16771678Благодаря согласованным усилиям R. David Murray, модуль [`mailbox`](https://python-all.ru/3.14/library/mailbox.html#module-mailbox) был исправлен для Python 3.2. Сложность заключалась в том, что mailbox изначально был спроектирован с текстовым интерфейсом, но email-сообщения лучше представлять с помощью [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes), поскольку различные части сообщения могут иметь разные кодировки.16791680Решение использовало двоичную поддержку пакета [`email`](https://python-all.ru/3.14/library/email.html#module-email) для разбора произвольных email-сообщений. Кроме того, решение потребовало ряда изменений API.16811682Как и ожидалось, метод [`add()`](https://python-all.ru/3.14/library/mailbox.html#mailbox.Mailbox.add) для объектов [`mailbox.Mailbox`](https://python-all.ru/3.14/library/mailbox.html#mailbox.Mailbox) теперь принимает двоичные входные данные.16831684[`StringIO`](https://python-all.ru/3.14/library/io.html#io.StringIO) и ввод из текстового файла устарели. Кроме того, строковый ввод будет выдавать ошибку на раннем этапе, если используются не-ASCII символы. Ранее ошибка возникала при обработке email на более позднем шаге.16851686Также поддерживается двоичный вывод. Метод [`get_file()`](https://python-all.ru/3.14/library/mailbox.html#mailbox.Mailbox.get_file) теперь возвращает файл в двоичном режиме (ранее он некорректно устанавливал файл в текстовый режим). Также появился новый метод [`get_bytes()`](https://python-all.ru/3.14/library/mailbox.html#mailbox.Mailbox.get_bytes), который возвращает [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes)-представление сообщения, соответствующего заданному *ключу*.16871688Всё ещё возможно получить недвоичный вывод, используя метод [`get_string()`](https://python-all.ru/3.14/library/mailbox.html#mailbox.Mailbox.get_string) старого API, но такой подход не очень полезен. Вместо этого лучше извлекать сообщения из объекта [`Message`](https://python-all.ru/3.14/library/mailbox.html#mailbox.Message) или загружать их из двоичного ввода.16891690(Предоставлено R. David Murray, при участии Steffen Daode Nurpmeso и начального патча от Victor Stinner в [bpo-9124](https://python-all.ru/3.14/whatsnew/3.2.html).)16911692### turtledemo16931694Демонстрационный код для модуля [`turtle`](https://python-all.ru/3.14/library/turtle.html#module-turtle) был перенесён из каталога *Demo* в основную библиотеку. Он включает более десятка примеров скриптов с наглядными демонстрациями. Находясь в [`sys.path`](https://python-all.ru/3.14/library/sys.html#sys.path), его теперь можно запускать напрямую из командной строки:16951696```console1697$ python -m turtledemo1698```16991700(Перенесён из каталога Demo Alexander Belopolsky в [bpo-10199](https://python-all.ru/3.14/whatsnew/3.2.html).)17011702## Многопоточность17031704- Механизм сериализации выполнения одновременно работающих потоков Python (обычно известный как [GIL](https://python-all.ru/3.14/glossary.html#term-GIL) или Global Interpreter Lock) был переписан. Среди целей были более предсказуемые интервалы переключения и снижение накладных расходов из-за конкуренции за блокировку и количества последующих системных вызовов. Понятие «интервал проверки» для разрешения переключения потоков было отброшено и заменено абсолютной длительностью, выраженной в секундах. Этот параметр настраивается через [`sys.setswitchinterval()`](https://python-all.ru/3.14/library/sys.html#sys.setswitchinterval). В настоящее время по умолчанию он составляет 5 миллисекунд.17051706 Дополнительные сведения о реализации можно прочитать в [сообщении в списке рассылки python-dev](https://python-all.ru/3.14/whatsnew/3.2.html) (однако, «приоритетные запросы», как описано в этом сообщении, не были сохранены для включения).17071708 (Предоставлено Antoine Pitrou.)1709- Обычные и рекурсивные блокировки теперь принимают необязательный аргумент *timeout* для своего метода [`acquire()`](https://python-all.ru/3.14/library/threading.html#threading.Lock.acquire). (Предоставлено Antoine Pitrou; [bpo-7316](https://python-all.ru/3.14/whatsnew/3.2.html).)1710- Аналогично, [`threading.Semaphore.acquire()`](https://python-all.ru/3.14/library/threading.html#threading.Semaphore.acquire) также получил аргумент *timeout*. (Предоставлено Torsten Landschoff; [bpo-850728](https://python-all.ru/3.14/whatsnew/3.2.html).)1711- Захват обычных и рекурсивных блокировок теперь может быть прерван сигналами на платформах, использующих Pthreads. Это означает, что программы Python, которые зависают при захвате блокировок, могут быть успешно завершены повторной отправкой SIGINT процессу (нажатием `Ctrl`+`C` в большинстве оболочек). (Предоставлено Reid Kleckner; [bpo-8844](https://python-all.ru/3.14/whatsnew/3.2.html).)17121713## Оптимизации17141715Добавлено несколько небольших улучшений производительности:17161717- Оптимизатор «глазка» Python теперь распознает шаблоны, такие как `x in {1, 2, 3}`, как проверку принадлежности к набору констант. Оптимизатор перестраивает [`set`](https://python-all.ru/3.14/library/stdtypes.html#set) в [`frozenset`](https://python-all.ru/3.14/library/stdtypes.html#frozenset) и сохраняет предварительно построенную константу.17181719 Теперь, когда замедление устранено, стало практичным начать писать проверки принадлежности с использованием set-нотации. Этот стиль одновременно ясен семантически и быстр в работе:17201721 ```python1722 extension = name.rpartition('.')[2]1723 if extension in {'xml', 'html', 'xhtml', 'css'}:1724 handle(name)1725 ```17261727 (Патч и дополнительные тесты предоставлены Дэйвом Малкольмом; [bpo-6690](https://python-all.ru/3.14/whatsnew/3.2.html)).1728- Сериализация и десериализация данных с использованием модуля [`pickle`](https://python-all.ru/3.14/library/pickle.html#module-pickle) теперь работает в несколько раз быстрее.17291730 (Предоставлено Александром Вассалотти, Антуаном Питру и командой Unladen Swallow в [bpo-9410](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-3873](https://python-all.ru/3.14/whatsnew/3.2.html).)1731- Алгоритм [Timsort](https://python-all.ru/3.14/whatsnew/3.2.html), используемый в [`list.sort()`](https://python-all.ru/3.14/library/stdtypes.html#list.sort) и [`sorted()`](https://python-all.ru/3.14/library/functions.html#sorted), теперь работает быстрее и использует меньше памяти при вызове с [функцией ключа](https://python-all.ru/3.14/glossary.html#term-key-function). Ранее каждый элемент списка оборачивался временным объектом, который запоминал значение ключа для каждого элемента. Теперь два массива ключей и значений сортируются параллельно. Это экономит память, потребляемую обёртками сортировки, и время, затрачиваемое на делегирование сравнений.17321733 (Патч от Дэниела Штуцбаха в [bpo-9915](https://python-all.ru/3.14/whatsnew/3.2.html).)1734- Производительность декодирования JSON улучшена, а потребление памяти снижено, когда одна и та же строка повторяется для нескольких ключей. Кроме того, кодирование JSON теперь использует ускорения на C, когда аргумент `sort_keys` равен true.17351736 (Предоставлено Антуаном Питру в [bpo-7451](https://python-all.ru/3.14/whatsnew/3.2.html) и Рэймондом Хеттингером и Антуаном Питру в [bpo-10314](https://python-all.ru/3.14/whatsnew/3.2.html).)1737- Рекурсивные блокировки (созданные с помощью API [`threading.RLock()`](https://python-all.ru/3.14/library/threading.html#threading.RLock)) теперь выигрывают от реализации на C, которая делает их такими же быстрыми, как обычные блокировки, и в 10–15 раз быстрее, чем их предыдущая чистая реализация на Python.17381739 (Предоставлено Антуаном Питру; [bpo-3001](https://python-all.ru/3.14/whatsnew/3.2.html).)1740- Алгоритм быстрого поиска в stringlib теперь используется методами [`split()`](https://python-all.ru/3.14/library/stdtypes.html#str.split), [`rsplit()`](https://python-all.ru/3.14/library/stdtypes.html#str.rsplit), [`splitlines()`](https://python-all.ru/3.14/library/stdtypes.html#str.splitlines) и [`replace()`](https://python-all.ru/3.14/library/stdtypes.html#str.replace) на объектах [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes), [`bytearray`](https://python-all.ru/3.14/library/stdtypes.html#bytearray) и [`str`](https://python-all.ru/3.14/library/stdtypes.html#str). Аналогично, алгоритм используется и в [`rfind()`](https://python-all.ru/3.14/library/stdtypes.html#str.rfind), [`rindex()`](https://python-all.ru/3.14/library/stdtypes.html#str.rindex), `rsplit()` и [`rpartition()`](https://python-all.ru/3.14/library/stdtypes.html#str.rpartition).17411742 (Патч от Флорана Ксиклуна в [bpo-7622](https://python-all.ru/3.14/whatsnew/3.2.html) и [bpo-7462](https://python-all.ru/3.14/whatsnew/3.2.html).)1743- Преобразования целых чисел в строки теперь работают с двумя «цифрами» за раз, сокращая количество операций деления и взятия остатка.17441745 ([bpo-6713](https://python-all.ru/3.14/whatsnew/3.2.html) от Гавейна Болтона, Марка Дикинсона и Виктора Стиннера.)17461747Было сделано несколько других незначительных оптимизаций. Разность множеств теперь работает быстрее, когда один операнд намного больше другого (патч от Андреса Беннетта в [bpo-8685](https://python-all.ru/3.14/whatsnew/3.2.html)). Метод `array.repeat()` получил более быструю реализацию ([bpo-1569291](https://python-all.ru/3.14/whatsnew/3.2.html) от Александра Белопольского). [`BaseHTTPRequestHandler`](https://python-all.ru/3.14/library/http.server.html#http.server.BaseHTTPRequestHandler) имеет более эффективную буферизацию ([bpo-3709](https://python-all.ru/3.14/whatsnew/3.2.html) от Эндрю Шаафа). Функция [`operator.attrgetter()`](https://python-all.ru/3.14/library/operator.html#operator.attrgetter) была ускорена ([bpo-10160](https://python-all.ru/3.14/whatsnew/3.2.html) от Христоса Георгиу). И [`ConfigParser`](https://python-all.ru/3.14/library/configparser.html#configparser.ConfigParser) загружает многострочные аргументы немного быстрее ([bpo-7113](https://python-all.ru/3.14/whatsnew/3.2.html) от Лукаша Ланги).17481749## Юникод17501751Python был обновлён до [Unicode 6.0.0](https://python-all.ru/3.14/whatsnew/3.2.html). Обновление стандарта добавляет более 2000 новых символов, включая [эмодзи](https://python-all.ru/3.14/whatsnew/3.2.html), которые важны для мобильных телефонов.17521753Кроме того, обновлённый стандарт изменил свойства символов для двух символов каннада (U+0CF1, U+0CF2) и одного числового символа New Tai Lue (U+19DA), сделав первые допустимыми для использования в идентификаторах, а последний – недопустимым. Подробнее см. [Unicode Character Database Changes](https://python-all.ru/3.14/whatsnew/3.2.html).17541755## Кодеки17561757Добавлена поддержка арабской DOS-кодировки *cp720* ([bpo-1616979](https://python-all.ru/3.14/whatsnew/3.2.html)).17581759Кодировка MBCS больше не игнорирует аргумент обработчика ошибок. В режиме строгой обработки по умолчанию она возбуждает [`UnicodeDecodeError`](https://python-all.ru/3.14/library/exceptions.html#UnicodeDecodeError) при обнаружении не декодируемой последовательности байтов и [`UnicodeEncodeError`](https://python-all.ru/3.14/library/exceptions.html#UnicodeEncodeError) для не кодируемого символа.17601761Кодек MBCS поддерживает обработчики ошибок `'strict'` и `'ignore'` для декодирования, и `'strict'` и `'replace'` для кодирования.17621763Для эмуляции кодировки MBCS Python 3.1 выберите обработчик `'ignore'` для декодирования и `'replace'` для кодирования.17641765На Mac OS X Python декодирует аргументы командной строки с помощью `'utf-8'`, а не кодировки локали.17661767По умолчанию [`tarfile`](https://python-all.ru/3.14/library/tarfile.html#module-tarfile) использует кодировку `'utf-8'` в Windows (вместо `'mbcs'`) и обработчик ошибок `'surrogateescape'` на всех операционных системах.17681769## Документация17701771Документация продолжает улучшаться.17721773- Таблица быстрых ссылок добавлена в начало длинных разделов, таких как [Встроенные функции](https://python-all.ru/3.14/library/functions.html#built-in-funcs). В случае с [`itertools`](https://python-all.ru/3.14/library/itertools.html#module-itertools) ссылки сопровождаются таблицами сводок в стиле шпаргалок, чтобы дать обзор и освежить память без необходимости читать всю документацию.1774- В некоторых случаях чистый исходный код на Python может быть полезным дополнением к документации, поэтому теперь многие модули имеют быстрые ссылки на последнюю версию исходного кода. Например, документация модуля [`functools`](https://python-all.ru/3.14/library/functools.html#module-functools) имеет быструю ссылку вверху с пометкой:17751776 > **Исходный код** [Lib/functools.py](https://python-all.ru/src/3.14/Lib/functools.py).17771778 (Автор: Raymond Hettinger; см. [обоснование](https://python-all.ru/3.14/whatsnew/3.2.html).)1779- Документация теперь содержит больше примеров и рецептов. В частности, в модуле [`re`](https://python-all.ru/3.14/library/re.html#module-re) есть обширный раздел [«Примеры регулярных выражений»](https://python-all.ru/3.14/library/re.html#re-examples). Точно так же модуль [`itertools`](https://python-all.ru/3.14/library/itertools.html#module-itertools) продолжает пополняться новыми [«Рецептами itertools»](https://python-all.ru/3.14/library/itertools.html#itertools-recipes).1780- Модуль [`datetime`](https://python-all.ru/3.14/library/datetime.html#module-datetime) теперь имеет вспомогательную реализацию на чистом Python. Функциональность не изменилась. Это просто предоставляет более читабельную альтернативную реализацию.17811782 (Автор: Alexander Belopolsky; [bpo-9528](https://python-all.ru/3.14/whatsnew/3.2.html).)1783- Необслуживаемый каталог `Demo` был удалён. Некоторые демонстрационные примеры были включены в документацию, некоторые перемещены в каталог `Tools/demo`, а остальные удалены полностью.17841785 (Автор: Georg Brandl; [bpo-7962](https://python-all.ru/3.14/whatsnew/3.2.html).)17861787## IDLE17881789- Меню «Формат» теперь содержит опцию для очистки исходных файлов путём удаления замыкающих пробелов.17901791 (Автор: Raymond Hettinger; [bpo-5150](https://python-all.ru/3.14/whatsnew/3.2.html).)1792- IDLE на Mac OS X теперь работает как с Carbon AquaTk, так и с Cocoa AquaTk.17931794 (Авторы: Kevin Walzer, Ned Deily и Ronald Oussoren; [bpo-6075](https://python-all.ru/3.14/whatsnew/3.2.html).)17951796## Репозиторий кода17971798В дополнение к существующему репозиторию Subversion по адресу [https://svn.python.org](https://python-all.ru/3.14/whatsnew/3.2.html) теперь доступен репозиторий [Mercurial](https://python-all.ru/3.14/whatsnew/3.2.html) по адресу [https://hg.python.org/](https://python-all.ru/3.14/whatsnew/3.2.html).17991800После выхода версии 3.2 планируется перейти на Mercurial в качестве основного репозитория. Эта распределённая система управления версиями должна упростить членам сообщества создание и обмен внешними наборами изменений. Подробнее см. [**PEP 385**](https://python-all.ru/3.14/whatsnew/3.2.html).18011802Чтобы научиться пользоваться новой системой управления версиями, см. [«Быстрый старт»](https://python-all.ru/3.14/whatsnew/3.2.html) или [«Руководство по рабочим процессам Mercurial»](https://python-all.ru/3.14/whatsnew/3.2.html).18031804## Изменения в сборке и C API18051806Изменения процесса сборки Python и C API включают:18071808- Сценарии *idle*, *pydoc* и *2to3* теперь устанавливаются с суффиксом, соответствующим версии, на `make altinstall` ([bpo-10679](https://python-all.ru/3.14/whatsnew/3.2.html)).1809- C-функции, обращающиеся к базе данных Unicode, теперь принимают и возвращают символы из всего диапазона Unicode, даже в сборках с узкими юникодными строками (Py\_UNICODE\_TOLOWER, Py\_UNICODE\_ISDECIMAL и другие). Видимое различие в Python заключается в том, что [`unicodedata.numeric()`](https://python-all.ru/3.14/library/unicodedata.html#unicodedata.numeric) теперь возвращает корректное значение для больших кодовых точек, а [`repr()`](https://python-all.ru/3.14/library/functions.html#repr) может считать больше символов печатаемыми.18101811 (Сообщил Bupjoe Lee, исправил Amaury Forgeot D’Arc; [bpo-5127](https://python-all.ru/3.14/whatsnew/3.2.html).)1812- Вычисляемые переходы (computed gotos) теперь включены по умолчанию на поддерживаемых компиляторах (которые обнаруживаются сценарием configure). Их по-прежнему можно выборочно отключить, указав `--without-computed-gotos`.18131814 (Автор: Antoine Pitrou; [bpo-9203](https://python-all.ru/3.14/whatsnew/3.2.html).)1815- Опция `--with-wctype-functions` была удалена. Встроенная база данных Unicode теперь используется для всех функций.18161817 (Автор: Amaury Forgeot D’Arc; [bpo-9210](https://python-all.ru/3.14/whatsnew/3.2.html).)1818- Хеш-значения теперь являются значениями нового типа, [`Py_hash_t`](https://python-all.ru/3.14/c-api/hash.html#c.Py_hash_t), который определён как имеющий тот же размер, что и указатель. Ранее они были типа long, который на некоторых 64-битных операционных системах всё ещё имеет длину всего 32 бита. В результате этого исправления [`set`](https://python-all.ru/3.14/library/stdtypes.html#set) и [`dict`](https://python-all.ru/3.14/library/stdtypes.html#dict) теперь могут содержать более `2**32` записей в сборках с 64-битными указателями (ранее они могли вырасти до такого размера, но их производительность катастрофически падала).18191820 (Предложено Raymond Hettinger, реализовано Benjamin Peterson; [bpo-9778](https://python-all.ru/3.14/whatsnew/3.2.html).)1821- Новый макрос `Py_VA_COPY` копирует состояние списка аргументов переменной длины. Он эквивалентен *va\_copy* из C99, но доступен на всех платформах Python ([bpo-2443](https://python-all.ru/3.14/whatsnew/3.2.html)).1822- Новая функция C API `PySys_SetArgvEx()` позволяет встроенному интерпретатору устанавливать [`sys.argv`](https://python-all.ru/3.14/library/sys.html#sys.argv) без изменения [`sys.path`](https://python-all.ru/3.14/library/sys.html#sys.path) ([bpo-5753](https://python-all.ru/3.14/whatsnew/3.2.html)).1823- `PyEval_CallObject()` теперь доступен только в форме макроса. Объявление функции, которое сохранялось по причинам обратной совместимости, теперь удалено – макрос был введён в 1997 году ([bpo-8276](https://python-all.ru/3.14/whatsnew/3.2.html)).1824- Появилась новая функция [`PyLong_AsLongLongAndOverflow()`](https://python-all.ru/3.14/c-api/long.html#c.PyLong_AsLongLongAndOverflow), которая аналогична [`PyLong_AsLongAndOverflow()`](https://python-all.ru/3.14/c-api/long.html#c.PyLong_AsLongAndOverflow). Обе служат для преобразования Python [`int`](https://python-all.ru/3.14/library/functions.html#int) в нативный тип фиксированной ширины, с обнаружением случаев, когда преобразование не помещается ([bpo-7767](https://python-all.ru/3.14/whatsnew/3.2.html)).1825- Функция [`PyUnicode_CompareWithASCIIString()`](https://python-all.ru/3.14/c-api/unicode.html#c.PyUnicode_CompareWithASCIIString) теперь возвращает *не равно*, если Python-строка завершается *NUL*.1826- Появилась новая функция [`PyErr_NewExceptionWithDoc()`](https://python-all.ru/3.14/c-api/exceptions.html#c.PyErr_NewExceptionWithDoc), которая подобна [`PyErr_NewException()`](https://python-all.ru/3.14/c-api/exceptions.html#c.PyErr_NewException), но позволяет указать строку документации. Это даёт исключениям на C те же возможности самодокументирования, что и их аналогам на чистом Python ([bpo-7033](https://python-all.ru/3.14/whatsnew/3.2.html)).1827- При компиляции с опцией `--with-valgrind` распределитель pymalloc будет автоматически отключаться при работе под Valgrind. Это обеспечивает улучшенное обнаружение утечек памяти при работе под Valgrind, сохраняя преимущества pymalloc в остальное время ([bpo-2422](https://python-all.ru/3.14/whatsnew/3.2.html)).1828- Удалён формат `O?` из функций *PyArg\_Parse*. Формат больше не используется и никогда не был документирован ([bpo-8837](https://python-all.ru/3.14/whatsnew/3.2.html)).18291830Был внесён ряд других небольших изменений в C-API. Полный список приведён в файле [Misc/NEWS](https://python-all.ru/3.14/whatsnew/3.2.html).18311832Кроме того, были обновлены сборочные файлы для Mac OS X; подробности см. в [Mac/BuildScript/README.txt](https://python-all.ru/3.14/whatsnew/3.2.html). Для пользователей, работающих в 32/64-разрядной сборке, существует известная проблема со стандартным Tcl/Tk в Mac OS X 10.6. Поэтому рекомендуется установить обновлённую альтернативу, например [ActiveState Tcl/Tk 8.5.9](https://python-all.ru/3.14/whatsnew/3.2.html). Дополнительные сведения доступны на странице [https://www.python.org/download/mac/tcltk/](https://python-all.ru/3.14/whatsnew/3.2.html).18331834## Переход на Python 3.218351836В этом разделе перечислены описанные ранее изменения и другие исправления ошибок, которые могут потребовать доработки вашего кода:18371838- Модуль [`configparser`](https://python-all.ru/3.14/library/configparser.html#module-configparser) претерпел ряд исправлений. Самое существенное изменение – замена старого класса `ConfigParser` на давно рекомендуемую альтернативу `SafeConfigParser`. Кроме того, имеется ряд более мелких несовместимостей:18391840 - Синтаксис интерполяции теперь проверяется при операциях [`get()`](https://python-all.ru/3.14/library/configparser.html#configparser.ConfigParser.get) и [`set()`](https://python-all.ru/3.14/library/configparser.html#configparser.ConfigParser.set). В схеме интерполяции по умолчанию допустимы только два токена с символом процента: `%(name)s` и `%%` (последний – экранированный знак процента).1841 - Методы [`set()`](https://python-all.ru/3.14/library/configparser.html#configparser.ConfigParser.set) и [`add_section()`](https://python-all.ru/3.14/library/configparser.html#configparser.ConfigParser.add_section) теперь проверяют, что значения являются строками. Раньше неподдерживаемые типы могли быть вставлены непреднамеренно.1842 - Повторяющиеся секции или параметры из одного источника теперь вызывают [`DuplicateSectionError`](https://python-all.ru/3.14/library/configparser.html#configparser.DuplicateSectionError) или [`DuplicateOptionError`](https://python-all.ru/3.14/library/configparser.html#configparser.DuplicateOptionError). Раньше дубликаты молча перезаписывали предыдущую запись.1843 - Встрочные комментарии теперь по умолчанию отключены, поэтому символ **;** теперь можно безопасно использовать в значениях.1844 - Комментарии теперь можно располагать с отступом. Следовательно, чтобы **;** или **#** оказались в начале строки в многострочных значениях, их нужно интерполировать. Это предотвращает ошибочную интерпретацию префиксных символов комментариев в значениях как комментариев.1845 - `""` теперь является допустимым значением и больше не преобразуется автоматически в пустую строку. Для пустых строк используйте `"option ="` в строке.1846- Модуль `nntplib` был существенно переработан, поэтому его API часто несовместимы с API версии 3.1.1847- Объекты [`bytearray`](https://python-all.ru/3.14/library/stdtypes.html#bytearray) больше нельзя использовать в качестве имён файлов; вместо этого их следует преобразовывать в [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes).1848- `array.tostring()` и `array.fromstring()` переименованы в [`array.tobytes()`](https://python-all.ru/3.14/library/array.html#array.array.tobytes) и [`array.frombytes()`](https://python-all.ru/3.14/library/array.html#array.array.frombytes) для ясности. Старые имена объявлены устаревшими. (См. [bpo-8990](https://python-all.ru/3.14/whatsnew/3.2.html).)1849- Функции `PyArg_Parse*()`:18501851 - Формат «t#» удалён: используйте «s#» или «s\*»1852 - Форматы «w» и «w#» удалены: используйте «w\*»1853- Тип `PyCObject`, объявленный устаревшим в 3.1, удалён. Для обёртывания непрозрачных C-указателей в объекты Python следует использовать API [`PyCapsule`](https://python-all.ru/3.14/c-api/capsule.html#c.PyCapsule); новый тип имеет чётко определённый интерфейс для передачи информации о типобезопасности и менее сложную сигнатуру вызова деструктора.1854- Функция `sys.setfilesystemencoding()` удалена, так как имела ошибочную архитектуру.1855- Функция и метод [`random.seed()`](https://python-all.ru/3.14/library/random.html#random.seed) теперь солят строковые начальные значения с помощью хеш-функции sha512. Чтобы получить доступ к предыдущей версии *seed* для воспроизведения последовательностей Python 3.1, установите аргумент *version* в *1*, `random.seed(s, version=1)`.1856- Ранее объявленная устаревшей функция `string.maketrans()` удалена в пользу статических методов [`bytes.maketrans()`](https://python-all.ru/3.14/library/stdtypes.html#bytes.maketrans) и [`bytearray.maketrans()`](https://python-all.ru/3.14/library/stdtypes.html#bytearray.maketrans). Это изменение устраняет путаницу с тем, какие типы поддерживаются модулем [`string`](https://python-all.ru/3.14/library/string.html#module-string). Теперь [`str`](https://python-all.ru/3.14/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes) и [`bytearray`](https://python-all.ru/3.14/library/stdtypes.html#bytearray) имеют собственные методы **maketrans** и **translate** с промежуточными таблицами перевода соответствующего типа.18571858 (Предложено Georg Brandl; [bpo-5675](https://python-all.ru/3.14/whatsnew/3.2.html).)1859- Ранее объявленная устаревшей функция `contextlib.nested()` удалена в пользу обычного оператора [`with`](https://python-all.ru/3.14/reference/compound_stmts.html#with), который может принимать несколько менеджеров контекста. Последний способ быстрее (поскольку встроен) и лучше завершает несколько менеджеров контекста, если один из них вызывает исключение:18601861 ```python1862 with open('mylog.txt') as infile, open('a.out', 'w') as outfile:1863 for line in infile:1864 if '<critical>' in line:1865 outfile.write(line)1866 ```18671868 (Предложено Georg Brandl и Mattias Brändström; [appspot issue 53094](https://python-all.ru/3.14/whatsnew/3.2.html).)1869- [`struct.pack()`](https://python-all.ru/3.14/library/struct.html#struct.pack) теперь допускает только байты для кода упаковки строк `s`. Раньше он принимал текстовые аргументы и неявно кодировал их в байты через UTF-8. Это было проблематично, так как строило предположения о верной кодировке и потому что кодировка с переменной длиной может дать сбой при записи в сегмент структуры фиксированной длины.18701871 Код вида `struct.pack('<6sHHBBB', 'GIF87a', x, y)` следует переписать с использованием байтов вместо текста: `struct.pack('<6sHHBBB', b'GIF87a', x, y)`.18721873 (Обнаружено David Beazley, исправлено Victor Stinner; [bpo-10783](https://python-all.ru/3.14/whatsnew/3.2.html).)1874- Класс [`xml.etree.ElementTree`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) теперь вызывает [`xml.etree.ElementTree.ParseError`](https://python-all.ru/3.14/library/xml.etree.elementtree.html#xml.etree.ElementTree.ParseError) при неудачном разборе. Ранее вызывалось [`xml.parsers.expat.ExpatError`](https://python-all.ru/3.14/library/pyexpat.html#xml.parsers.expat.ExpatError).1875- Новое, более длинное значение [`str()`](https://python-all.ru/3.14/library/stdtypes.html#str) для чисел с плавающей точкой может нарушить doctest-тесты, которые полагаются на старый формат вывода.1876- В [`subprocess.Popen`](https://python-all.ru/3.14/library/subprocess.html#subprocess.Popen) значение по умолчанию для *close\_fds* теперь равно `True` в Unix; в Windows оно равно `True`, если три стандартных потока установлены в `None`, и `False` в противном случае. Раньше *close\_fds* всегда было `False` по умолчанию, что приводило к трудноуловимым ошибкам или состояниям гонки, когда открытые файловые дескрипторы просачивались в дочерний процесс.1877- Поддержка устаревшего HTTP 0.9 удалена из [`urllib.request`](https://python-all.ru/3.14/library/urllib.request.html#module-urllib.request) и [`http.client`](https://python-all.ru/3.14/library/http.client.html#module-http.client). Такая поддержка по-прежнему присутствует на стороне сервера (в [`http.server`](https://python-all.ru/3.14/library/http.server.html#module-http.server)).18781879 (Предложено Antoine Pitrou, [bpo-10711](https://python-all.ru/3.14/whatsnew/3.2.html).)1880- SSL-сокеты в режиме тайм-аута теперь вызывают [`socket.timeout`](https://python-all.ru/3.14/library/socket.html#socket.timeout) при возникновении тайм-аута, а не общее [`SSLError`](https://python-all.ru/3.14/library/ssl.html#ssl.SSLError).18811882 (Автор: Антуан Питу, [bpo-10272](https://python-all.ru/3.14/whatsnew/3.2.html).)1883- Вводящие в заблуждение функции `PyEval_AcquireLock()` и `PyEval_ReleaseLock()` официально устарели. Вместо них следует использовать API, учитывающие состояние потока (например, [`PyEval_SaveThread()`](https://python-all.ru/3.14/c-api/threads.html#c.PyEval_SaveThread) и [`PyEval_RestoreThread()`](https://python-all.ru/3.14/c-api/threads.html#c.PyEval_RestoreThread)).1884- Из соображений безопасности `asyncore.handle_accept()` объявлен устаревшим, и добавлена новая функция `asyncore.handle_accepted()` для его замены.18851886 (Автор: Джампаоло Родола, [bpo-6706](https://python-all.ru/3.14/whatsnew/3.2.html).)1887- Из-за новой реализации [GIL](https://python-all.ru/3.14/glossary.html#term-GIL) `PyEval_InitThreads()` больше нельзя вызывать до [`Py_Initialize()`](https://python-all.ru/3.14/c-api/interp-lifecycle.html#c.Py_Initialize).1888