> **Источник:** https://python-all.ru/3.2/whatsnew/3.2.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# Что нового в Python 3.2

| Автор: | Рэймонд Хеттингер |
| --- | --- |

В этой статье описаны новые возможности Python 3.2 по сравнению с версией 3.1. Она сосредоточена на нескольких ключевых моментах и приводит несколько примеров. Полные сведения см. в файле [Misc/NEWS](https://python-all.ru/src/3.2/Misc/NEWS).

> **См. также**
>
> [**PEP 392**](https://python-all.ru/3.2/whatsnew/3.2.html) - График выпуска Python 3.2

## PEP 384: Определение стабильного ABI

Раньше модули расширения, собранные для одной версии Python, часто были несовместимы с другими версиями. Особенно в Windows каждый выпуск с новыми возможностями требовал пересборки всех модулей расширения, которые хотелось использовать. Это было следствием свободного доступа к внутренним структурам интерпретатора Python, который могли использовать модули расширения.

В Python 3.2 появляется альтернативный подход: модули расширения, ограничивающие себя ограниченным API (определяя Py\_LIMITED\_API), не могут использовать многие внутренние структуры, но ограничены набором функций API, которые обещают быть стабильными на протяжении нескольких выпусков. В результате модули расширения, собранные для 3.2 в этом режиме, будут также работать с 3.3, 3.4 и так далее. Модули расширения, использующие детали структур памяти, по-прежнему можно собирать, но их придётся перекомпилировать для каждого выпуска с новыми возможностями.

> **См. также**
>
> **[**PEP 384**](https://python-all.ru/3.2/whatsnew/3.2.html) - Определение стабильного ABI**
>
> PEP написан Мартином фон Лёвисом.

## PEP 389: Модуль разбора командной строки argparse

Новый модуль для разбора командной строки, [`argparse`](https://python-all.ru/3.2/library/argparse.html#module-argparse), был представлен, чтобы преодолеть ограничения [`optparse`](https://python-all.ru/3.2/library/optparse.html#module-optparse), который не обеспечивал поддержку позиционных аргументов (не только опций), подкоманд, обязательных опций и других распространённых шаблонов задания и проверки опций.

Этот модуль уже получил широкое распространение в сообществе как сторонний модуль. Будучи более функциональным, чем его предшественник, модуль [`argparse`](https://python-all.ru/3.2/library/argparse.html#module-argparse) теперь является предпочтительным модулем для обработки командной строки. Старый модуль по-прежнему доступен из-за значительного объёма унаследованного кода, который от него зависит.

Вот пример аннотированного парсера, показывающий такие возможности, как ограничение результатов набором вариантов, указание *metavar* в справке, проверка наличия одного или нескольких позиционных аргументов и создание обязательной опции:

```python
import argparse
parser = argparse.ArgumentParser(
            description = 'Manage servers',         # основное описание для справки
            epilog = 'Tested on Solaris and Linux') # отображается после справки
parser.add_argument('action',                       # имя аргумента
            choices = ['deploy', 'start', 'stop'],  # три допустимых значения
            help = 'action on each target')         # сообщение справки
parser.add_argument('targets',
            metavar = 'HOSTNAME',                   # имя переменной, используемое в сообщении справки
            nargs = '+',                            # требуется одна или несколько целей
            help = 'url for target machines')       # пояснение к сообщению справки
parser.add_argument('-u', '--user',                 # опция -u или --user
            required = True,                        # сделать его обязательным аргументом
            help = 'login as user')
```

Пример вызова парсера для командной строки:

```python
>>> cmd  = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
>>> result = parser.parse_args(cmd.split())
>>> result.action
'deploy'
>>> result.targets
['sneezy.example.com', 'sleepy.example.com']
>>> result.user
'skycaptain'
```

Пример автоматически сгенерированной справки парсера:

```python
>>> parser.parse_args('-h'.split())

usage: manage_cloud.py [-h] -u USER
                       {deploy,start,stop} HOSTNAME [HOSTNAME ...]

Manage servers

positional arguments:
  {deploy,start,stop}   action on each target
  HOSTNAME              url for target machines

optional arguments:
  -h, --help            show this help message and exit
  -u USER, --user USER  login as user

Tested on Solaris and Linux
```

Особенно удобная возможность [`argparse`](https://python-all.ru/3.2/library/argparse.html#module-argparse) – это возможность определять подпарсеры, каждый со своими собственными схемами аргументов и отображением справки:

```python
import argparse
parser = argparse.ArgumentParser(prog='HELM')
subparsers = parser.add_subparsers()

parser_l = subparsers.add_parser('launch', help='Launch Control')   # first subgroup
parser_l.add_argument('-m', '--missiles', action='store_true')
parser_l.add_argument('-t', '--torpedos', action='store_true')

parser_m = subparsers.add_parser('move', help='Move Vessel',        # second subgroup
                                 aliases=('steer', 'turn'))         # equivalent names
parser_m.add_argument('-c', '--course', type=int, required=True)
parser_m.add_argument('-s', '--speed', type=int, default=0)

$ ./helm.py --help                         # top level help (launch and move)
$ ./helm.py launch --help                  # help for launch options
$ ./helm.py launch --missiles              # set missiles=True and torpedos=False
$ ./helm.py steer --course 180 --speed 5   # set movement parameters
```

> **См. также**
>
> **[**PEP 389**](https://python-all.ru/3.2/whatsnew/3.2.html) - Новый модуль разбора командной строки**
>
> PEP написан Стивеном Бетардом.
>
> [*Обновление кода optparse*](https://python-all.ru/3.2/library/argparse.html#upgrading-optparse-code) – подробнее о различиях с [`optparse`](https://python-all.ru/3.2/library/optparse.html#module-optparse).

## PEP 391: Конфигурация логирования на основе словарей

Модуль [`logging`](https://python-all.ru/3.2/library/logging.html#module-logging) предлагал два вида конфигурации: один стиль с вызовами функций для каждой опции, другой стиль на основе внешнего файла, сохранённого в формате `ConfigParser`. Эти варианты не обеспечивали гибкости для создания конфигураций из файлов JSON или YAML, а также не поддерживали инкрементальную конфигурацию, которая необходима для указания параметров логгера из командной строки.

Для поддержки более гибкого стиля модуль теперь предлагает [`logging.config.dictConfig()`](https://python-all.ru/3.2/library/logging.config.html#logging.config.dictConfig) для задания конфигурации логирования с помощью обычных словарей Python. Параметры конфигурации включают форматтеры, обработчики, фильтры и логгеры. Вот рабочий пример словаря конфигурации:

```python
{"version": 1,
 "formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
                "full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"}
                },
 "handlers": {"console": {
                   "class": "logging.StreamHandler",
                   "formatter": "brief",
                   "level": "INFO",
                   "stream": "ext://sys.stdout"},
              "console_priority": {
                   "class": "logging.StreamHandler",
                   "formatter": "full",
                   "level": "ERROR",
                   "stream": "ext://sys.stderr"}
              },
 "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
```

Если этот словарь сохранён в файле с именем `conf.json`, его можно загрузить и вызвать с помощью такого кода:

```python
>>> import json, logging.config
>>> with open('conf.json') as f:
        conf = json.load(f)
>>> logging.config.dictConfig(conf)
>>> logging.info("Transaction completed normally")
INFO    : root           : Transaction completed normally
>>> logging.critical("Abnormal termination")
2011-02-17 11:14:36,694 root            CRITICAL Abnormal termination
```

> **См. также**
>
> **[**PEP 391**](https://python-all.ru/3.2/whatsnew/3.2.html) – Конфигурация логирования на основе словарей**
>
> PEP написан Винаем Саджипом.

## PEP 3148: Модуль `concurrent.futures`

Код для создания параллельного выполнения и управления им собирается в новом пространстве имён верхнего уровня *concurrent*. Первый его компонент – пакет *futures*, предоставляющий единый высокоуровневый интерфейс для управления потоками и процессами.

Дизайн [`concurrent.futures`](https://python-all.ru/3.2/library/concurrent.futures.html#module-concurrent.futures) был вдохновлён пакетом *java.util.concurrent*. В этой модели выполняющийся вызов и его результат представлены объектом [`Future`](https://python-all.ru/3.2/library/concurrent.futures.html#concurrent.futures.Future), который абстрагирует возможности, общие для потоков, процессов и удалённых вызовов процедур. Этот объект поддерживает проверку состояния (выполняется или завершён), тайм-ауты, отмены, добавление колбэков, а также доступ к результатам или исключениям.

Основная часть нового модуля – два класса исполнителей для запуска и управления вызовами. Цель исполнителей – упростить использование существующих инструментов для параллельных вызовов. Они избавляют от необходимости настраивать пул ресурсов, запускать вызовы, создавать очередь результатов, добавлять обработку таймаутов и ограничивать общее количество потоков, процессов или удалённых вызовов.

В идеале каждое приложение должно использовать один общий исполнитель для нескольких компонентов, чтобы ограничения на процессы и потоки управлялись централизованно. Это решает проблему проектирования, возникающую, когда у каждого компонента своя конкурирующая стратегия управления ресурсами.

Оба класса имеют общий интерфейс с тремя методами: [`submit()`](https://python-all.ru/3.2/library/concurrent.futures.html#concurrent.futures.Executor.submit) для планирования вызываемого объекта и возврата объекта [`Future`](https://python-all.ru/3.2/library/concurrent.futures.html#concurrent.futures.Future); [`map()`](https://python-all.ru/3.2/library/concurrent.futures.html#concurrent.futures.Executor.map) для планирования множества асинхронных вызовов за раз, и [`shutdown()`](https://python-all.ru/3.2/library/concurrent.futures.html#concurrent.futures.Executor.shutdown) для освобождения ресурсов. Класс является [*менеджером контекста*](https://python-all.ru/3.2/glossary.html#term-context-manager) и может использоваться в операторе [`with`](https://python-all.ru/3.2/reference/compound_stmts.html#with), чтобы гарантировать автоматическое освобождение ресурсов, когда текущие ожидающие future завершат выполнение.

Простой пример [`ThreadPoolExecutor`](https://python-all.ru/3.2/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) – это запуск четырёх параллельных потоков для копирования файлов:

```python
import concurrent.futures, shutil
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as e:
    e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
    e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
    e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
    e.submit(shutil.copy, 'src4.txt', 'dest4.txt')
```

> **См. также**
>
> **[**PEP 3148**](https://python-all.ru/3.2/whatsnew/3.2.html) – Futures – асинхронное выполнение вычислений**
>
> PEP написан Брайаном Куинланом.
>
> [*Код для параллельного чтения URL в потоках*](https://python-all.ru/3.2/library/concurrent.futures.html#threadpoolexecutor-example) – пример использования потоков для параллельной загрузки нескольких веб-страниц.
>
> [*Код для вычисления простых чисел параллельно*](https://python-all.ru/3.2/library/concurrent.futures.html#processpoolexecutor-example), пример, демонстрирующий [`ProcessPoolExecutor`](https://python-all.ru/3.2/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor).

## PEP 3147: Директории репозитория PYC

Схема кэширования байт-кода Python в файлы *.pyc* плохо работала в средах с несколькими интерпретаторами Python. Если один интерпретатор встречал кэшированный файл, созданный другим, он перекомпилировал исходный код и перезаписывал кэш, теряя преимущества кэширования.

Проблема «pyc-войн» стала более заметной, поскольку в дистрибутивах Linux стало обычным делом поставлять несколько версий Python. Эти конфликты возникают и с альтернативными реализациями CPython, такими как Unladen Swallow.

Чтобы решить эту проблему, механизм импорта Python был расширен для использования разных имён файлов для каждого интерпретатора. Вместо того чтобы Python 3.2, Python 3.3 и Unladen Swallow конкурировали за файл с именем «mymodule.pyc», теперь они будут искать «mymodule.cpython-32.pyc», «mymodule.cpython-33.pyc» и «mymodule.unladen10.pyc». А чтобы все эти новые файлы не засоряли исходные каталоги, файлы *pyc* теперь собираются в каталог «\_\_pycache\_\_», расположенный внутри каталога пакета.

Помимо имён файлов и целевых каталогов, новая схема имеет несколько аспектов, видимых программисту:

- У импортируемых модулей теперь есть атрибут `__cached__`, в котором хранится имя файла, который был фактически импортирован:

  ```python
  >>> import collections
  >>> collections.__cached__
  'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
  ```
- Тег, уникальный для каждого интерпретатора, доступен из модуля [`imp`](https://python-all.ru/3.2/library/imp.html#module-imp):

  ```python
  >>> import imp
  >>> imp.get_tag()
  'cpython-32'
  ```
- Скрипты, которые пытаются определить имя исходного файла из импортированного файла, теперь должны быть умнее. Больше недостаточно просто удалить букву «c» из имени файла «.pyc». Вместо этого используйте новые функции в модуле [`imp`](https://python-all.ru/3.2/library/imp.html#module-imp):

  ```python
  >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')
  'c:/py32/lib/collections.py'
  >>> imp.cache_from_source('c:/py32/lib/collections.py')
  'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
  ```
- Модули [`py_compile`](https://python-all.ru/3.2/library/py_compile.html#module-py_compile) и [`compileall`](https://python-all.ru/3.2/library/compileall.html#module-compileall) были обновлены для отражения нового соглашения об именовании и целевого каталога. Командная строка вызова *compileall* имеет новые опции: `-i` для указания списка файлов и каталогов для компиляции и `-b`, которая приводит к записи байт-кода в их устаревшее расположение, а не в *\_\_pycache\_\_*.
- Модуль [`importlib.abc`](https://python-all.ru/3.2/library/importlib.html#module-importlib.abc) обновлён и теперь содержит новые [*абстрактные базовые классы*](https://python-all.ru/3.2/glossary.html#term-abstract-base-class) для загрузки файлов байт-кода. ABC [`PyLoader`](https://python-all.ru/3.2/library/importlib.html#importlib.abc.PyLoader) и [`PyPycLoader`](https://python-all.ru/3.2/library/importlib.html#importlib.abc.PyPycLoader) объявлены устаревшими (инструкции по сохранению совместимости с Python 3.1 приведены в документации).

> **См. также**
>
> **[**PEP 3147**](https://python-all.ru/3.2/whatsnew/3.2.html) – Директории репозитория PYC**
>
> PEP написан Барри Варшавой.

## PEP 3149: .so-файлы с тегом версии ABI

Директория репозитория PYC позволяет размещать несколько кэшированных файлов байт-кода в одном месте. Этот PEP реализует аналогичный механизм для разделяемых объектных файлов, помещая их в общую директорию с разными именами для каждой версии.

Общая директория называется «pyshared», а имена файлов различаются указанием реализации Python (например, CPython, PyPy, Jython и т.д.), номерами старшей и младшей версии, а также необязательными флагами сборки (например, «d» для отладки, «m» для pymalloc, «u» для wide-unicode). Для произвольного пакета «foo» при установке дистрибутивного пакета можно увидеть такие файлы:

```python
/usr/share/pyshared/foo.cpython-32m.so
/usr/share/pyshared/foo.cpython-33md.so
```

В самом Python теги доступны из функций модуля [`sysconfig`](https://python-all.ru/3.2/library/sysconfig.html#module-sysconfig):

```python
>>> import sysconfig
>>> sysconfig.get_config_var('SOABI')       # найти тег версии
'cpython-32mu'
>>> sysconfig.get_config_var('EXT_SUFFIX')  # найти полное расширение имени файла
'.cpython-32mu.so'
```

> **См. также**
>
> **[**PEP 3149**](https://python-all.ru/3.2/whatsnew/3.2.html) – файлы .so с тегами версии ABI**
>
> PEP написан Барри Варшавой.

## PEP 3333: Python Web Server Gateway Interface v1.0.1

Этот информационный PEP проясняет, как проблемы байтов/текста должны обрабатываться протоколом WSGI. Сложность в том, что обработка строк в Python 3 наиболее удобно выполняется с помощью типа [`str`](https://python-all.ru/3.2/library/functions.html#str), хотя сам протокол HTTP ориентирован на байты.

PEP различает так называемые *нативные строки*, используемые для заголовков и метаданных запросов/ответов, и *байтовые строки*, используемые для тел запросов и ответов.

*Нативные строки* всегда имеют тип [`str`](https://python-all.ru/3.2/library/functions.html#str), но ограничены кодовыми точками от *U+0000* до *U+00FF*, которые преобразуются в байты с помощью кодировки *Latin-1*. Эти строки используются для ключей и значений в словаре окружения, а также для заголовков ответа и статусов в функции `start_response()`. Они должны следовать [**RFC 2616**](https://python-all.ru/3.2/whatsnew/3.2.html) в отношении кодировки. То есть они должны быть либо символами *ISO-8859-1*, либо использовать [**RFC 2047**](https://python-all.ru/3.2/whatsnew/3.2.html) кодировку MIME.

Для разработчиков, переносящих WSGI-приложения с Python 2, вот ключевые моменты:

- Если приложение уже использовало строки для заголовков в Python 2, никаких изменений не требуется.
- Если же приложение кодировало выходные заголовки или декодировало входные заголовки, то заголовки необходимо будет перекодировать в Latin-1. Например, выходной заголовок, закодированный в utf-8 с использованием `h.encode('utf-8')`, теперь нужно преобразовать из байтов в нативные строки с помощью `h.encode('utf-8').decode('latin-1')`.
- Значения, возвращаемые приложением или отправляемые с помощью метода `write()`, должны быть байтовыми строками. Функция `start_response()` и переменная environ должны использовать нативные строки. Их нельзя смешивать.

Для разработчиков серверов, пишущих шлюзы CGI-to-WSGI или другие протоколы в стиле CGI, пользователи должны иметь возможность доступа к окружению с помощью нативных строк, даже если базовая платформа использует другие соглашения. Чтобы устранить этот разрыв, модуль [`wsgiref`](https://python-all.ru/3.2/library/wsgiref.html#module-wsgiref) содержит новую функцию [`wsgiref.handlers.read_environ()`](https://python-all.ru/3.2/library/wsgiref.html#wsgiref.handlers.read_environ) для перекодирования переменных CGI из [`os.environ`](https://python-all.ru/3.2/library/os.html#os.environ) в нативные строки и возврата нового словаря.

> **См. также**
>
> **[**PEP 3333**](https://python-all.ru/3.2/whatsnew/3.2.html) – Python Web Server Gateway Interface v1.0.1**
>
> PEP написан Филлипом Иби.

## Прочие изменения языка

Некоторые небольшие изменения, внесённые в ядро языка Python:

- Форматирование строк для [`format()`](https://python-all.ru/3.2/library/functions.html#format) и [`str.format()`](https://python-all.ru/3.2/library/stdtypes.html#str.format) получило новые возможности для символа формата **#**. Ранее для целых чисел в двоичной, восьмеричной или шестнадцатеричной системе он приводил к добавлению префикса '0b', '0o' или '0x' соответственно. Теперь он также может обрабатывать числа с плавающей запятой, комплексные и Decimal, что приводит к тому, что вывод всегда содержит десятичную точку, даже если после неё нет цифр.

  ```python
  >>> format(20, '#o')
  '0o24'
  >>> format(12.34, '#5.0f')
  '  12.'
  ```

  (Предложено Марком Дикинсоном и реализовано Эриком Смитом в [issue 7094](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Также появился новый метод [`str.format_map()`](https://python-all.ru/3.2/library/stdtypes.html#str.format_map), расширяющий возможности существующего метода [`str.format()`](https://python-all.ru/3.2/library/stdtypes.html#str.format) за счёт возможности принимать произвольные объекты [*mapping*](https://python-all.ru/3.2/glossary.html#term-mapping) (отображения). Этот новый метод позволяет использовать форматирование строк с любыми объектами, похожими на словарь, такими как [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict), [`Shelf`](https://python-all.ru/3.2/library/shelve.html#shelve.Shelf), [`ConfigParser`](https://python-all.ru/3.2/library/configparser.html#configparser.ConfigParser) или [`dbm`](https://python-all.ru/3.2/library/dbm.html#module-dbm). Он также полезен с пользовательскими подклассами [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict), которые нормализуют ключи перед поиском или предоставляют метод `__missing__()` для неизвестных ключей:

  ```python
  >>> import shelve
  >>> d = shelve.open('tmp.shl')
  >>> 'The {project_name} status is {status} as of {date}'.format_map(d)
  'The testing project status is green as of February 15, 2011'

  >>> class LowerCasedDict(dict):
          def __getitem__(self, key):
              return dict.__getitem__(self, key.lower())
  >>> lcd = LowerCasedDict(part='widgets', quantity=10)
  >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd)
  'There are 10 widgets in stock'

  >>> class PlaceholderDict(dict):
          def __missing__(self, key):
              return '<{}>'.format(key)
  >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict())
  'Hello <name>, welcome to <location>'
  ```

> (Предложено Рэймондом Хеттингером и реализовано Эриком Смитом в
>
> [issue 6081](https://python-all.ru/3.2/whatsnew/3.2.html)
>
> .)

- Интерпретатор теперь можно запускать с тихой опцией `-q`, чтобы предотвратить отображение информации об авторских правах и версии в интерактивном режиме. Эту опцию можно проверить с помощью атрибута [`sys.flags`](https://python-all.ru/3.2/library/sys.html#sys.flags):

  ```python
  $ python -q
  >>> sys.flags
  sys.flags(debug=0, division_warning=0, inspect=0, interactive=0,
  optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0,
  ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)
  ```

  (Предложено Марчином Войдыром в [issue 1772833](https://python-all.ru/3.2/whatsnew/3.2.html)).
- Функция [`hasattr()`](https://python-all.ru/3.2/library/functions.html#hasattr) работает путём вызова [`getattr()`](https://python-all.ru/3.2/library/functions.html#getattr) и определения, возникает ли исключение. Этот метод позволяет ей обнаруживать методы, созданные динамически с помощью [`__getattr__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__getattr__) или [`__getattribute__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__getattribute__), которые в противном случае отсутствовали бы в словаре класса. Ранее *hasattr* перехватывал любое исключение, возможно маскируя настоящие ошибки. Теперь *hasattr* был сужен и перехватывает только [`AttributeError`](https://python-all.ru/3.2/library/exceptions.html#AttributeError), позволяя другим исключениям проходить:

  ```python
  >>> class A:
          @property
          def f(self):
              return 1 // 0

  >>> a = A()
  >>> hasattr(a, 'f')
  Traceback (most recent call last):
    ...
  ZeroDivisionError: integer division or modulo by zero
  ```

  (Обнаружено Юрием Селивановым и исправлено Бенджамином Петерсоном; [issue 9666](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Результат [`str()`](https://python-all.ru/3.2/library/functions.html#str) для числа с плавающей точкой или комплексного числа теперь совпадает с его [`repr()`](https://python-all.ru/3.2/library/functions.html#repr). Ранее форма [`str()`](https://python-all.ru/3.2/library/functions.html#str) была короче, но это лишь вызывало путаницу и больше не нужно, поскольку теперь по умолчанию отображается максимально короткое [`repr()`](https://python-all.ru/3.2/library/functions.html#repr):

  ```python
  >>> import math
  >>> repr(math.pi)
  '3.141592653589793'
  >>> str(math.pi)
  '3.141592653589793'
  ```

  (Предложено и реализовано Марком Дикинсоном; [issue 9337](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Объекты [`memoryview`](https://python-all.ru/3.2/library/stdtypes.html#memoryview) теперь имеют метод [`release()`](https://python-all.ru/3.2/library/stdtypes.html#memoryview.release) и поддерживают протокол контекстного менеджера. Это позволяет своевременно освобождать любые ресурсы, полученные при запросе буфера от исходного объекта.

  ```python
  >>> with memoryview(b'abcdefgh') as v:
          print(v.tolist())
  [97, 98, 99, 100, 101, 102, 103, 104]
  ```

  (Добавлено Антуаном Питру; [issue 9757](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Ранее было запрещено удалять имя из локального пространства имён, если оно встречается как свободная переменная во вложенном блоке:

  ```python
  def outer(x):
      def inner():
         return x
      inner()
      del x
  ```

  Теперь это разрешено. Помните, что цель предложения [`except`](https://python-all.ru/3.2/reference/compound_stmts.html#except) очищается, так что этот код, который работал в Python 2.6, вызывал [`SyntaxError`](https://python-all.ru/3.2/library/exceptions.html#SyntaxError) в Python 3.1, а теперь снова работает:

  ```python
  def f():
      def print_error():
         print(e)
      try:
         something
      except Exception as e:
         print_error()
         # неявное "del e" здесь
  ```

  (См. [issue 4617](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Внутренний инструмент `structsequence` теперь создаёт подклассы tuple. Это означает, что C-структуры, такие как возвращаемые [`os.stat()`](https://python-all.ru/3.2/library/os.html#os.stat), [`time.gmtime()`](https://python-all.ru/3.2/library/time.html#time.gmtime) и [`sys.version_info`](https://python-all.ru/3.2/library/sys.html#sys.version_info), теперь работают как [*именованный кортеж*](https://python-all.ru/3.2/glossary.html#term-named-tuple) и взаимодействуют с функциями и методами, ожидающими кортеж в качестве аргумента. Это большой шаг вперёд в деле придания C-структурам такой же гибкости, как у их аналогов на чистом Python:

  ```python
  >>> isinstance(sys.version_info, tuple)
  True
  >>> 'Version %d.%d.%d %s(%d)' % sys.version_info
  'Version 3.2.0 final(0)'
  ```

  (Предложено Арфревером Фретесом Тайферсаром Арахезисом и реализовано Бенджамином Петерсоном в [issue 8413](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Предупреждения теперь легче контролировать с помощью переменной окружения [`PYTHONWARNINGS`](https://python-all.ru/3.2/using/cmdline.html#envvar-PYTHONWARNINGS) в качестве альтернативы использованию `-W` в командной строке:

  ```python
  $ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'
  ```

  (Предложено Барри Варшавой и реализовано Филипом Дженви в [issue 7301](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Добавлена новая категория предупреждений [`ResourceWarning`](https://python-all.ru/3.2/library/exceptions.html#ResourceWarning). Она возникает при обнаружении потенциальных проблем с потреблением ресурсов или очисткой. По умолчанию она отключена в обычных сборках, но может быть включена средствами модуля [`warnings`](https://python-all.ru/3.2/library/warnings.html#module-warnings) или из командной строки.

  [`ResourceWarning`](https://python-all.ru/3.2/library/exceptions.html#ResourceWarning) выдаётся при завершении интерпретатора, если список [`gc.garbage`](https://python-all.ru/3.2/library/gc.html#gc.garbage) не пуст, и если установлен [`gc.DEBUG_UNCOLLECTABLE`](https://python-all.ru/3.2/library/gc.html#gc.DEBUG_UNCOLLECTABLE), то выводятся все несобираемые объекты. Это предназначено для того, чтобы программист осознавал, что его код содержит проблемы с финализацией объектов.

  [`ResourceWarning`](https://python-all.ru/3.2/library/exceptions.html#ResourceWarning) также выдаётся, когда [*файловый объект*](https://python-all.ru/3.2/glossary.html#term-file-object) уничтожается без явного закрытия. Хотя деаллокатор такого объекта гарантирует закрытие базового ресурса операционной системы (обычно файлового дескриптора), задержка в деаллокации может вызвать различные проблемы, особенно в Windows. Вот пример включения предупреждения из командной строки:

  ```python
  $ python -q -Wdefault
  >>> f = open("foo", "wb")
  >>> del f
  __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
  ```

  (Добавлено Антуаном Питру и Георгом Брандлем в [issue 10093](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 477863](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Объекты [`range`](https://python-all.ru/3.2/library/functions.html#range) теперь поддерживают методы *index* и *count*. Это часть работы по обеспечению полной реализации [`collections.Sequence`](https://python-all.ru/3.2/library/collections.html#collections.Sequence) [*абстрактного базового класса*](https://python-all.ru/3.2/glossary.html#term-abstract-base-class). В результате язык получит более единообразный API. Кроме того, объекты [`range`](https://python-all.ru/3.2/library/functions.html#range) теперь поддерживают срезы и отрицательные индексы, даже со значениями больше [`sys.maxsize`](https://python-all.ru/3.2/library/sys.html#sys.maxsize). Это делает *range* более совместимым со списками:

  ```python
  >>> range(0, 100, 2).count(10)
  1
  >>> range(0, 100, 2).index(10)
  5
  >>> range(0, 100, 2)[5]
  10
  >>> range(0, 100, 2)[0:5]
  range(0, 10, 2)
  ```

  (Предложено Дэниелом Штуцбахом в [issue 9213](https://python-all.ru/3.2/whatsnew/3.2.html), Александром Белопольским в [issue 2690](https://python-all.ru/3.2/whatsnew/3.2.html) и Ником Коглан в [issue 10889](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Встроенная функция [`callable()`](https://python-all.ru/3.2/library/functions.html#callable) из Py2.x была воскрешена. Она предоставляет краткую, читаемую альтернативу использованию [*абстрактного базового класса*](https://python-all.ru/3.2/glossary.html#term-abstract-base-class) в выражении вида `isinstance(x, collections.Callable)`:

  ```python
  >>> callable(max)
  True
  >>> callable(20)
  False
  ```

  (См. [issue 10518](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Механизм импорта Python теперь может загружать модули, установленные в каталогах, в именах путей которых есть не-ASCII символы. Это решило давнюю проблему с домашними каталогами пользователей, имеющих не-ASCII символы в именах.

> (Потребовало обширной работы Виктора Стиннера в
>
> [issue 9425](https://python-all.ru/3.2/whatsnew/3.2.html)
>
> .)

## Новые, улучшенные и устаревшие модули

Стандартная библиотека Python прошла значительную работу по сопровождению и улучшению качества.

Самая большая новость для Python 3.2 в том, что пакет [`email`](https://python-all.ru/3.2/library/email.html#module-email), модули [`mailbox`](https://python-all.ru/3.2/library/mailbox.html#module-mailbox) и [`nntplib`](https://python-all.ru/3.2/library/nntplib.html#module-nntplib) теперь корректно работают с моделью bytes/text в Python 3. Впервые обеспечена правильная обработка сообщений со смешанными кодировками.

По всей стандартной библиотеке уделено больше внимания вопросам кодировок и различиям между текстом и байтами. В частности, взаимодействие с операционной системой теперь лучше обменивается не-ASCII данными, используя кодировку Windows MBCS, локаль-зависимые кодировки или UTF-8.

Ещё одно важное достижение – добавление значительно улучшенной поддержки *SSL*-соединений и сертификатов безопасности.

Кроме того, больше классов теперь реализуют [*менеджер контекста*](https://python-all.ru/3.2/glossary.html#term-context-manager) для поддержки удобной и надёжной очистки ресурсов с помощью оператора [`with`](https://python-all.ru/3.2/reference/compound_stmts.html#with).

### email

Удобство использования пакета [`email`](https://python-all.ru/3.2/library/email.html#module-email) в Python 3 было в значительной степени восстановлено благодаря обширным усилиям Р. Дэвида Мюррея. Проблема заключалась в том, что электронные письма обычно читаются и хранятся в виде [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes), а не [`str`](https://python-all.ru/3.2/library/functions.html#str) текста, и они могут содержать несколько кодировок в одном письме. Поэтому пакет email пришлось расширить для разбора и генерации сообщений в формате bytes.

- Новые функции [`message_from_bytes()`](https://python-all.ru/3.2/library/email.parser.html#email.message_from_bytes) и [`message_from_binary_file()`](https://python-all.ru/3.2/library/email.parser.html#email.message_from_binary_file), а также новые классы [`BytesFeedParser`](https://python-all.ru/3.2/library/email.parser.html#email.parser.BytesFeedParser) и [`BytesParser`](https://python-all.ru/3.2/library/email.parser.html#email.parser.BytesParser) позволяют разбирать двоичные данные сообщений в объекты модели.
- При вводе байтов в модель [`get_payload()`](https://python-all.ru/3.2/library/email.message.html#email.message.Message.get_payload) по умолчанию будет декодировать тело сообщения с *Content-Transfer-Encoding* равным *8bit*, используя кодировку, указанную в MIME-заголовках, и вернёт результирующую строку.
- При вводе байтов в модель [`Generator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.Generator) будет преобразовывать тела сообщений с *Content-Transfer-Encoding* равным *8bit*, чтобы вместо него использовалось *7bit* *Content-Transfer-Encoding*.

  Заголовки с незакодированными не-ASCII байтами считаются закодированными по [**RFC 2047**](https://python-all.ru/3.2/whatsnew/3.2.html) с использованием набора символов *unknown-8bit*.
- Новый класс [`BytesGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator) создаёт вывод в виде байтов, сохраняя любые неизменённые не-ASCII данные, присутствовавшие во входных данных, использованных для построения модели, включая тела сообщений с *Content-Transfer-Encoding* равным *8bit*.
- Класс [`smtplib`](https://python-all.ru/3.2/library/smtplib.html#module-smtplib) [`SMTP`](https://python-all.ru/3.2/library/smtplib.html#smtplib.SMTP) теперь принимает строку байтов в качестве аргумента *msg* для метода [`sendmail()`](https://python-all.ru/3.2/library/smtplib.html#smtplib.SMTP.sendmail), а новый метод [`send_message()`](https://python-all.ru/3.2/library/smtplib.html#smtplib.SMTP.send_message) принимает объект [`Message`](https://python-all.ru/3.2/library/email.message.html#email.message.Message) и может опционально получать адреса *from\_addr* и *to\_addrs* непосредственно из объекта.

(Предложено и реализовано Р. Дэвидом Мюрреем, [issue 4661](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 10321](https://python-all.ru/3.2/whatsnew/3.2.html).)

### elementtree

Пакет [`xml.etree.ElementTree`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) и его аналог `xml.etree.cElementTree` были обновлены до версии 1.3.

Добавлено несколько новых полезных функций и методов:

- [`xml.etree.ElementTree.fromstringlist()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.fromstringlist) – строит XML-документ из последовательности фрагментов
- [`xml.etree.ElementTree.register_namespace()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.register_namespace) для регистрации глобального префикса пространства имён
- [`xml.etree.ElementTree.tostringlist()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.tostringlist) для строкового представления, включающего все подсписки
- [`xml.etree.ElementTree.Element.extend()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.extend) для добавления последовательности из нуля или более элементов
- [`xml.etree.ElementTree.Element.iterfind()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.iterfind) ищет элемент и дочерние элементы
- [`xml.etree.ElementTree.Element.itertext()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.itertext) создаёт итератор текста по элементу и его дочерним элементам
- [`xml.etree.ElementTree.TreeBuilder.end()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder.end) закрывает текущий элемент
- [`xml.etree.ElementTree.TreeBuilder.doctype()`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder.doctype) обрабатывает объявление doctype

Два метода устарели:

- `xml.etree.ElementTree.getchildren()` используйте `list(elem)` вместо этого.
- `xml.etree.ElementTree.getiterator()` используйте `Element.iter` вместо этого.

Подробнее об обновлении см. в статье [Introducing ElementTree](https://python-all.ru/3.2/whatsnew/3.2.html) на сайте Фредрика Лунда.

(Предложено Florent Xicluna и Fredrik Lundh, [issue 6472](https://python-all.ru/3.2/whatsnew/3.2.html).)

### functools

- Модуль [`functools`](https://python-all.ru/3.2/library/functools.html#module-functools) включает новый декоратор для кэширования вызовов функций. [`functools.lru_cache()`](https://python-all.ru/3.2/library/functools.html#functools.lru_cache) позволяет сохранять результаты повторных запросов к внешнему ресурсу, если ожидается, что они будут одинаковыми.

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

  ```python
  >>> import functools
  >>> @functools.lru_cache(maxsize=300)
  >>> def get_phone_number(name):
          c = conn.cursor()
          c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
          return c.fetchone()[0]
  ```

  ```python
  >>> for name in user_requests:
          get_phone_number(name)        # cached lookup
  ```

  Чтобы помочь с выбором эффективного размера кеша, обёрнутая функция оснащается средствами отслеживания статистики кеша:

  ```python
  >>> get_phone_number.cache_info()
  CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)
  ```

  Если таблица phonelist обновляется, устаревшее содержимое кеша можно очистить с помощью:

  ```python
  >>> get_phone_number.cache_clear()
  ```

  (Предложено Raymond Hettinger с использованием идей дизайна от Jim Baker, Miki Tebeka и Nick Coghlan; см. [recipe 498245](https://python-all.ru/3.2/whatsnew/3.2.html), [recipe 577479](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 10586](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 10593](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Декоратор [`functools.wraps()`](https://python-all.ru/3.2/library/functools.html#functools.wraps) теперь добавляет атрибут `__wrapped__`, указывающий на исходную вызываемую функцию. Это позволяет интроспектировать обёрнутые функции. Он также копирует `__annotations__`, если она определена. И теперь он корректно пропускает отсутствующие атрибуты, такие как `__doc__`, которые могут быть не определены для обёрнутой вызываемой функции.

  В приведённом выше примере кеш можно удалить, восстановив исходную функцию:

  ```python
  >>> get_phone_number = get_phone_number.__wrapped__    # некэшированная функция
  ```

  (Авторы: Nick Coghlan и Terrence Cole; [issue 9567](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 3445](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 8814](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Чтобы упростить написание классов с методами полного сравнения, новый декоратор [`functools.total_ordering()`](https://python-all.ru/3.2/library/functools.html#functools.total_ordering) использует существующие методы равенства и неравенства для заполнения остальных методов.

  Например, указание *\_\_eq\_\_* и *\_\_lt\_\_* позволит [`total_ordering()`](https://python-all.ru/3.2/library/functools.html#functools.total_ordering) добавить *\_\_le\_\_*, *\_\_gt\_\_* и *\_\_ge\_\_*:

  ```python
  @total_ordering
  class Student:
      def __eq__(self, other):
          return ((self.lastname.lower(), self.firstname.lower()) ==
                  (other.lastname.lower(), other.firstname.lower()))
      def __lt__(self, other):
          return ((self.lastname.lower(), self.firstname.lower()) <
                  (other.lastname.lower(), other.firstname.lower()))
  ```

  С помощью декоратора *total\_ordering* остальные методы сравнения заполняются автоматически.

  (Автор: Raymond Hettinger.)
- Чтобы облегчить перенос программ с Python 2, функция [`functools.cmp_to_key()`](https://python-all.ru/3.2/library/functools.html#functools.cmp_to_key) преобразует старую функцию сравнения в современную [*функцию ключа*](https://python-all.ru/3.2/glossary.html#term-key-function):

  ```python
  >>> # порядок сортировки с учётом локали
  >>> sorted(iterable, key=cmp_to_key(locale.strcoll))
  ```

  Примеры сортировки и краткое руководство по сортировке см. в руководстве [Sorting HowTo](https://python-all.ru/3.2/whatsnew/3.2.html).

  (Автор: Raymond Hettinger.)

### itertools

- Модуль [`itertools`](https://python-all.ru/3.2/library/itertools.html#module-itertools) имеет новую функцию [`accumulate()`](https://python-all.ru/3.2/library/itertools.html#itertools.accumulate), созданную по образцу оператора *scan* из APL и функции *accumulate* из Numpy:

  ```python
  >>> from itertools import accumulate
  >>> list(accumulate([8, 2, 50]))
  [8, 10, 60]
  ```

  ```python
  >>> prob_dist = [0.1, 0.4, 0.2, 0.3]
  >>> list(accumulate(prob_dist))      # кумулятивное распределение вероятностей
  [0.1, 0.5, 0.7, 1.0]
  ```

  Пример использования [`accumulate()`](https://python-all.ru/3.2/library/itertools.html#itertools.accumulate) см. в [*примерах для модуля random*](https://python-all.ru/3.2/library/random.html#random-examples).

  (Автор: Raymond Hettinger с учётом предложений по дизайну от Mark Dickinson.)

### collections

- Класс [`collections.Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) теперь имеет две формы вычитания на месте: существующий оператор *-=* для [насыщающего вычитания](https://python-all.ru/3.2/whatsnew/3.2.html) и новый метод [`subtract()`](https://python-all.ru/3.2/library/collections.html#collections.Counter.subtract) для обычного вычитания. Первый подходит для [мультимножеств](https://python-all.ru/3.2/whatsnew/3.2.html), которые имеют только положительные счётчики, а второй больше подходит для случаев, допускающих отрицательные счётчики:

  ```python
  >>> tally = Counter(dogs=5, cat=3)
  >>> tally -= Counter(dogs=2, cats=8)    # насыщающее вычитание
  >>> tally
  Counter({'dogs': 3})
  ```

  ```python
  >>> tally = Counter(dogs=5, cats=3)
  >>> tally.subtract(dogs=2, cats=8)      # обычное вычитание
  >>> tally
  Counter({'dogs': 3, 'cats': -5})
  ```

  (Автор: Raymond Hettinger.)
- Класс [`collections.OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) имеет новый метод [`move_to_end()`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict.move_to_end), который принимает существующий ключ и перемещает его в первую или последнюю позицию упорядоченной последовательности.

  По умолчанию элемент перемещается в последнюю позицию. Это эквивалентно обновлению записи с помощью `od[k] = od.pop(k)`.

  Быстрая операция перемещения в конец полезна для изменения порядка следования записей. Например, упорядоченный словарь можно использовать для отслеживания порядка доступа, упорядочивая записи от самых старых к самым недавно запрошенным.

  ```python
  >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e'])
  >>> list(d)
  ['a', 'b', 'X', 'd', 'e']
  >>> d.move_to_end('X')
  >>> list(d)
  ['a', 'b', 'd', 'e', 'X']
  ```

  (Автор: Raymond Hettinger.)
- Класс [`collections.deque`](https://python-all.ru/3.2/library/collections.html#collections.deque) получил два новых метода: [`count()`](https://python-all.ru/3.2/library/collections.html#collections.deque.count) и [`reverse()`](https://python-all.ru/3.2/library/collections.html#collections.deque.reverse), что делает их более взаимозаменяемыми с объектами [`list`](https://python-all.ru/3.2/library/functions.html#list):

  ```python
  >>> d = deque('simsalabim')
  >>> d.count('s')
  2
  >>> d.reverse()
  >>> d
  deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])
  ```

  (Автор: Raymond Hettinger.)

### threading

Модуль [`threading`](https://python-all.ru/3.2/library/threading.html#module-threading) имеет новый класс синхронизации [`Barrier`](https://python-all.ru/3.2/library/threading.html#threading.Barrier), который заставляет несколько потоков ждать, пока все они не достигнут общей точки барьера. Барьеры полезны для того, чтобы задача с несколькими предусловиями не запускалась, пока все предшествующие задачи не будут завершены.

Барьеры могут работать с произвольным числом потоков. Это обобщение механизма [рандеву](https://python-all.ru/3.2/whatsnew/3.2.html), который определён только для двух потоков.

Реализованные как двухфазный циклический барьер, объекты [`Barrier`](https://python-all.ru/3.2/library/threading.html#threading.Barrier) подходят для использования в циклах. Отдельные фазы *заполнения* и *опустошения* гарантируют, что все потоки будут освобождены (опустошены) до того, как любой из них сможет вернуться и войти в барьер снова. Барьер полностью сбрасывается после каждого цикла.

Пример использования барьеров:

```python
from threading import Barrier, Thread

def get_votes(site):
    ballots = conduct_election(site)
    all_polls_closed.wait()        # не подсчитывать, пока все голосования не закрыты
    totals = summarize(ballots)
    publish(site, totals)

all_polls_closed = Barrier(len(sites))
for site in sites:
    Thread(target=get_votes, args=(site,)).start()
```

В этом примере барьер обеспечивает правило, что голоса не могут быть подсчитаны на любом избирательном участке, пока все участки не закроются. Обратите внимание, что решение с барьером похоже на решение с [`threading.Thread.join()`](https://python-all.ru/3.2/library/threading.html#threading.Thread.join), но потоки остаются живыми и продолжают работать (подводить итоги голосования) после пересечения точки барьера.

Если какая-либо из предшествующих задач может зависнуть или быть задержана, барьер можно создать с необязательным параметром *timeout*. Тогда, если время ожидания истечёт до того, как все предшествующие задачи достигнут точки барьера, все ожидающие потоки освобождаются и возбуждается исключение [`BrokenBarrierError`](https://python-all.ru/3.2/library/threading.html#threading.BrokenBarrierError):

```python
def get_votes(site):
    ballots = conduct_election(site)
    try:
        all_polls_closed.wait(timeout = midnight - time.now())
    except BrokenBarrierError:
        lockbox = seal_ballots(ballots)
        queue.put(lockbox)
    else:
        totals = summarize(ballots)
        publish(site, totals)
```

В этом примере барьер обеспечивает более надежное правило. Если некоторые избирательные участки не заканчивают работу до полуночи, барьер срабатывает по тайм-ауту, и бюллетени опечатываются и помещаются в очередь для последующей обработки.

Смотрите [Barrier Synchronization Patterns](https://python-all.ru/3.2/whatsnew/3.2.html) для получения дополнительных примеров использования барьеров в параллельных вычислениях. Кроме того, простое и подробное объяснение барьеров приведено в [The Little Book of Semaphores](https://python-all.ru/3.2/whatsnew/3.2.html), *раздел 3.6*.

(Предложено Kristján Valur Jónsson с проверкой API от Jeffrey Yasskin в [issue 8777](https://python-all.ru/3.2/whatsnew/3.2.html).)

### datetime and time

- Модуль [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime) теперь имеет новый тип [`timezone`](https://python-all.ru/3.2/library/datetime.html#datetime.timezone), который реализует интерфейс [`tzinfo`](https://python-all.ru/3.2/library/datetime.html#datetime.tzinfo), возвращая фиксированное смещение UTC и название часового пояса. Это упрощает создание объектов datetime с учётом часового пояса:

  ```python
  >>> from datetime import datetime, timezone

  >>> datetime.now(timezone.utc)
  datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)

  >>> datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")
  datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
  ```
- Кроме того, объекты [`timedelta`](https://python-all.ru/3.2/library/datetime.html#datetime.timedelta) теперь можно умножать на [`float`](https://python-all.ru/3.2/library/functions.html#float) и делить на [`float`](https://python-all.ru/3.2/library/functions.html#float) и [`int`](https://python-all.ru/3.2/library/functions.html#int). И объекты [`timedelta`](https://python-all.ru/3.2/library/datetime.html#datetime.timedelta) теперь можно делить друг на друга.
- Метод [`datetime.date.strftime()`](https://python-all.ru/3.2/library/datetime.html#datetime.date.strftime) больше не ограничен годами после 1900. Новый поддерживаемый диапазон лет – от 1000 до 9999 включительно.
- Когда в кортеже времени используется год из двух цифр, его интерпретация определяется [`time.accept2dyear`](https://python-all.ru/3.2/library/time.html#time.accept2dyear). По умолчанию *True*, что означает, что для двузначного года столетие подбирается по правилам POSIX, управляющим форматом `%y` strptime.

  Начиная с Py3.2, использование эвристики подбора столетия будет вызывать [`DeprecationWarning`](https://python-all.ru/3.2/library/exceptions.html#DeprecationWarning). Вместо этого рекомендуется установить [`time.accept2dyear`](https://python-all.ru/3.2/library/time.html#time.accept2dyear) в *False*, чтобы можно было использовать большие диапазоны дат без угадывания:

  ```python
  >>> import time, warnings
  >>> warnings.resetwarnings()      # удалить фильтры предупреждений по умолчанию

  >>> time.accept2dyear = True      # угадать, означает ли 11 число 11 или 2011
  >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
  Warning (from warnings module):
    ...
  DeprecationWarning: Century info guessed for a 2-digit year.
  'Fri Jan  1 12:34:56 2011'

  >>> time.accept2dyear = False     # использовать полный диапазон допустимых дат
  >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
  'Fri Jan  1 12:34:56 11'
  ```

  Несколько функций теперь имеют значительно расширенные диапазоны дат. Когда [`time.accept2dyear`](https://python-all.ru/3.2/library/time.html#time.accept2dyear) имеет значение false, функция [`time.asctime()`](https://python-all.ru/3.2/library/time.html#time.asctime) будет принимать любой год, помещающийся в C int, в то время как функции [`time.mktime()`](https://python-all.ru/3.2/library/time.html#time.mktime) и [`time.strftime()`](https://python-all.ru/3.2/library/time.html#time.strftime) будут принимать полный диапазон, поддерживаемый соответствующими функциями операционной системы.

(Предложено Александром Белопольским и Виктором Штиннером в [выпуске 1289118](https://python-all.ru/3.2/whatsnew/3.2.html), [выпуске 5094](https://python-all.ru/3.2/whatsnew/3.2.html), [выпуске 6641](https://python-all.ru/3.2/whatsnew/3.2.html), [выпуске 2706](https://python-all.ru/3.2/whatsnew/3.2.html), [выпуске 1777412](https://python-all.ru/3.2/whatsnew/3.2.html), [выпуске 8013](https://python-all.ru/3.2/whatsnew/3.2.html), и [выпуске 10827](https://python-all.ru/3.2/whatsnew/3.2.html).)

### math

Модуль [`math`](https://python-all.ru/3.2/library/math.html#module-math) был обновлён и теперь содержит шесть новых функций, вдохновлённых стандартом C99.

Функция [`isfinite()`](https://python-all.ru/3.2/library/math.html#math.isfinite) предоставляет надёжный и быстрый способ обнаружения особых значений. Она возвращает *True* для обычных чисел и *False* для *Nan* или *Infinity*:

```python
>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]
[True, True, False, False]
```

Функция [`expm1()`](https://python-all.ru/3.2/library/math.html#math.expm1) вычисляет `e**x-1` для малых значений *x* без потери точности, которая обычно сопровождает вычитание почти равных величин:

```python
>>> expm1(0.013671875)   # более точный способ вычисления e**x-1 для малых x
0.013765762467652909
```

Функция [`erf()`](https://python-all.ru/3.2/library/math.html#math.erf) вычисляет интеграл вероятности или [функцию ошибок Гаусса](https://python-all.ru/3.2/whatsnew/3.2.html). Дополнительная функция ошибок, [`erfc()`](https://python-all.ru/3.2/library/math.html#math.erfc), равна `1 - erf(x)`:

```python
>>> erf(1.0/sqrt(2.0))   # доля нормального распределения в пределах одного стандартного отклонения
0.682689492137086
>>> erfc(1.0/sqrt(2.0))  # доля нормального распределения за пределами одного стандартного отклонения
0.31731050786291404
>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))
1.0
```

Функция [`gamma()`](https://python-all.ru/3.2/library/math.html#math.gamma) является непрерывным расширением факториала. Подробнее см. [http://en.wikipedia.org/wiki/Gamma\_function](https://python-all.ru/3.2/whatsnew/3.2.html). Поскольку функция связана с факториалами, она быстро растёт даже при малых значениях *x*, поэтому существует также функция [`lgamma()`](https://python-all.ru/3.2/library/math.html#math.lgamma) для вычисления натурального логарифма гамма-функции:

```python
>>> gamma(7.0)           # шесть факториал
720.0
>>> lgamma(801.0)        # логарифм факториала 800
4551.950730698041
```

(Автор: Mark Dickinson.)

### abc

Модуль [`abc`](https://python-all.ru/3.2/library/abc.html#module-abc) теперь поддерживает [`abstractclassmethod()`](https://python-all.ru/3.2/library/abc.html#abc.abstractclassmethod) и [`abstractstaticmethod()`](https://python-all.ru/3.2/library/abc.html#abc.abstractstaticmethod).

Эти инструменты позволяют определить [*абстрактный базовый класс*](https://python-all.ru/3.2/glossary.html#term-abstract-base-class), который требует реализации определённого [`classmethod()`](https://python-all.ru/3.2/library/functions.html#classmethod) или [`staticmethod()`](https://python-all.ru/3.2/library/functions.html#staticmethod):

```python
class Temperature(metaclass=abc.ABCMeta):
    @abc.abstractclassmethod
    def from_fahrenheit(cls, t):
        ...
    @abc.abstractclassmethod
    def from_celsius(cls, t):
        ...
```

(Патч предоставлен Дэниелом Урбаном; [выпуск 5867](https://python-all.ru/3.2/whatsnew/3.2.html).)

### io

У [`io.BytesIO`](https://python-all.ru/3.2/library/io.html#io.BytesIO) появился новый метод [`getbuffer()`](https://python-all.ru/3.2/library/io.html#io.BytesIO.getbuffer), который предоставляет функциональность, аналогичную [`memoryview()`](https://python-all.ru/3.2/library/stdtypes.html#memoryview). Он создаёт редактируемое представление данных без создания копии. Произвольный доступ к буферу и поддержка срезов хорошо подходят для редактирования на месте:

```python
>>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11

>>> def change_location(buffer, record_number, location):
        start = record_number * REC_LEN + LOC_START
        buffer[start: start+LOC_LEN] = location

>>> import io

>>> byte_stream = io.BytesIO(
    b'G3805  storeroom  Main chassis    '
    b'X7899  shipping   Reserve cog     '
    b'L6988  receiving  Primary sprocket'
)
>>> buffer = byte_stream.getbuffer()
>>> change_location(buffer, 1, b'warehouse  ')
>>> change_location(buffer, 0, b'showroom   ')
>>> print(byte_stream.getvalue())
b'G3805  showroom   Main chassis    '
b'X7899  warehouse  Reserve cog     '
b'L6988  receiving  Primary sprocket'
```

(Предложено Антуаном Питру в [выпуске 5506](https://python-all.ru/3.2/whatsnew/3.2.html).)

### reprlib

При написании метода [`__repr__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__repr__) для пользовательского контейнера легко забыть обработать случай, когда элемент ссылается обратно на сам контейнер. Встроенные объекты Python, такие как [`list`](https://python-all.ru/3.2/library/functions.html#list) и [`set`](https://python-all.ru/3.2/library/stdtypes.html#set), обрабатывают самоссылки, отображая ”...” в рекурсивной части строки представления.

Чтобы упростить написание таких методов [`__repr__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__repr__), в модуле [`reprlib`](https://python-all.ru/3.2/library/reprlib.html#module-reprlib) появился новый декоратор [`recursive_repr()`](https://python-all.ru/3.2/library/reprlib.html#reprlib.recursive_repr) для обнаружения рекурсивных вызовов [`__repr__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__repr__) и подстановки вместо них строки-заполнителя:

```python
>>> class MyList(list):
        @recursive_repr()
        def __repr__(self):
            return '<' + '|'.join(map(repr, self)) + '>'

>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>
```

(Предложено Рэймондом Хеттингером в [выпуске 9826](https://python-all.ru/3.2/whatsnew/3.2.html) и [выпуске 9840](https://python-all.ru/3.2/whatsnew/3.2.html).)

### logging

В дополнение к описанной выше конфигурации на основе словаря пакет [`logging`](https://python-all.ru/3.2/library/logging.html#module-logging) содержит множество других улучшений.

Документация по logging была дополнена [*базовым руководством*](https://python-all.ru/3.2/howto/logging.html#logging-basic-tutorial), [*продвинутым руководством*](https://python-all.ru/3.2/howto/logging.html#logging-advanced-tutorial) и [*поваренной книгой*](https://python-all.ru/3.2/howto/logging-cookbook.html#logging-cookbook) с рецептами логирования. Эти документы – самый быстрый способ изучить логирование.

Функция настройки [`logging.basicConfig()`](https://python-all.ru/3.2/library/logging.html#logging.basicConfig) получила аргумент *style* для поддержки трёх различных типов форматирования строк. По умолчанию используется “%” для традиционного %-форматирования, может быть установлено “{” для нового стиля [`str.format()`](https://python-all.ru/3.2/library/stdtypes.html#str.format), или “$” для форматирования в стиле оболочки, предоставляемого [`string.Template`](https://python-all.ru/3.2/library/string.html#string.Template). Следующие три конфигурации эквивалентны:

```python
>>> from logging import basicConfig
>>> basicConfig(style='%', format="%(name)s -> %(levelname)s: %(message)s")
>>> basicConfig(style='{', format="{name} -> {levelname} {message}")
>>> basicConfig(style='$', format="$name -> $levelname: $message")
```

Если до возникновения события логирования не задана конфигурация, теперь используется конфигурация по умолчанию с [`StreamHandler`](https://python-all.ru/3.2/library/logging.handlers.html#logging.StreamHandler), направленным в [`sys.stderr`](https://python-all.ru/3.2/library/sys.html#sys.stderr), для событий уровня `WARNING` и выше. Ранее событие, возникшее до настройки конфигурации, либо вызывало исключение, либо молча отбрасывалось в зависимости от значения `logging.raiseExceptions`. Новый обработчик по умолчанию хранится в [`logging.lastResort`](https://python-all.ru/3.2/library/logging.html#logging.lastResort).

Использование фильтров было упрощено. Вместо создания объекта [`Filter`](https://python-all.ru/3.2/library/logging.html#logging.Filter) предикатом может быть любой вызываемый объект Python, возвращающий *True* или *False*.

Было сделано множество других улучшений, повышающих гибкость и упрощающих конфигурацию. Полный список изменений в Python 3.2 смотрите в документации модуля.

### csv

Модуль [`csv`](https://python-all.ru/3.2/library/csv.html#module-csv) теперь поддерживает новый диалект, [`unix_dialect`](https://python-all.ru/3.2/library/csv.html#csv.unix_dialect), который применяет кавычки для всех полей и использует традиционный стиль Unix с `'\n'` в качестве разделителя строк. Зарегистрированное имя диалекта – `unix`.

У [`csv.DictWriter`](https://python-all.ru/3.2/library/csv.html#csv.DictWriter) появился новый метод [`writeheader()`](https://python-all.ru/3.2/library/csv.html#csv.DictWriter.writeheader) для записи начальной строки с названиями полей:

```python
>>> import csv, sys
>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')
>>> w.writeheader()
"name","dept"
>>> w.writerows([
        {'name': 'tom', 'dept': 'accounting'},
        {'name': 'susan', 'dept': 'Salesl'}])
"tom","accounting"
"susan","sales"
```

(Новый диалект предложен Джеем Талботом в [выпуске 5975](https://python-all.ru/3.2/whatsnew/3.2.html), а новый метод предложен Эдом Абрахамом в [выпуске 1537721](https://python-all.ru/3.2/whatsnew/3.2.html).)

### contextlib

Появился новый и немного умопомрачительный инструмент [`ContextDecorator`](https://python-all.ru/3.2/library/contextlib.html#contextlib.ContextDecorator), который полезен для создания [*менеджера контекста*](https://python-all.ru/3.2/glossary.html#term-context-manager), выполняющего двойную роль декоратора функции.

Для удобства эта новая функциональность используется [`contextmanager()`](https://python-all.ru/3.2/library/contextlib.html#contextlib.contextmanager), поэтому не требуется дополнительных усилий для поддержки обеих ролей.

Основная идея в том, что и менеджеры контекста, и декораторы функций могут использоваться для обёрток до и после действия. Менеджеры контекста оборачивают группу инструкций с помощью оператора [`with`](https://python-all.ru/3.2/reference/compound_stmts.html#with), а декораторы функций оборачивают группу инструкций, заключённых в функцию. Поэтому иногда возникает необходимость написать обёртку до или после действия, которую можно использовать в любой роли.

Например, иногда полезно оборачивать функции или группы инструкций логгером, который может отслеживать время входа и время выхода. Вместо того чтобы писать и декоратор функции, и менеджер контекста для этой задачи, [`contextmanager()`](https://python-all.ru/3.2/library/contextlib.html#contextlib.contextmanager) предоставляет обе возможности в одном определении:

```python
from contextlib import contextmanager
import logging

logging.basicConfig(level=logging.INFO)

@contextmanager
def track_entry_and_exit(name):
    logging.info('Entering: {}'.format(name))
    yield
    logging.info('Exiting: {}'.format(name))
```

Ранее это можно было использовать только как менеджер контекста:

```python
with track_entry_and_exit('widget loader'):
    print('Some time consuming activity goes here')
    load_widget()
```

Теперь его можно использовать и как декоратор:

```python
@track_entry_and_exit('widget loader')
def activity():
    print('Some time consuming activity goes here')
    load_widget()
```

Попытка выполнять две роли одновременно накладывает некоторые ограничения на технику. Менеджеры контекста обычно имеют возможность возвращать аргумент, используемый оператором [`with`](https://python-all.ru/3.2/reference/compound_stmts.html#with), но для декораторов функций такой аналогии нет.

В приведённом выше примере нет чистого способа для менеджера контекста *track\_entry\_and\_exit* вернуть экземпляр логгера для использования в теле вложенных операторов.

(Предложено Майклом Фордом в [выпуске 9110](https://python-all.ru/3.2/whatsnew/3.2.html).)

### decimal and fractions

Марк Дикинсон разработал элегантную и эффективную схему, гарантирующую, что разные числовые типы данных будут иметь одинаковое хэш-значение всякий раз, когда их фактические значения равны ([выпуск 8188](https://python-all.ru/3.2/whatsnew/3.2.html)):

```python
assert hash(Fraction(3, 2)) == hash(1.5) == \
       hash(Decimal("1.5")) == hash(complex(1.5, 0))
```

Некоторые детали хэширования раскрываются через новый атрибут [`sys.hash_info`](https://python-all.ru/3.2/library/sys.html#sys.hash_info), который описывает разрядность хэш-значения, простой модуль, хэш-значения для *бесконечности* и *nan*, а также множитель, используемый для мнимой части числа:

```python
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)
```

Раннее решение ограничить совместимость различных числовых типов было смягчено. По-прежнему не поддерживается (и не рекомендуется) неявное смешивание в арифметических выражениях, таких как `Decimal('1.1') + float('1.1')`, поскольку последнее теряет информацию в процессе построения двоичного числа с плавающей точкой. Однако, поскольку существующее значение с плавающей точкой может быть без потерь преобразовано в десятичное или рациональное представление, имеет смысл добавить их в конструктор и поддерживать сравнения смешанных типов.

- Конструктор [`decimal.Decimal`](https://python-all.ru/3.2/library/decimal.html#decimal.Decimal) теперь принимает объекты [`float`](https://python-all.ru/3.2/library/functions.html#float) напрямую, поэтому больше нет необходимости использовать метод [`from_float()`](https://python-all.ru/3.2/library/decimal.html#decimal.Decimal.from_float) ([выпуск 8257](https://python-all.ru/3.2/whatsnew/3.2.html)).
- Сравнения смешанных типов теперь полностью поддерживаются, так что объекты [`Decimal`](https://python-all.ru/3.2/library/decimal.html#decimal.Decimal) можно напрямую сравнивать с [`float`](https://python-all.ru/3.2/library/functions.html#float) и [`fractions.Fraction`](https://python-all.ru/3.2/library/fractions.html#fractions.Fraction) ([выпуск 2531](https://python-all.ru/3.2/whatsnew/3.2.html) и [выпуск 8188](https://python-all.ru/3.2/whatsnew/3.2.html)).

Аналогичные изменения были внесены в [`fractions.Fraction`](https://python-all.ru/3.2/library/fractions.html#fractions.Fraction), поэтому методы [`from_float()`](https://python-all.ru/3.2/library/fractions.html#fractions.Fraction.from_float) и [`from_decimal()`](https://python-all.ru/3.2/library/fractions.html#fractions.Fraction.from_decimal) больше не нужны ([issue 8294](https://python-all.ru/3.2/whatsnew/3.2.html)):

```python
>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)
```

Ещё одно полезное изменение для модуля [`decimal`](https://python-all.ru/3.2/library/decimal.html#module-decimal) заключается в том, что атрибут `Context.clamp` теперь стал общедоступным. Это полезно для создания контекстов, соответствующих форматам обмена десятичными числами, определённым в IEEE 754 (см. [issue 8540](https://python-all.ru/3.2/whatsnew/3.2.html)).

(Авторы: Mark Dickinson и Raymond Hettinger.)

### ftp

Класс [`ftplib.FTP`](https://python-all.ru/3.2/library/ftplib.html#ftplib.FTP) теперь поддерживает протокол контекстного менеджера, чтобы безусловно перехватывать исключения [`socket.error`](https://python-all.ru/3.2/library/socket.html#socket.error) и закрывать FTP соединение по завершении:

```python
>>> from ftplib import FTP
>>> with FTP("ftp1.at.proftpd.org") as ftp:
        ftp.login()
        ftp.dir()

'230 Anonymous login ok, restrictions apply.'
dr-xr-xr-x   9 ftp      ftp           154 May  6 10:43 .
dr-xr-xr-x   9 ftp      ftp           154 May  6 10:43 ..
dr-xr-xr-x   5 ftp      ftp          4096 May  6 10:43 CentOS
dr-xr-xr-x   3 ftp      ftp            18 Jul 10  2008 Fedora
```

Other file-like objects such as [`mmap.mmap`](https://python-all.ru/3.2/library/mmap.html#mmap.mmap) and [`fileinput.input()`](https://python-all.ru/3.2/library/fileinput.html#fileinput.input) also grew auto-closing context managers:

```python
with fileinput.input(files=('log1.txt', 'log2.txt')) as f:
    for line in f:
        process(line)
```

(Авторы: Tarek Ziadé и Giampaolo Rodolà ([issue 4972](https://python-all.ru/3.2/whatsnew/3.2.html)), а также Georg Brandl ([issue 8046](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 1286](https://python-all.ru/3.2/whatsnew/3.2.html)).)

Класс [`FTP_TLS`](https://python-all.ru/3.2/library/ftplib.html#ftplib.FTP_TLS) теперь принимает параметр *context*, который является объектом [`ssl.SSLContext`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLContext), позволяющим объединять параметры конфигурации SSL, сертификаты и закрытые ключи в единую (потенциально долгоживущую) структуру.

(Автор: Giampaolo Rodolà; [issue 8806](https://python-all.ru/3.2/whatsnew/3.2.html).)

### popen

Функции `os.popen()` и [`subprocess.Popen()`](https://python-all.ru/3.2/library/subprocess.html#subprocess.Popen) теперь поддерживают инструкции [`with`](https://python-all.ru/3.2/reference/compound_stmts.html#with) для автоматического закрытия файловых дескрипторов.

(Авторы: Antoine Pitrou и Brian Curtin в [issue 7461](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 10554](https://python-all.ru/3.2/whatsnew/3.2.html).)

### select

Модуль [`select`](https://python-all.ru/3.2/library/select.html#module-select) теперь предоставляет новый постоянный атрибут [`PIPE_BUF`](https://python-all.ru/3.2/library/select.html#select.PIPE_BUF), который указывает минимальное количество байтов, гарантированно не вызывающих блокировку, когда [`select.select()`](https://python-all.ru/3.2/library/select.html#select.select) сообщает, что канал готов к записи.

```python
>>> import select
>>> select.PIPE_BUF
512
```

(Доступно в Unix-системах. Патч от Sébastien Sablé в [issue 9862](https://python-all.ru/3.2/whatsnew/3.2.html))

### gzip и zipfile

[`gzip.GzipFile`](https://python-all.ru/3.2/library/gzip.html#gzip.GzipFile) теперь реализует [`io.BufferedIOBase`](https://python-all.ru/3.2/library/io.html#io.BufferedIOBase) [*абстрактный базовый класс*](https://python-all.ru/3.2/glossary.html#term-abstract-base-class) (за исключением `truncate()`). Он также имеет метод [`peek()`](https://python-all.ru/3.2/library/gzip.html#gzip.GzipFile.peek) и поддерживает непозиционируемые и дополненные нулями файловые объекты.

Модуль [`gzip`](https://python-all.ru/3.2/library/gzip.html#module-gzip) также обзавёлся функциями [`compress()`](https://python-all.ru/3.2/library/gzip.html#gzip.compress) и [`decompress()`](https://python-all.ru/3.2/library/gzip.html#gzip.decompress) для более удобного сжатия и распаковки в памяти. Имейте в виду, что текст должен быть закодирован как [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes) перед сжатием и распаковкой:

```python
>>> s = 'Three shall be the number thou shalt count, '
>>> s += 'and the number of the counting shall be three'
>>> b = s.encode()                        # преобразовать в utf-8
>>> len(b)
89
>>> c = gzip.compress(b)
>>> len(c)
77
>>> gzip.decompress(c).decode()[:42]      # распаковать и преобразовать в текст
'Three shall be the number thou shalt count,'
```

(Авторы: Anand B. Pillai ([issue 3488](https://python-all.ru/3.2/whatsnew/3.2.html)); а также Antoine Pitrou, Nir Aides и Brian Curtin ([issue 9962](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 1675951](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 7471](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 2846](https://python-all.ru/3.2/whatsnew/3.2.html)).)

Кроме того, класс `zipfile.ZipExtFile` был переработан для представления файлов, хранящихся внутри архива. Новая реализация значительно быстрее и может быть обёрнута в объект [`io.BufferedReader`](https://python-all.ru/3.2/library/io.html#io.BufferedReader) для дополнительного ускорения. Она также решает проблему, при которой перемежающиеся вызовы *read* и *readline* давали неверные результаты.

(Патч предоставлен Nir Aides в [issue 7610](https://python-all.ru/3.2/whatsnew/3.2.html).)

### tarfile

Класс [`TarFile`](https://python-all.ru/3.2/library/tarfile.html#tarfile.TarFile) теперь можно использовать как менеджер контекста. Кроме того, его метод [`add()`](https://python-all.ru/3.2/library/tarfile.html#tarfile.TarFile.add) получил новую опцию *filter*, которая управляет тем, какие файлы добавляются в архив, и позволяет редактировать метаданные файлов.

Новая опция *filter* заменяет старый, менее гибкий параметр *exclude*, который теперь считается устаревшим. Если указан, необязательный параметр *filter* должен быть [*именованным аргументом*](https://python-all.ru/3.2/glossary.html#term-keyword-argument). Предоставленная пользователем функция фильтрации принимает объект [`TarInfo`](https://python-all.ru/3.2/library/tarfile.html#tarfile.TarInfo) и возвращает обновлённый объект [`TarInfo`](https://python-all.ru/3.2/library/tarfile.html#tarfile.TarInfo); если файл нужно исключить, функция может вернуть *None*:

```python
>>> import tarfile, glob

>>> def myfilter(tarinfo):
       if tarinfo.isfile():             # only save real files
            tarinfo.uname = 'monty'     # redact the user name
            return tarinfo

>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
        for filename in glob.glob('*.txt'):
            tf.add(filename, filter=myfilter)
        tf.list()
-rw-r--r-- monty/501        902 2011-01-26 17:59:11 annotations.txt
-rw-r--r-- monty/501        123 2011-01-26 17:59:11 general_questions.txt
-rw-r--r-- monty/501       3514 2011-01-26 17:59:11 prion.txt
-rw-r--r-- monty/501        124 2011-01-26 17:59:11 py_todo.txt
-rw-r--r-- monty/501       1399 2011-01-26 17:59:11 semaphore_notes.txt
```

(Предложено Tarek Ziadé, реализовано Lars Gustäbel в [issue 6856](https://python-all.ru/3.2/whatsnew/3.2.html).)

### hashlib

Модуль [`hashlib`](https://python-all.ru/3.2/library/hashlib.html#module-hashlib) имеет два новых постоянных атрибута, перечисляющих алгоритмы хеширования, которые гарантированно присутствуют во всех реализациях, и те, что доступны в текущей реализации:

```python
>>> import hashlib

>>> hashlib.algorithms_guaranteed
{'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}

>>> hashlib.algorithms_available
{'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',
'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',
'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',
'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}
```

(Предложено Carl Chenet в [issue 7418](https://python-all.ru/3.2/whatsnew/3.2.html).)

### ast

Модуль [`ast`](https://python-all.ru/3.2/library/ast.html#module-ast) содержит замечательный универсальный инструмент для безопасного вычисления строк выражений с использованием синтаксиса литералов Python. Функция [`ast.literal_eval()`](https://python-all.ru/3.2/library/ast.html#ast.literal_eval) служит безопасной альтернативой встроенной функции [`eval()`](https://python-all.ru/3.2/library/functions.html#eval), которой легко злоупотребить. Python 3.2 добавляет литералы [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes) и [`set`](https://python-all.ru/3.2/library/stdtypes.html#set) в список поддерживаемых типов: строки, байты, числа, кортежи, списки, словари, множества, булевы значения и None.

```python
>>> from ast import literal_eval

>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
>>> literal_eval(request)
{'args': (2, 0.5), 'req': 3, 'func': 'pow'}

>>> request = "os.system('do something harmful')"
>>> literal_eval(request)
Traceback (most recent call last):
  ...
ValueError: malformed node or string: <_ast.Call object at 0x101739a10>
```

(Реализовано Бенджамином Петерсоном и Георгом Брандлем.)

### os

В разных операционных системах используются различные кодировки для имён файлов и переменных окружения. Модуль [`os`](https://python-all.ru/3.2/library/os.html#module-os) предоставляет две новые функции, [`fsencode()`](https://python-all.ru/3.2/library/os.html#os.fsencode) и [`fsdecode()`](https://python-all.ru/3.2/library/os.html#os.fsdecode), для кодирования и декодирования имён файлов:

```python
>>> filename = 'Sehenswürdigkeiten'
>>> os.fsencode(filename)
b'Sehensw\xc3\xbcrdigkeiten'
```

Некоторые операционные системы разрешают прямой доступ к закодированным байтам в окружении. В таком случае константа [`os.supports_bytes_environ`](https://python-all.ru/3.2/library/os.html#os.supports_bytes_environ) будет равна true.

For direct access to encoded environment variables (if available), use the new [`os.getenvb()`](https://python-all.ru/3.2/library/os.html#os.getenvb) function or use [`os.environb`](https://python-all.ru/3.2/library/os.html#os.environb) which is a bytes version of [`os.environ`](https://python-all.ru/3.2/library/os.html#os.environ).

(Автор: Victor Stinner.)

### shutil

Функция [`shutil.copytree()`](https://python-all.ru/3.2/library/shutil.html#shutil.copytree) получила две новые опции:

- *ignore\_dangling\_symlinks*: когда `symlinks=False`, функция копирует файл, на который указывает символическая ссылка, а не саму ссылку. Эта опция подавляет ошибку, возникающую, если файл не существует.
- *copy\_function*: вызываемый объект, который будет использоваться для копирования файлов. По умолчанию используется [`shutil.copy2()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy2).

(Автор: Tarek Ziadé.)

Кроме того, модуль [`shutil`](https://python-all.ru/3.2/library/shutil.html#module-shutil) теперь поддерживает [*операции архивирования*](https://python-all.ru/3.2/library/shutil.html#archiving-operations) для файлов ZIP, несжатых файлов TAR, а также файлов TAR, сжатых с помощью gzip и bzip2. Также есть функции для регистрации дополнительных форматов архивов (например, файлов TAR, сжатых с помощью xz, или пользовательских форматов).

Основными функциями являются [`make_archive()`](https://python-all.ru/3.2/library/shutil.html#shutil.make_archive) и [`unpack_archive()`](https://python-all.ru/3.2/library/shutil.html#shutil.unpack_archive). По умолчанию обе работают с текущим каталогом (который можно задать с помощью [`os.chdir()`](https://python-all.ru/3.2/library/os.html#os.chdir)) и со всеми подкаталогами. Имя файла архива должно быть указано с полным путём. Операция архивирования не является разрушительной (исходные файлы остаются без изменений).

```python
>>> import shutil, pprint

>>> os.chdir('mydata')                               # перейти в каталог исходного кода
>>> f = shutil.make_archive('/var/backup/mydata',
                            'zip')                   # archive the current directory
>>> f                                                # показать имя архива
'/var/backup/mydata.zip'
>>> os.chdir('tmp')                                  # перейти к распаковке
>>> shutil.unpack_archive('/var/backup/mydata.zip')  # восстановить данные

>>> pprint.pprint(shutil.get_archive_formats())      # отобразить известные форматы
[('bztar', "bzip2'ed tar-file"),
 ('gztar', "gzip'ed tar-file"),
 ('tar', 'uncompressed tar file'),
 ('zip', 'ZIP file')]

>>> shutil.register_archive_format(                  # зарегистрировать новый формат архива
        name = 'xz',
        function = xz.compress,                      # callable archiving function
        extra_args = [('level', 8)],                 # arguments to the function
        description = 'xz compression'
)
```

(Автор: Tarek Ziadé.)

### sqlite3

Модуль [`sqlite3`](https://python-all.ru/3.2/library/sqlite3.html#module-sqlite3) был обновлён до версии pysqlite 2.6.0. У него появились две новые возможности.

- Атрибут `sqlite3.Connection.in_transit` равен true, если есть активная транзакция с незафиксированными изменениями.
- Методы [`sqlite3.Connection.enable_load_extension()`](https://python-all.ru/3.2/library/sqlite3.html#sqlite3.Connection.enable_load_extension) и [`sqlite3.Connection.load_extension()`](https://python-all.ru/3.2/library/sqlite3.html#sqlite3.Connection.load_extension) позволяют загружать расширения SQLite из файлов ”.so”. Одно из известных расширений – это расширение полнотекстового поиска, распространяемое вместе с SQLite.

(Авторы: R. David Murray и Shashwat Anand; [issue 8845](https://python-all.ru/3.2/whatsnew/3.2.html).)

### html

Был добавлен новый модуль [`html`](https://python-all.ru/3.2/library/html.html#module-html) с единственной функцией [`escape()`](https://python-all.ru/3.2/library/html.html#html.escape), которая используется для экранирования зарезервированных символов в HTML-разметке:

```python
>>> import html
>>> html.escape('x > 2 && x < 7')
'x &gt; 2 &amp;&amp; x &lt; 7'
```

### socket

В модуле [`socket`](https://python-all.ru/3.2/library/socket.html#module-socket) появилось два улучшения.

- У объектов сокетов теперь есть метод [`detach()`](https://python-all.ru/3.2/library/socket.html#socket.socket.detach), который переводит сокет в закрытое состояние без фактического закрытия нижележащего файлового дескриптора. Последний затем можно использовать повторно для других целей. (Добавлено Antoine Pitrou; [issue 8524](https://python-all.ru/3.2/whatsnew/3.2.html).)
- [`socket.create_connection()`](https://python-all.ru/3.2/library/socket.html#socket.create_connection) теперь поддерживает протокол контекстного менеджера, чтобы безусловно перехватывать исключения [`socket.error`](https://python-all.ru/3.2/library/socket.html#socket.error) и закрывать сокет по завершении. (Автор: Giampaolo Rodolà; [issue 9794](https://python-all.ru/3.2/whatsnew/3.2.html).)

### ssl

Модуль [`ssl`](https://python-all.ru/3.2/library/ssl.html#module-ssl) добавил ряд возможностей для удовлетворения общих требований безопасных (шифрованных, аутентифицированных) интернет-соединений:

- Новый класс [`SSLContext`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLContext) служит контейнером для постоянных данных SSL, таких как настройки протокола, сертификаты, закрытые ключи и различные другие параметры. Он включает метод [`wrap_socket()`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLContext.wrap_socket) для создания SSL-сокета из SSL-контекста.
- Новая функция [`ssl.match_hostname()`](https://python-all.ru/3.2/library/ssl.html#ssl.match_hostname) поддерживает проверку подлинности сервера для протоколов более высокого уровня, реализуя правила HTTPS (из [**RFC 2818**](https://python-all.ru/3.2/whatsnew/3.2.html)), которые также подходят для других протоколов.
- Функция-конструктор [`ssl.wrap_socket()`](https://python-all.ru/3.2/library/ssl.html#ssl.wrap_socket) теперь принимает аргумент *ciphers*. Строка *ciphers* перечисляет разрешённые алгоритмы шифрования в формате, описанном в [документации OpenSSL](https://python-all.ru/3.2/whatsnew/3.2.html).
- При сборке с новыми версиями OpenSSL модуль [`ssl`](https://python-all.ru/3.2/library/ssl.html#module-ssl) теперь поддерживает расширение Server Name Indication протокола TLS, позволяющее использовать несколько «виртуальных хостов» с разными сертификатами на одном IP-порту. Это расширение поддерживается только в режиме клиента и активируется передачей аргумента *server\_hostname* в [`ssl.SSLContext.wrap_socket()`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLContext.wrap_socket).
- В модуль [`ssl`](https://python-all.ru/3.2/library/ssl.html#module-ssl) были добавлены различные параметры, такие как [`OP_NO_SSLv2`](https://python-all.ru/3.2/library/ssl.html#ssl.OP_NO_SSLv2), который отключает небезопасный и устаревший протокол SSLv2.
- Расширение теперь загружает все шифры и алгоритмы дайджестов OpenSSL. Если некоторые SSL-сертификаты не удаётся проверить, они сообщаются как ошибка «неизвестный алгоритм».
- Версию используемой OpenSSL теперь можно получить через атрибуты модуля [`ssl.OPENSSL_VERSION`](https://python-all.ru/3.2/library/ssl.html#ssl.OPENSSL_VERSION) (строка), [`ssl.OPENSSL_VERSION_INFO`](https://python-all.ru/3.2/library/ssl.html#ssl.OPENSSL_VERSION_INFO) (кортеж из 5 элементов) и [`ssl.OPENSSL_VERSION_NUMBER`](https://python-all.ru/3.2/library/ssl.html#ssl.OPENSSL_VERSION_NUMBER) (целое число).

(Автор: Antoine Pitrou; [issue 8850](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 1589](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 8322](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 5639](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 4870](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 8484](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 8321](https://python-all.ru/3.2/whatsnew/3.2.html).)

### nntp

Модуль [`nntplib`](https://python-all.ru/3.2/library/nntplib.html#module-nntplib) получил переработанную реализацию с улучшенной семантикой байтов и текста, а также более практичными API. Эти улучшения нарушают совместимость с версией nntplib в Python 3.1, которая сама по себе была частично неработоспособной.

Также была добавлена поддержка безопасных соединений как через неявный (с помощью [`nntplib.NNTP_SSL`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP_SSL)), так и явный (с помощью [`nntplib.NNTP.starttls()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.starttls)) TLS.

(Авторы: Antoine Pitrou ([issue 9360](https://python-all.ru/3.2/whatsnew/3.2.html)) и Andrew Vant ([issue 1926](https://python-all.ru/3.2/whatsnew/3.2.html)).)

### сертификаты

[`http.client.HTTPSConnection`](https://python-all.ru/3.2/library/http.client.html#http.client.HTTPSConnection), [`urllib.request.HTTPSHandler`](https://python-all.ru/3.2/library/urllib.request.html#urllib.request.HTTPSHandler) и [`urllib.request.urlopen()`](https://python-all.ru/3.2/library/urllib.request.html#urllib.request.urlopen) теперь принимают необязательные аргументы для проверки сертификата сервера относительно набора центров сертификации, как рекомендуется при публичном использовании HTTPS.

(Добавлено Antoine Pitrou, [issue 9003](https://python-all.ru/3.2/whatsnew/3.2.html).)

### imaplib

Поддержка явного TLS для стандартных IMAP4-соединений была добавлена через новый метод [`imaplib.IMAP4.starttls`](https://python-all.ru/3.2/library/imaplib.html#imaplib.IMAP4.starttls).

(Авторы: Lorenzo M. Catucci и Antoine Pitrou, [issue 4471](https://python-all.ru/3.2/whatsnew/3.2.html).)

### http.client

В модуле [`http.client`](https://python-all.ru/3.2/library/http.client.html#module-http.client) был сделан ряд небольших улучшений API. Устаревшие простые ответы HTTP 0.9 больше не поддерживаются, а параметр *strict* объявлен устаревшим во всех классах.

Классы [`HTTPConnection`](https://python-all.ru/3.2/library/http.client.html#http.client.HTTPConnection) и [`HTTPSConnection`](https://python-all.ru/3.2/library/http.client.html#http.client.HTTPSConnection) теперь имеют параметр *source\_address*, представляющий собой кортеж (host, port), указывающий, откуда устанавливается HTTP-соединение.

Добавлена поддержка проверки сертификатов и виртуальных хостов HTTPS в [`HTTPSConnection`](https://python-all.ru/3.2/library/http.client.html#http.client.HTTPSConnection).

Метод [`request()`](https://python-all.ru/3.2/library/http.client.html#http.client.HTTPConnection.request) у объектов соединения принимал необязательный аргумент *body*, чтобы можно было использовать [*файловый объект*](https://python-all.ru/3.2/glossary.html#term-file-object) для передачи содержимого запроса. Теперь же аргумент *body* также принимает [*итерируемый объект*](https://python-all.ru/3.2/glossary.html#term-iterable), при условии, что он содержит явный заголовок `Content-Length`. Этот расширенный интерфейс стал гораздо более гибким.

Для установки HTTPS-соединения через прокси-сервер появился новый метод [`set_tunnel()`](https://python-all.ru/3.2/library/http.client.html#http.client.HTTPConnection.set_tunnel), который задаёт хост и порт для туннелирования HTTP Connect.

Для соответствия поведению [`http.server`](https://python-all.ru/3.2/library/http.server.html#module-http.server) библиотека HTTP-клиента теперь также кодирует заголовки в кодировке ISO-8859-1 (Latin-1). Для входящих заголовков она уже это делала, так что теперь поведение согласовано для входящего и исходящего трафика. (См. работу Armin Ronacher в [issue 10980](https://python-all.ru/3.2/whatsnew/3.2.html).)

### unittest

Модуль unittest получил ряд улучшений: поддержка обнаружения тестов для пакетов, более простое экспериментирование в интерактивной оболочке, новые методы тестовых случаев, улучшенные диагностические сообщения при сбоях тестов и более понятные имена методов.

- Вызов из командной строки `python -m unittest` теперь может принимать пути к файлам вместо имён модулей для запуска конкретных тестов ([issue 10620](https://python-all.ru/3.2/whatsnew/3.2.html)). Новая система обнаружения тестов может находить тесты внутри пакетов, находя любой тест, импортируемый из корневой директории. Корневая директория может быть задана опцией *-t*, шаблон для сопоставления файлов – с помощью `-p`, а директория для начала поиска – с помощью `-s`:

  ```python
  $ python -m unittest discover -s my_proj_dir -p _test.py
  ```

  (Предложено Michael Foord.)
- Экспериментировать в интерактивной оболочке стало проще, поскольку класс `unittest.case.TestCase` теперь можно создавать без аргументов:

  ```python
  >>> TestCase().assertEqual(pow(2, 3), 8)
  ```

  (Предложено Michael Foord.)
- В модуле [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) появились два новых метода: [`assertWarns()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarns) и [`assertWarnsRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarnsRegex), которые проверяют, что заданный тип предупреждения вызывается тестируемым кодом:

  ```python
  with self.assertWarns(DeprecationWarning):
      legacy_function('XYZ')
  ```

  (Автор: Antoine Pitrou, [issue 9754](https://python-all.ru/3.2/whatsnew/3.2.html).)

  Ещё один новый метод, [`assertCountEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertCountEqual), используется для сравнения двух итерируемых объектов, чтобы определить, равны ли количества их элементов (то есть одинаковые ли элементы присутствуют с одинаковым числом вхождений, независимо от порядка):

  ```python
  def test_anagram(self):
      self.assertCountEqual('algorithm', 'logarithm')
  ```

  (Автор: Raymond Hettinger.)
- Одной из ключевых особенностей модуля unittest является стремление выдавать информативную диагностику при сбое теста. Когда это возможно, сбой записывается вместе с diff (разницей) вывода. Это особенно полезно при анализе логов неудачных тестовых запусков. Однако, поскольку diff'ы могут быть объёмными, появился новый атрибут [`maxDiff`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.maxDiff), который задаёт максимальную длину отображаемых diff'ов.
- Кроме того, имена методов в модуле были приведены в порядок.

  Например, [`assertRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRegex) – это новое имя для `assertRegexpMatches()`, которое было названо неправильно, потому что тест использует [`re.search()`](https://python-all.ru/3.2/library/re.html#re.search), а не [`re.match()`](https://python-all.ru/3.2/library/re.html#re.match). Другие методы, использующие регулярные выражения, теперь названы с краткой формой «Regex» вместо «Regexp» – это соответствует именам в других реализациях unittest, совпадает со старым названием модуля [`re`](https://python-all.ru/3.2/library/re.html#module-re) в Python и имеет однозначное верблюжье написание.

  (Предложено Raymond Hettinger; реализовано Ezio Melotti.)
- Чтобы повысить согласованность, некоторые давно существующие псевдонимы методов объявляются устаревшими; вместо них следует использовать предпочтительные имена:

  > | Старое имя | Предпочтительное имя |
  > | --- | --- |
  > | `assert_()` | [`assertTrue()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertTrue) |
  > | `assertEquals()` | [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual) |
  > | `assertNotEquals()` | [`assertNotEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotEqual) |
  > | `assertAlmostEquals()` | [`assertAlmostEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertAlmostEqual) |
  > | `assertNotAlmostEquals()` | [`assertNotAlmostEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) |

  Аналогично, методы `TestCase.fail*`, устаревшие в Python 3.1, как ожидается, будут удалены в Python 3.3. См. также раздел [*Deprecated aliases*](https://python-all.ru/3.2/library/unittest.html#deprecated-aliases) в документации [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest).

  (Автор: Ezio Melotti; [issue 9424](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Метод [`assertDictContainsSubset()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertDictContainsSubset) был объявлен устаревшим, поскольку он был реализован с ошибкой: аргументы передавались в неправильном порядке. Это создавало трудноуловимые иллюзии, когда тесты вида `TestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1})` завершались неудачей.

  (Автор: Raymond Hettinger.)

### random

Целочисленные методы модуля [`random`](https://python-all.ru/3.2/library/random.html#module-random) теперь лучше обеспечивают равномерное распределение. Ранее они вычисляли выборки с помощью `int(n*random())`, что давало небольшое смещение, когда *n* не являлось степенью двойки. Теперь несколько выборок делаются из диапазона до следующей степени двойки, и выборка сохраняется только в том случае, если она попадает в диапазон `0 <= x < n`. Затронутые функции и методы: [`randrange()`](https://python-all.ru/3.2/library/random.html#random.randrange), [`randint()`](https://python-all.ru/3.2/library/random.html#random.randint), [`choice()`](https://python-all.ru/3.2/library/random.html#random.choice), [`shuffle()`](https://python-all.ru/3.2/library/random.html#random.shuffle) и [`sample()`](https://python-all.ru/3.2/library/random.html#random.sample).

(Автор: Raymond Hettinger; [issue 9025](https://python-all.ru/3.2/whatsnew/3.2.html).)

### poplib

Класс [`POP3_SSL`](https://python-all.ru/3.2/library/poplib.html#poplib.POP3_SSL) теперь принимает параметр *context*, который является объектом [`ssl.SSLContext`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLContext), позволяющим объединять параметры конфигурации SSL, сертификаты и закрытые ключи в одну (потенциально долгоживущую) структуру.

(Автор: Giampaolo Rodolà; [issue 8807](https://python-all.ru/3.2/whatsnew/3.2.html).)

### asyncore

[`asyncore.dispatcher`](https://python-all.ru/3.2/library/asyncore.html#asyncore.dispatcher) теперь предоставляет метод [`handle_accepted()`](https://python-all.ru/3.2/library/asyncore.html#asyncore.dispatcher.handle_accepted), возвращающий пару *(sock, addr)*. Этот метод вызывается при фактическом установлении соединения с новым удалённым узлом. Он предназначен для замены устаревшего метода [`handle_accept()`](https://python-all.ru/3.2/library/asyncore.html#asyncore.dispatcher.handle_accept) и избавляет пользователя от необходимости напрямую вызывать [`accept()`](https://python-all.ru/3.2/library/asyncore.html#asyncore.dispatcher.accept).

(Автор: Giampaolo Rodolà; [issue 6706](https://python-all.ru/3.2/whatsnew/3.2.html).)

### tempfile

Модуль [`tempfile`](https://python-all.ru/3.2/library/tempfile.html#module-tempfile) получил новый контекстный менеджер [`TemporaryDirectory`](https://python-all.ru/3.2/library/tempfile.html#tempfile.TemporaryDirectory), обеспечивающий простое и детерминированное удаление временных каталогов:

```python
with tempfile.TemporaryDirectory() as tmpdirname:
    print('created temporary dir:', tmpdirname)
```

(Авторы: Neil Schemenauer и Nick Coghlan; [issue 5178](https://python-all.ru/3.2/whatsnew/3.2.html).)

### inspect

- Модуль [`inspect`](https://python-all.ru/3.2/library/inspect.html#module-inspect) содержит новую функцию [`getgeneratorstate()`](https://python-all.ru/3.2/library/inspect.html#inspect.getgeneratorstate) для простого определения текущего состояния генератора-итератора:

  ```python
  >>> from inspect import getgeneratorstate
  >>> def gen():
          yield 'demo'
  >>> g = gen()
  >>> getgeneratorstate(g)
  'GEN_CREATED'
  >>> next(g)
  'demo'
  >>> getgeneratorstate(g)
  'GEN_SUSPENDED'
  >>> next(g, None)
  >>> getgeneratorstate(g)
  'GEN_CLOSED'
  ```

  (Авторы: Rodolpho Eckhardt и Nick Coghlan, [issue 10220](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Для поддержки поиска без возможности активации динамического атрибута модуль [`inspect`](https://python-all.ru/3.2/library/inspect.html#module-inspect) содержит новую функцию [`getattr_static()`](https://python-all.ru/3.2/library/inspect.html#inspect.getattr_static). В отличие от [`hasattr()`](https://python-all.ru/3.2/library/functions.html#hasattr), это настоящий поиск только для чтения, который гарантированно не изменяет состояние во время поиска:

  ```python
  >>> class A:
          @property
          def f(self):
              print('Running')
              return 10

  >>> a = A()
  >>> getattr(a, 'f')
  Running
  10
  >>> inspect.getattr_static(a, 'f')
  <property object at 0x1022bd788>
  ```

> (Предложено Michael Foord.)

### pydoc

Модуль [`pydoc`](https://python-all.ru/3.2/library/pydoc.html#module-pydoc) теперь предоставляет значительно улучшенный интерфейс веб-сервера, а также новый параметр командной строки `-b` для автоматического открытия окна браузера для отображения этого сервера:

```python
$ pydoc3.2 -b
```

(Автор: Ron Adam; [issue 2001](https://python-all.ru/3.2/whatsnew/3.2.html).)

### dis

Модуль [`dis`](https://python-all.ru/3.2/library/dis.html#module-dis) получил две новые функции для инспекции кода: [`code_info()`](https://python-all.ru/3.2/library/dis.html#dis.code_info) и [`show_code()`](https://python-all.ru/3.2/library/dis.html#dis.show_code). Обе предоставляют подробную информацию об объекте кода для переданной функции, метода, строки исходного кода или объекта кода. Первая возвращает строку, вторая выводит её:

```python
>>> import dis, random
>>> dis.show_code(random.choice)
Name:              choice
Filename:          /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py
Argument count:    2
Kw-only arguments: 0
Number of locals:  3
Stack size:        11
Flags:             OPTIMIZED, NEWLOCALS, NOFREE
Constants:
   0: 'Choose a random element from a non-empty sequence.'
   1: 'Cannot choose from an empty sequence'
Names:
   0: _randbelow
   1: len
   2: ValueError
   3: IndexError
Variable names:
   0: self
   1: seq
   2: i
```

Кроме того, функция [`dis()`](https://python-all.ru/3.2/library/dis.html#dis.dis) теперь принимает строковые аргументы, так что распространённую идиому `dis(compile(s, '', 'eval'))` можно сократить до `dis(s)`:

```python
>>> dis('3*x+1 if x%2==1 else x//2')
  1           0 LOAD_NAME                0 (x)
              3 LOAD_CONST               0 (2)
              6 BINARY_MODULO
              7 LOAD_CONST               1 (1)
             10 COMPARE_OP               2 (==)
             13 POP_JUMP_IF_FALSE       28
             16 LOAD_CONST               2 (3)
             19 LOAD_NAME                0 (x)
             22 BINARY_MULTIPLY
             23 LOAD_CONST               1 (1)
             26 BINARY_ADD
             27 RETURN_VALUE
        >>   28 LOAD_NAME                0 (x)
             31 LOAD_CONST               0 (2)
             34 BINARY_FLOOR_DIVIDE
             35 RETURN_VALUE
```

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

(Автор: Nick Coghlan, [issue 9147](https://python-all.ru/3.2/whatsnew/3.2.html).)

### dbm

Все модули баз данных теперь поддерживают методы `get()` и `setdefault()`.

(Предложено Ray Allen в [issue 9523](https://python-all.ru/3.2/whatsnew/3.2.html).)

### ctypes

Новый тип [`ctypes.c_ssize_t`](https://python-all.ru/3.2/library/ctypes.html#ctypes.c_ssize_t) представляет тип данных C `ssize_t`.

### site

Модуль [`site`](https://python-all.ru/3.2/library/site.html#module-site) содержит три новые функции для вывода подробной информации об установке Python.

- [`getsitepackages()`](https://python-all.ru/3.2/library/site.html#site.getsitepackages) выводит список всех глобальных каталогов site-packages.
- [`getuserbase()`](https://python-all.ru/3.2/library/site.html#site.getuserbase) сообщает базовый каталог пользователя, в котором могут храниться данные.
- [`getusersitepackages()`](https://python-all.ru/3.2/library/site.html#site.getusersitepackages) показывает путь к каталогу site-packages для текущего пользователя.

```python
>>> import site
>>> site.getsitepackages()
['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',
 '/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',
 '/Library/Python/3.2/site-packages']
>>> site.getuserbase()
'/Users/raymondhettinger/Library/Python/3.2'
>>> site.getusersitepackages()
'/Users/raymondhettinger/Library/Python/3.2/lib/python/site-packages'
```

Удобно, что часть функциональности site доступна напрямую из командной строки:

```python
$ python -m site --user-base
/Users/raymondhettinger/.local
$ python -m site --user-site
/Users/raymondhettinger/.local/lib/python3.2/site-packages
```

(Автор: Tarek Ziadé, [issue 6693](https://python-all.ru/3.2/whatsnew/3.2.html).)

### sysconfig

Новый модуль [`sysconfig`](https://python-all.ru/3.2/library/sysconfig.html#module-sysconfig) упрощает поиск путей установки и переменных конфигурации, которые различаются между платформами и установками.

Модуль предоставляет простые функции доступа для получения информации о платформе и версии:

- [`get_platform()`](https://python-all.ru/3.2/library/sysconfig.html#sysconfig.get_platform) возвращает такие значения, как *linux-i586* или *macosx-10.6-ppc*.
- [`get_python_version()`](https://python-all.ru/3.2/library/sysconfig.html#sysconfig.get_python_version) возвращает строку версии Python, например «3.2».

Он также предоставляет доступ к путям и переменным, соответствующим одной из семи именованных схем, используемых [`distutils`](https://python-all.ru/3.2/library/distutils.html#module-distutils). К ним относятся *posix\_prefix*, *posix\_home*, *posix\_user*, *nt*, *nt\_user*, *os2*, *os2\_home*:

- [`get_paths()`](https://python-all.ru/3.2/library/sysconfig.html#sysconfig.get_paths) создаёт словарь, содержащий пути установки для текущей схемы установки.
- [`get_config_vars()`](https://python-all.ru/3.2/library/sysconfig.html#sysconfig.get_config_vars) возвращает словарь переменных, зависящих от платформы.

Также имеется удобный интерфейс командной строки:

```python
C:\Python32>python -m sysconfig
Platform: "win32"
Python version: "3.2"
Current installation scheme: "nt"

Paths:
        data = "C:\Python32"
        include = "C:\Python32\Include"
        platinclude = "C:\Python32\Include"
        platlib = "C:\Python32\Lib\site-packages"
        platstdlib = "C:\Python32\Lib"
        purelib = "C:\Python32\Lib\site-packages"
        scripts = "C:\Python32\Scripts"
        stdlib = "C:\Python32\Lib"

Variables:
        BINDIR = "C:\Python32"
        BINLIBDEST = "C:\Python32\Lib"
        EXE = ".exe"
        INCLUDEPY = "C:\Python32\Include"
        LIBDEST = "C:\Python32\Lib"
        SO = ".pyd"
        VERSION = "32"
        abiflags = ""
        base = "C:\Python32"
        exec_prefix = "C:\Python32"
        platbase = "C:\Python32"
        prefix = "C:\Python32"
        projectbase = "C:\Python32"
        py_version = "3.2"
        py_version_nodot = "32"
        py_version_short = "3.2"
        srcdir = "C:\Python32"
        userbase = "C:\Documents and Settings\Raymond\Application Data\Python"
```

(Перенесено из Distutils Тареком Зиаде.)

### pdb

Модуль отладчика [`pdb`](https://python-all.ru/3.2/library/pdb.html#module-pdb) получил ряд улучшений удобства использования:

- `pdb.py` теперь имеет опцию `-c`, которая выполняет команды, заданные в файле сценария `.pdbrc`.
- Файл сценария `.pdbrc` может содержать команды `continue` и `next`, которые продолжают отладку.
- Конструктор класса `Pdb` теперь принимает аргумент *nosigint*.
- Новые команды: `l(list)`, `ll(long list)` и `source` для просмотра исходного кода.
- Новые команды: `display` и `undisplay` для отображения или скрытия значения выражения, если оно изменилось.
- Новая команда: `interact` для запуска интерактивного интерпретатора, содержащего глобальные и локальные имена, найденные в текущей области видимости.
- Точки останова можно удалять по номеру.

(Добавлено Георгом Брандлем, Антонио Куни и Ильёй Сандлером.)

### configparser

Модуль [`configparser`](https://python-all.ru/3.2/library/configparser.html#module-configparser) был изменён для улучшения удобства использования и предсказуемости парсера по умолчанию и поддерживаемого им синтаксиса INI. Старый класс `ConfigParser` был удалён в пользу `SafeConfigParser`, который, в свою очередь, был переименован в [`ConfigParser`](https://python-all.ru/3.2/library/configparser.html#configparser.ConfigParser). Поддержка строчных комментариев теперь отключена по умолчанию, а дублирование разделов или опций не допускается в одном источнике конфигурации.

Парсеры конфигураций получили новый API на основе протокола отображения:

```python
>>> parser = ConfigParser()
>>> parser.read_string("""
[DEFAULT]
location = upper left
visible = yes
editable = no
color = blue

[main]
title = Main Menu
color = green

[options]
title = Options
""")
>>> parser['main']['color']
'green'
>>> parser['main']['editable']
'no'
>>> section = parser['options']
>>> section['title']
'Options'
>>> section['title'] = 'Options (editable: %(editable)s)'
>>> section['title']
'Options (editable: no)'
```

Новый API реализован поверх классического API, поэтому пользовательские подклассы парсеров должны иметь возможность использовать его без изменений.

Структура INI-файла, принимаемая парсерами конфигураций, теперь может быть настроена. Пользователи могут задавать альтернативные разделители опция/значение и префиксы комментариев, изменять имя секции *DEFAULT* или переключать синтаксис интерполяции.

Реализована поддержка подключаемой интерполяции, включая дополнительный обработчик интерполяции [`ExtendedInterpolation`](https://python-all.ru/3.2/library/configparser.html#configparser.ExtendedInterpolation):

```python
>>> parser = ConfigParser(interpolation=ExtendedInterpolation())
>>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},
                      'custom': {'prefix': '/usr/local'}})
>>> parser.read_string("""
    [buildout]
    parts =
      zope9
      instance
    find-links =
      ${buildout:directory}/downloads/dist

    [zope9]
    recipe = plone.recipe.zope9install
    location = /opt/zope

    [instance]
    recipe = plone.recipe.zope9instance
    zope9-location = ${zope9:location}
    zope-conf = ${custom:prefix}/etc/zope.conf
    """)
>>> parser['buildout']['find-links']
'\n/home/ambv/zope9/downloads/dist'
>>> parser['instance']['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance = parser['instance']
>>> instance['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance['zope9-location']
'/opt/zope'
```

Был также введён ряд небольших возможностей, таких как поддержка указания кодировки в операциях чтения, указание значений по умолчанию для get-функций или чтение напрямую из словарей и строк.

(Все изменения предоставлены Łukasz Langa.)

### urllib.parse

Для модуля [`urllib.parse`](https://python-all.ru/3.2/library/urllib.parse.html#module-urllib.parse) был внесён ряд улучшений удобства использования.

Функция [`urlparse()`](https://python-all.ru/3.2/library/urllib.parse.html#urllib.parse.urlparse) теперь поддерживает адреса [IPv6](https://python-all.ru/3.2/whatsnew/3.2.html), как описано в [**RFC 2732**](https://python-all.ru/3.2/whatsnew/3.2.html):

```python
>>> import urllib.parse
>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
ParseResult(scheme='http',
            netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',
            path='/foo/',
            params='',
            query='',
            fragment='')
```

Функция [`urldefrag()`](https://python-all.ru/3.2/library/urllib.parse.html#urllib.parse.urldefrag) теперь возвращает [*именованный кортеж*](https://python-all.ru/3.2/glossary.html#term-named-tuple):

```python
>>> r = urllib.parse.urldefrag('http://python.org/about/#target')
>>> r
DefragResult(url='http://python.org/about/', fragment='target')
>>> r[0]
'http://python.org/about/'
>>> r.fragment
'target'
```

Кроме того, функция [`urlencode()`](https://python-all.ru/3.2/library/urllib.parse.html#urllib.parse.urlencode) теперь стала гораздо более гибкой: она принимает аргумент *query* как строку, так и тип bytes. Если это строка, то параметры *safe*, *encoding* и *error* передаются в [`quote_plus()`](https://python-all.ru/3.2/library/urllib.parse.html#urllib.parse.quote_plus) для кодирования:

```python
>>> urllib.parse.urlencode([
         ('type', 'telenovela'),
         ('name', '¿Dónde Está Elisa?')],
         encoding='latin-1')
'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'
```

Как подробно описано в [*Parsing ASCII Encoded Bytes*](https://python-all.ru/3.2/library/urllib.parse.html#parsing-ascii-encoded-bytes), все функции [`urllib.parse`](https://python-all.ru/3.2/library/urllib.parse.html#module-urllib.parse) теперь принимают на вход ASCII-закодированные байтовые строки, при условии, что они не смешиваются с обычными строками. Если в качестве параметров заданы ASCII-закодированные байтовые строки, возвращаемые типы также будут ASCII-закодированными байтовыми строками:

```python
>>> urllib.parse.urlparse(b'http://www.python.org:80/about/')
ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',
                 path=b'/about/', params=b'', query=b'', fragment=b'')
```

(Работа Ника Коглана, Дэна Мана и Сентила Кумарана в [issue 2987](https://python-all.ru/3.2/whatsnew/3.2.html), [issue 5468](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 9873](https://python-all.ru/3.2/whatsnew/3.2.html).)

### mailbox

Благодаря согласованным усилиям Р. Дэвида Мюррея, модуль [`mailbox`](https://python-all.ru/3.2/library/mailbox.html#module-mailbox) был исправлен для Python 3.2. Проблема заключалась в том, что mailbox изначально был спроектирован с текстовым интерфейсом, но email-сообщения лучше представлять через [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes), поскольку разные части сообщения могут иметь разные кодировки.

Решение задействовало двоичную поддержку пакета [`email`](https://python-all.ru/3.2/library/email.html#module-email) для разбора произвольных email-сообщений. Кроме того, решение потребовало ряда изменений API.

Как и ожидалось, метод [`add()`](https://python-all.ru/3.2/library/mailbox.html#mailbox.Mailbox.add) для объектов [`mailbox.Mailbox`](https://python-all.ru/3.2/library/mailbox.html#mailbox.Mailbox) теперь принимает двоичный ввод.

[`StringIO`](https://python-all.ru/3.2/library/io.html#io.StringIO) и ввод из текстового файла устарели. Кроме того, строковый ввод будет завершаться ошибкой на раннем этапе, если используются символы не в ASCII. Ранее ошибка возникала при обработке письма на более позднем этапе.

Также добавлена поддержка двоичного вывода. Метод [`get_file()`](https://python-all.ru/3.2/library/mailbox.html#mailbox.Mailbox.get_file) теперь возвращает файл в двоичном режиме (ранее он некорректно устанавливал текстовый режим). Кроме того, появился новый метод [`get_bytes()`](https://python-all.ru/3.2/library/mailbox.html#mailbox.Mailbox.get_bytes), который возвращает [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes)-представление сообщения, соответствующее заданному *key*.

По-прежнему можно получить недвоичный вывод с помощью метода старого API [`get_string()`](https://python-all.ru/3.2/library/mailbox.html#mailbox.Mailbox.get_string), но такой подход не очень полезен. Вместо этого лучше извлекать сообщения из объекта [`Message`](https://python-all.ru/3.2/library/mailbox.html#mailbox.Message) или загружать их из двоичного ввода.

(Предоставлено Р. Дэвидом Мюрреем, при участии Штеффена Даоде Нурпмезо и начального патча от Виктора Стиннера в [issue 9124](https://python-all.ru/3.2/whatsnew/3.2.html).)

### turtledemo

Демонстрационный код для модуля [`turtle`](https://python-all.ru/3.2/library/turtle.html#module-turtle) был перемещён из каталога *Demo* в основную библиотеку. Он включает более десятка примеров сценариев с живыми отображениями. Находясь в [`sys.path`](https://python-all.ru/3.2/library/sys.html#sys.path), его теперь можно запускать напрямую из командной строки:

```python
$ python -m turtledemo
```

(Перемещено из каталога Demo Александром Белопольским в [issue 10199](https://python-all.ru/3.2/whatsnew/3.2.html).)

## Многопоточность

- Механизм сериализации выполнения одновременно работающих потоков Python (обычно известный как [*GIL*](https://python-all.ru/3.2/glossary.html#term-gil) или [*Глобальная блокировка интерпретатора*](https://python-all.ru/3.2/glossary.html#term-global-interpreter-lock)) был переписан. Среди целей были более предсказуемые интервалы переключения и снижение накладных расходов из-за конкуренции за блокировку и количества последующих системных вызовов. Понятие «интервал проверки» для разрешения переключения потоков было отброшено и заменено абсолютной длительностью, выраженной в секундах. Этот параметр настраивается через [`sys.setswitchinterval()`](https://python-all.ru/3.2/library/sys.html#sys.setswitchinterval). В настоящее время по умолчанию он равен 5 миллисекундам.

  Дополнительные сведения о реализации можно прочитать в [сообщении в списке рассылки python-dev](https://python-all.ru/3.2/whatsnew/3.2.html) (однако, «приоритетные запросы», как описано в этом сообщении, не были сохранены для включения).

  (Предоставлено Antoine Pitrou.)
- Обычные и рекурсивные блокировки теперь принимают необязательный аргумент *timeout* для своего метода [`acquire()`](https://python-all.ru/3.2/library/threading.html#threading.Lock.acquire). (Автор: Antoine Pitrou; [issue 7316](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Аналогично, метод [`threading.Semaphore.acquire()`](https://python-all.ru/3.2/library/threading.html#threading.Semaphore.acquire) также получил аргумент *timeout*. (Автор: Torsten Landschoff; [issue 850728](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Теперь на платформах, использующих Pthreads, захват обычных и рекурсивных блокировок может быть прерван сигналами. Это означает, что программы Python, попавшие в взаимоблокировку при захвате блокировок, можно успешно завершить, многократно отправляя процессу сигнал SIGINT (нажатием `Ctrl+C` в большинстве оболочек). (Автор: Reid Kleckner; [issue 8844](https://python-all.ru/3.2/whatsnew/3.2.html).)

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

Добавлено несколько небольших улучшений производительности:

- Оптимизатор peephole в Python теперь распознает такие шаблоны, как `x in {1, 2, 3}`, как проверку принадлежности множеству констант. Оптимизатор преобразует [`set`](https://python-all.ru/3.2/library/stdtypes.html#set) в [`frozenset`](https://python-all.ru/3.2/library/stdtypes.html#frozenset) и сохраняет предварительно созданную константу.

  Теперь, когда замедление устранено, стало практичным начать писать проверки принадлежности с использованием set-нотации. Этот стиль одновременно ясен семантически и быстр в работе:

  ```python
  extension = name.rpartition('.')[2]
  if extension in {'xml', 'html', 'xhtml', 'css'}:
      handle(name)
  ```

  (Патч и дополнительные тесты предоставлены Dave Malcolm; [issue 6690](https://python-all.ru/3.2/whatsnew/3.2.html)).
- Сериализация и десериализация данных с помощью модуля [`pickle`](https://python-all.ru/3.2/library/pickle.html#module-pickle) теперь выполняется в несколько раз быстрее.

  (Авторы: Alexandre Vassalotti, Antoine Pitrou и команда Unladen Swallow; [issue 9410](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 3873](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Алгоритм [Timsort](https://python-all.ru/3.2/whatsnew/3.2.html), используемый в `list.sort()` и [`sorted()`](https://python-all.ru/3.2/library/functions.html#sorted), теперь работает быстрее и использует меньше памяти при вызове с [*функцией ключа*](https://python-all.ru/3.2/glossary.html#term-key-function). Раньше каждый элемент списка оборачивался временным объектом, который запоминал значение ключа для каждого элемента. Теперь два массива – ключей и значений – сортируются параллельно. Это экономит память, занимаемую обёртками для сортировки, и время, затрачиваемое на делегирование сравнений.

  (Патч от Daniel Stutzbach в [issue 9915](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Производительность декодирования JSON улучшена, а потребление памяти снижено, когда одна и та же строка повторяется для нескольких ключей. Кроме того, кодирование JSON теперь использует ускорения на C, когда аргумент `sort_keys` равен true.

  (Авторы: Antoine Pitrou в [issue 7451](https://python-all.ru/3.2/whatsnew/3.2.html), и Raymond Hettinger с Antoine Pitrou в [issue 10314](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Рекурсивные блокировки (создаваемые через API [`threading.RLock()`](https://python-all.ru/3.2/library/threading.html#threading.RLock)) теперь выигрывают от реализации на C, которая делает их такими же быстрыми, как обычные блокировки, и в 10–15 раз быстрее предыдущей реализации на чистом Python.

  (Автор: Antoine Pitrou; [issue 3001](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Алгоритм быстрого поиска в stringlib теперь используется методами `split()`, `splitlines()` и `replace()` объектов [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes), [`bytearray`](https://python-all.ru/3.2/library/functions.html#bytearray) и [`str`](https://python-all.ru/3.2/library/functions.html#str). Кроме того, этот алгоритм также используется методами `rfind()`, `rindex()`, `rsplit()` и `rpartition()`.

  (Патч от Florent Xicluna в [issue 7622](https://python-all.ru/3.2/whatsnew/3.2.html) и [issue 7462](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Преобразования целых чисел в строки теперь работают с двумя «цифрами» за раз, сокращая количество операций деления и взятия остатка.

  ([issue 6713](https://python-all.ru/3.2/whatsnew/3.2.html) от Gawain Bolton, Mark Dickinson и Victor Stinner.)

Было реализовано несколько других незначительных оптимизаций. Разность множеств теперь выполняется быстрее, когда один операнд намного больше другого (патч от Andress Bennetts в [issue 8685](https://python-all.ru/3.2/whatsnew/3.2.html)). Метод `array.repeat()` получил более быструю реализацию ([issue 1569291](https://python-all.ru/3.2/whatsnew/3.2.html) от Alexander Belopolsky). Класс `BaseHTTPRequestHandler` имеет более эффективную буферизацию ([issue 3709](https://python-all.ru/3.2/whatsnew/3.2.html) от Andrew Schaaf). Функция [`operator.attrgetter()`](https://python-all.ru/3.2/library/operator.html#operator.attrgetter) ускорена ([issue 10160](https://python-all.ru/3.2/whatsnew/3.2.html) от Christos Georgiou). А `ConfigParser` загружает многострочные аргументы немного быстрее ([issue 7113](https://python-all.ru/3.2/whatsnew/3.2.html) от Łukasz Langa).

## Юникод

Python был обновлён до [Unicode 6.0.0](https://python-all.ru/3.2/whatsnew/3.2.html). Обновление стандарта добавляет более 2000 новых символов, включая [эмодзи](https://python-all.ru/3.2/whatsnew/3.2.html), которые важны для мобильных телефонов.

Кроме того, обновлённый стандарт изменил свойства символов для двух символов каннада (U+0CF1, U+0CF2) и одного числового символа New Tai Lue (U+19DA), сделав первые допустимыми для использования в идентификаторах, а последний – недопустимым. Подробнее см. [Unicode Character Database Changes](https://python-all.ru/3.2/whatsnew/3.2.html).

## Кодеки

Добавлена поддержка арабской кодировки DOS *cp720* ([issue 1616979](https://python-all.ru/3.2/whatsnew/3.2.html)).

MBCS encoding no longer ignores the error handler argument. In the default strict mode, it raises an [`UnicodeDecodeError`](https://python-all.ru/3.2/library/exceptions.html#UnicodeDecodeError) when it encounters an undecodable byte sequence and an [`UnicodeEncodeError`](https://python-all.ru/3.2/library/exceptions.html#UnicodeEncodeError) for an unencodable character.

Кодек MBCS поддерживает обработчики ошибок `'strict'` и `'ignore'` для декодирования, и `'strict'` и `'replace'` для кодирования.

Для эмуляции кодировки MBCS из Python 3.1 выберите обработчик `'ignore'` для декодирования и обработчик `'replace'` для кодирования.

На Mac OS X Python декодирует аргументы командной строки с помощью `'utf-8'`, а не кодировки локали.

По умолчанию [`tarfile`](https://python-all.ru/3.2/library/tarfile.html#module-tarfile) использует кодировку `'utf-8'` в Windows (вместо `'mbcs'`) и обработчик ошибок `'surrogateescape'` на всех операционных системах.

## Документация

Документация продолжает улучшаться.

- В верхней части длинных разделов, таких как [*Встроенные функции*](https://python-all.ru/3.2/library/functions.html#built-in-funcs), теперь добавлена таблица быстрых ссылок. В случае [`itertools`](https://python-all.ru/3.2/library/itertools.html#module-itertools) ссылки сопровождаются таблицами кратких сводок в стиле шпаргалки, чтобы дать обзор и освежить память без необходимости читать всю документацию.
- В некоторых случаях исходный код на чистом Python может быть полезным дополнением к документации, поэтому теперь многие модули содержат быстрые ссылки на последнюю версию исходного кода. Например, документация модуля [`functools`](https://python-all.ru/3.2/library/functools.html#module-functools) имеет вверху быструю ссылку с подписью:

  > **Исходный код** [Lib/functools.py](https://python-all.ru/src/3.2/Lib/functools.py).

  (Автор: Raymond Hettinger; см. [обоснование](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Документация теперь содержит больше примеров и рецептов. В частности, модуль [`re`](https://python-all.ru/3.2/library/re.html#module-re) имеет обширный раздел [*Примеры регулярных выражений*](https://python-all.ru/3.2/library/re.html#re-examples). Кроме того, модуль [`itertools`](https://python-all.ru/3.2/library/itertools.html#module-itertools) продолжает обновляться новыми [*Рецептами itertools*](https://python-all.ru/3.2/library/itertools.html#itertools-recipes).
- Модуль [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime) теперь имеет вспомогательную реализацию на чистом Python. Функциональность не изменилась. Это просто предоставляет более удобную для чтения альтернативную реализацию.

  (Автор: Alexander Belopolsky; [issue 9528](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Не поддерживаемая директория `Demo` удалена. Некоторые демонстрации были интегрированы в документацию, некоторые перемещены в директорию `Tools/demo`, а остальные полностью удалены.

  (Автор: Georg Brandl; [issue 7962](https://python-all.ru/3.2/whatsnew/3.2.html).)

## IDLE

- Меню «Формат» теперь содержит опцию для очистки исходных файлов путём удаления замыкающих пробелов.

  (Автор: Raymond Hettinger; [issue 5150](https://python-all.ru/3.2/whatsnew/3.2.html).)
- IDLE на Mac OS X теперь работает как с Carbon AquaTk, так и с Cocoa AquaTk.

  (Авторы: Kevin Walzer, Ned Deily и Ronald Oussoren; [issue 6075](https://python-all.ru/3.2/whatsnew/3.2.html).)

## Репозиторий кода

В дополнение к существующему репозиторию Subversion по адресу [http://svn.python.org](https://python-all.ru/3.2/whatsnew/3.2.html) теперь также доступен репозиторий [Mercurial](https://python-all.ru/3.2/whatsnew/3.2.html) по адресу [http://hg.python.org/](https://python-all.ru/3.2/whatsnew/3.2.html).

После выхода версии 3.2 планируется перейти на Mercurial в качестве основного репозитория. Эта распределённая система управления версиями должна упростить членам сообщества создание и обмен внешними наборами изменений. Подробнее см. [**PEP 385**](https://python-all.ru/3.2/whatsnew/3.2.html).

Чтобы освоить новую систему контроля версий, ознакомьтесь с [учебником Джоэла Спольски](https://python-all.ru/3.2/whatsnew/3.2.html) или [руководством по рабочим процессам Mercurial](https://python-all.ru/3.2/whatsnew/3.2.html).

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

Изменения процесса сборки Python и C API включают:

- Скрипты *idle*, *pydoc* и *2to3* теперь устанавливаются с суффиксом, зависящим от версии, при `make altinstall` ([issue 10679](https://python-all.ru/3.2/whatsnew/3.2.html)).
- C-функции, обращающиеся к базе данных Unicode, теперь принимают и возвращают символы из полного диапазона Unicode, даже в узких сборках Unicode (Py\_UNICODE\_TOLOWER, Py\_UNICODE\_ISDECIMAL и другие). Заметное отличие в Python: [`unicodedata.numeric()`](https://python-all.ru/3.2/library/unicodedata.html#unicodedata.numeric) теперь возвращает правильное значение для больших кодовых точек, а [`repr()`](https://python-all.ru/3.2/library/functions.html#repr) может считать больше символов печатаемыми.

  (Сообщил Bupjoe Lee, исправил Amaury Forgeot D’Arc; [issue 5127](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Вычисляемые goto теперь включены по умолчанию в поддерживаемых компиляторах (которые определяются скриптом configure). Их можно выборочно отключить, указав `--without-computed-gotos`.

  (Автор: Antoine Pitrou; [issue 9203](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Опция `--with-wctype-functions` была удалена. Теперь для всех функций используется встроенная база данных Unicode.

  (Автор: Amaury Forgeot D’Arc; [issue 9210](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Хеш-значения теперь являются значениями нового типа `Py_hash_t`, который определяется как имеющий тот же размер, что и указатель. Ранее они были типа long, который в некоторых 64-битных операционных системах по-прежнему имеет длину всего 32 бита. В результате этого исправления [`set`](https://python-all.ru/3.2/library/stdtypes.html#set) и [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict) теперь могут содержать более `2**32` элементов в сборках с 64-битными указателями (ранее они могли вырасти до такого размера, но их производительность катастрофически падала).

  (Предложено Raymond Hettinger, реализовано Benjamin Peterson; [issue 9778](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Новый макрос `Py_VA_COPY` копирует состояние списка переменных аргументов. Он эквивалентен *va\_copy* из C99, но доступен на всех платформах Python ([issue 2443](https://python-all.ru/3.2/whatsnew/3.2.html)).
- Новая функция C API [`PySys_SetArgvEx()`](https://python-all.ru/3.2/c-api/init.html#PySys_SetArgvEx) позволяет встроенному интерпретатору задавать [`sys.argv`](https://python-all.ru/3.2/library/sys.html#sys.argv) без изменения [`sys.path`](https://python-all.ru/3.2/library/sys.html#sys.path) ([issue 5753](https://python-all.ru/3.2/whatsnew/3.2.html)).
- `PyEval_CallObject` теперь доступен только в виде макроса. Объявление функции, которое сохранялось для обратной совместимости, теперь удалено – макрос был введён в 1997 году ([issue 8276](https://python-all.ru/3.2/whatsnew/3.2.html)).
- Появилась новая функция [`PyLong_AsLongLongAndOverflow()`](https://python-all.ru/3.2/c-api/long.html#PyLong_AsLongLongAndOverflow), аналогичная [`PyLong_AsLongAndOverflow()`](https://python-all.ru/3.2/c-api/long.html#PyLong_AsLongAndOverflow). Обе служат для преобразования Python [`int`](https://python-all.ru/3.2/library/functions.html#int) в нативный тип фиксированного размера с обнаружением случаев, когда преобразование невозможно ([issue 7767](https://python-all.ru/3.2/whatsnew/3.2.html)).
- Функция [`PyUnicode_CompareWithASCIIString()`](https://python-all.ru/3.2/c-api/unicode.html#PyUnicode_CompareWithASCIIString) теперь возвращает *не равно*, если строка Python завершается *NUL*.
- Появилась новая функция [`PyErr_NewExceptionWithDoc()`](https://python-all.ru/3.2/c-api/exceptions.html#PyErr_NewExceptionWithDoc), похожая на [`PyErr_NewException()`](https://python-all.ru/3.2/c-api/exceptions.html#PyErr_NewException), но позволяющая указать docstring. Это даёт исключениям на C такие же возможности самодокументирования, как у их аналогов на чистом Python ([issue 7033](https://python-all.ru/3.2/whatsnew/3.2.html)).
- При сборке с опцией `--with-valgrind` аллокатор pymalloc будет автоматически отключаться при работе под Valgrind. Это обеспечивает улучшенное обнаружение утечек памяти при работе под Valgrind, одновременно используя преимущества pymalloc в остальное время ([issue 2422](https://python-all.ru/3.2/whatsnew/3.2.html)).
- Удалён формат `O?` из функций *PyArg\_Parse*. Этот формат больше не используется и никогда не был документирован ([issue 8837](https://python-all.ru/3.2/whatsnew/3.2.html)).

Было внесено множество других мелких изменений в C-API. Полный список см. в файле [Misc/NEWS](https://python-all.ru/src/3.2/Misc/NEWS).

Кроме того, в сборку для Mac OS X был внесён ряд обновлений; подробности см. в [Mac/BuildScript/README.txt](https://python-all.ru/src/3.2/Mac/BuildScript/README.txt). Для пользователей 32/64-битной сборки существует известная проблема с Tcl/Tk по умолчанию в Mac OS X 10.6. Поэтому рекомендуется установить обновлённую альтернативу, например [ActiveState Tcl/Tk 8.5.9](https://python-all.ru/3.2/whatsnew/3.2.html). Дополнительные сведения – на [http://www.python.org/download/mac/tcltk/](https://python-all.ru/3.2/whatsnew/3.2.html).

## Переход на Python 3.2

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

- Модуль [`configparser`](https://python-all.ru/3.2/library/configparser.html#module-configparser) претерпел ряд улучшений. Основное изменение – замена старого класса `ConfigParser` на давно предпочтительную альтернативу `SafeConfigParser`. Кроме того, имеется ряд мелких несовместимостей:

  - Синтаксис интерполяции теперь проверяется при операциях [`get()`](https://python-all.ru/3.2/library/configparser.html#configparser.ConfigParser.get) и [`set()`](https://python-all.ru/3.2/library/configparser.html#configparser.ConfigParser.set). В схеме интерполяции по умолчанию допустимы только два токена со знаками процента: `%(name)s` и `%%`, причём последний представляет собой экранированный знак процента.
  - Методы [`set()`](https://python-all.ru/3.2/library/configparser.html#configparser.ConfigParser.set) и [`add_section()`](https://python-all.ru/3.2/library/configparser.html#configparser.ConfigParser.add_section) теперь проверяют, что значения являются строками. Ранее неподдерживаемые типы могли быть случайно введены.
  - Повторяющиеся разделы или параметры из одного источника теперь вызывают [`DuplicateSectionError`](https://python-all.ru/3.2/library/configparser.html#configparser.DuplicateSectionError) или [`DuplicateOptionError`](https://python-all.ru/3.2/library/configparser.html#configparser.DuplicateOptionError). Ранее дубликаты молча перезаписывали предыдущую запись.
  - Встрочные комментарии теперь по умолчанию отключены, поэтому символ **;** теперь можно безопасно использовать в значениях.
  - Комментарии теперь можно располагать с отступом. Следовательно, чтобы **;** или **#** оказались в начале строки в многострочных значениях, их нужно интерполировать. Это предотвращает ошибочную интерпретацию префиксных символов комментариев в значениях как комментариев.
  - `""` теперь является допустимым значением и больше не преобразуется автоматически в пустую строку. Для пустых строк используйте `"option ="` в строке.
- Модуль [`nntplib`](https://python-all.ru/3.2/library/nntplib.html#module-nntplib) был существенно переработан, поэтому его API часто несовместимы с API версии 3.1.
- Объекты [`bytearray`](https://python-all.ru/3.2/library/functions.html#bytearray) больше нельзя использовать в качестве имён файлов; вместо этого их следует преобразовывать в [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes).
- Методы `array.tostring()` и `array.fromstring()` были переименованы в `array.tobytes()` и `array.frombytes()` для ясности. Старые имена объявлены устаревшими. (См. [issue 8990](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Функции `PyArg_Parse*()`:

  - Формат «t#» удалён: используйте «s#» или «s\*»
  - Форматы «w» и «w#» удалены: используйте «w\*»
- Тип `PyCObject`, устаревший в 3.1, был удалён. Для обёртывания непрозрачных C-указателей в объекты Python следует использовать API [`PyCapsule`](https://python-all.ru/3.2/c-api/capsule.html#PyCapsule); новый тип имеет чётко определённый интерфейс для передачи информации о типобезопасности и менее сложную сигнатуру для вызова деструктора.
- Функция `sys.setfilesystemencoding()` была удалена из-за ошибочного дизайна.
- Функция и метод [`random.seed()`](https://python-all.ru/3.2/library/random.html#random.seed) теперь «солят» строковые начальные значения с помощью хеш-функции sha512. Чтобы получить доступ к предыдущей версии *seed* для воспроизведения последовательностей Python 3.1, установите аргумент *version* в *1*, `random.seed(s, version=1)`.
- Ранее устаревшая функция `string.maketrans()` была удалена в пользу статических методов [`bytes.maketrans()`](https://python-all.ru/3.2/library/stdtypes.html#bytes.maketrans) и [`bytearray.maketrans()`](https://python-all.ru/3.2/library/stdtypes.html#bytearray.maketrans). Это изменение устраняет путаницу относительно того, какие типы поддерживались модулем [`string`](https://python-all.ru/3.2/library/string.html#module-string). Теперь [`str`](https://python-all.ru/3.2/library/functions.html#str), [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes) и [`bytearray`](https://python-all.ru/3.2/library/functions.html#bytearray) имеют собственные методы **maketrans** и **translate** с промежуточными таблицами перевода соответствующего типа.

  (Автор: Georg Brandl; [issue 5675](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Ранее устаревшая функция `contextlib.nested()` была удалена в пользу обычного оператора [`with`](https://python-all.ru/3.2/reference/compound_stmts.html#with), который может принимать несколько менеджеров контекста. Последний подход быстрее (поскольку является встроенным) и лучше завершает работу нескольких менеджеров контекста, когда один из них вызывает исключение:

  ```python
  with open('mylog.txt') as infile, open('a.out', 'w') as outfile:
      for line in infile:
          if '<critical>' in line:
              outfile.write(line)
  ```

  (Предложено Georg Brandl и Mattias Brändström; [appspot issue 53094](https://python-all.ru/3.2/whatsnew/3.2.html).)
- [`struct.pack()`](https://python-all.ru/3.2/library/struct.html#struct.pack) теперь допускает только байты для строкового кода упаковки `s`. Ранее он принимал текстовые аргументы и неявно кодировал их в байты с помощью UTF-8. Это было проблематично, поскольку делались предположения о правильной кодировке и потому что кодировка с переменной длиной может дать сбой при записи в сегмент фиксированной длины структуры.

  Код вида `struct.pack('<6sHHBBB', 'GIF87a', x, y)` следует переписать с использованием байтов вместо текста: `struct.pack('<6sHHBBB', b'GIF87a', x, y)`.

  (Обнаружено Дэвидом Бизли и исправлено Виктором Штиннером; [issue 10783](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Класс [`xml.etree.ElementTree`](https://python-all.ru/3.2/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) теперь при ошибке разбора вызывает исключение `xml.etree.ElementTree.ParseError`. Ранее он вызывал [`xml.parsers.expat.ExpatError`](https://python-all.ru/3.2/library/pyexpat.html#xml.parsers.expat.ExpatError).
- Новое, более длинное строковое представление [`str()`](https://python-all.ru/3.2/library/functions.html#str) чисел с плавающей запятой может нарушить doctest-ы, которые полагаются на старый формат вывода.
- В [`subprocess.Popen`](https://python-all.ru/3.2/library/subprocess.html#subprocess.Popen) значение по умолчанию для *close\_fds* теперь равно `True` в Unix; в Windows оно равно `True`, если три стандартных потока установлены в `None`, и `False` в противном случае. Ранее *close\_fds* всегда было `False` по умолчанию, что приводило к трудноуловимым ошибкам или состояниям гонки, когда открытые файловые дескрипторы просачивались в дочерний процесс.
- Поддержка устаревшего HTTP 0.9 удалена из [`urllib.request`](https://python-all.ru/3.2/library/urllib.request.html#module-urllib.request) и [`http.client`](https://python-all.ru/3.2/library/http.client.html#module-http.client). Такая поддержка всё ещё присутствует на стороне сервера (в [`http.server`](https://python-all.ru/3.2/library/http.server.html#module-http.server)).

  (Автор: Antoine Pitrou, [issue 10711](https://python-all.ru/3.2/whatsnew/3.2.html).)
- SSL-сокеты в режиме тайм-аута теперь возбуждают [`socket.timeout`](https://python-all.ru/3.2/library/socket.html#socket.timeout) при возникновении тайм-аута, а не общее исключение [`SSLError`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLError).

  (Автор: Antoine Pitrou, [issue 10272](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Вводящие в заблуждение функции [`PyEval_AcquireLock()`](https://python-all.ru/3.2/c-api/init.html#PyEval_AcquireLock) и [`PyEval_ReleaseLock()`](https://python-all.ru/3.2/c-api/init.html#PyEval_ReleaseLock) официально устарели. Вместо них следует использовать API, учитывающие состояние потоков (такие как [`PyEval_SaveThread()`](https://python-all.ru/3.2/c-api/init.html#PyEval_SaveThread) и [`PyEval_RestoreThread()`](https://python-all.ru/3.2/c-api/init.html#PyEval_RestoreThread)).
- Из-за рисков безопасности функция `asyncore.handle_accept()` устарела, и для её замены добавлена новая функция `asyncore.handle_accepted()`.

  (Автор: Giampaolo Rodola, [issue 6706](https://python-all.ru/3.2/whatsnew/3.2.html).)
- Из-за новой реализации [*GIL*](https://python-all.ru/3.2/glossary.html#term-gil) [`PyEval_InitThreads()`](https://python-all.ru/3.2/c-api/init.html#PyEval_InitThreads) больше нельзя вызывать до [`Py_Initialize()`](https://python-all.ru/3.2/c-api/init.html#Py_Initialize).
