Что нового в Python 2.7

Автор:А.М. Кухлинг (amk на amk.ca)

В этой статье объясняются новые возможности Python 2.7. Python 2.7 был выпущен 3 июля 2010 года.

Обработка чисел была улучшена во многих отношениях как для чисел с плавающей запятой, так и для класса Decimal. В стандартной библиотеке есть несколько полезных дополнений, например, значительно улучшенный модуль unittest, модуль argparse для анализа параметров командной строки, удобные классы OrderedDict и Counter в модуле collections и многие другие улучшения.

Планируется, что Python 2.7 станет последним из релизов 2.x, поэтому мы работали над тем, чтобы сделать его хорошим выпуском в долгосрочной перспективе. Чтобы облегчить перенос на Python 3, в версию 2.7 было включено несколько новых функций из серии Python 3.x.

В этой статье не делается попытка предоставить полную спецификацию новых функций, а вместо этого представлен удобный обзор. Для получения полной информации вы должны обратиться к документации по Python 2.7 по адресу. Если вы хотите понять обоснование дизайна и реализации, обратитесь к PEP для новой функции или проблемы на сайте, в которой обсуждалось изменение. Когда это возможно, «Что нового в Python» содержит ссылку на элемент ошибки/исправления для каждого изменения.

Будущее Python 2.x

Python 2.7 является последним крупным выпуском в серии 2.x, т. к. сопровождающие Python сместили акцент своих усилий по разработке новых функций на серию Python 3.x. Это означает, что хотя Python 2 продолжает получать исправления ошибок и обновляться для правильной сборки на новом оборудовании и версиях поддерживаемых операционных систем, новых полнофункциональных релизов для языка или стандартной библиотеки не будет.

Однако, хотя между Python 2.7 и Python 3 существует большое общее подмножество, и многие изменения, связанные с переходом на это общее подмножество или непосредственно на Python 3, можно безопасно автоматизировать, некоторые другие изменения (в частности, связанные с обработкой Юникод ) может потребовать тщательного рассмотрения и, желательно, надежных наборов автоматических регрессионных тестов для эффективной миграции.

Это означает, что Python 2.7 останется на месте в течение длительного времени, предоставляя стабильную и поддерживаемую базовую платформу для производственных систем, которые ещё не были перенесены на Python 3. Полный ожидаемый жизненный цикл серии Python 2.7 подробно описан в PEP 373.

Вот некоторые ключевые последствия долгосрочного значения 2,7:

  • Как отмечалось выше, версия 2.7 имеет гораздо более длительный период обслуживания по сравнению с более ранними версиями 2.x. В настоящее время ожидается, что Python 2.7 будет поддерживаться основной командой разработчиков (получая обновления безопасности и другие исправления ошибок) как минимум до 2020 года (через 10 лет после его первоначального релиза по сравнению с более типичным периодом поддержки в 18–24 месяца).
  • По мере устаревания стандартной библиотеки Python 2.7 эффективное использование индекса пакетов Python (напрямую или через распространителя) становится все более важным для пользователей Python 2. В дополнение к большому количеству сторонних пакетов для различных задач, доступные пакеты включают в себя бэкпорты новых модулей и функций из стандартной библиотеки Python 3 совместимые с Python 2, а также различные инструменты и библиотеки, упрощающие переход на Python 3. Руководство пользователя по пакетизации Python содержит рекомендации по загрузке и установке программного обеспечения из указателя пакетов Python.
  • Хотя в настоящее время предпочтительным подходом к улучшению Python 2 является публикация новых пакетов в индексе пакетов Python, данный подход не обязательно работает во всех случаях, особенно в тех, которые связаны с сетевой безопасностью. В исключительных случаях, которые не могут быть адекватно обработаны путём публикации новых или обновленных пакетов в PyPI, можно использовать процесс предложения по улучшению Python, чтобы обосновать добавление новых функций непосредственно в стандартную библиотеку Python 2. Любые такие дополнения и отладочные релизы, в которые они были добавлены, будут отмечены в разделе Новые функции, добавленные в отладочные версии Python 2.7 ниже.

Для проектов, желающих перейти с Python 2 на Python 3, или для разработчиков библиотек и фреймворков, желающих поддерживать пользователей как на Python 2, так и на Python 3, доступно множество инструментов и руководств, которые помогут выбрать подходящий подход и управлять некоторыми из них. задействованы технические детали. Рекомендуемой отправной точкой является HOWTO руководство Портирование кода Python 2 на Python 3.

Изменения в обработке предупреждений об устаревании

Для Python 2.7 было принято политическое решение по умолчанию отключать предупреждения, представляющие интерес только для разработчиков. DeprecationWarning и его потомки теперь игнорируются, если не запрошено иное, что не позволяет пользователям видеть предупреждения, инициированные приложением. Это изменение также было внесено в ветку, ставшую Python 3.2. (Обсуждалось на stdlib-sig и выполнялось в bpo-7319.)

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

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

Вы можете снова включить отображение сообщений DeprecationWarning, запустив Python с переключателем -Wdefault (краткая форма: -Wd) или установив для переменной среды PYTHONWARNINGS значение "default" (или "d") перед запуском Python. Код Python также может повторно включить их, вызвав warnings.simplefilter('default').

Модуль unittest также автоматически повторно включает предупреждения об устаревании при выполнении тестов.

Возможности Python 3.1

Подобно тому, как Python 2.6 включает в себя функции Python 3.0, версия 2.7 включает в себя некоторые новые функции Python 3.1. Серия 2.x по-прежнему предоставляет инструменты для перехода на серию 3.x.

Частичный список функций версии 3.1, которые были перенесены в версию 2.7:

  • Синтаксис литералов множеств ({1,2,3} — изменяемое множество).
  • Словарное и множественное включение ({i: i*2 for i in range(3)}).
  • Несколько менеджеров контекста в одном операторе with.
  • Новая версия библиотеки io, переписанная на C для повышения производительности.
  • Тип упорядоченного словаря, описанный в PEP 372: добавление упорядоченного словаря в коллекции.
  • Новый описатель формата ",", рассмотренный в PEP 378: спецификатор формата для разделителя тысяч.
  • Объект memoryview.
  • Небольшое подмножество модуля importlib, приведено ниже.
  • repr() числа с плавающей запятой x во многих случаях короче: теперь оно основано на самой короткой десятичной строке, которая гарантированно округляется до x. Как и в предыдущих версиях Python, гарантируется, что float(repr(x)) восстановит x.
  • Преобразования чисел с плавающей запятой в строку и строки в число с плавающей запятой корректно округляются. Функция round() теперь также правильно округляется.
  • Тип PyCapsule, используемый для предоставления C API для модулей расширения.
  • Функция C API PyLong_AsLongAndOverflow().

Другие новые предупреждения режима Python3 включают в себя:

  • operator.isCallable() и operator.sequenceIncludes(), которые не поддерживаются в 3.x, теперь вызывают предупреждения.
  • Переключатель -3 теперь автоматически включает переключатель -Qwarn, который вызывает предупреждения об использовании классического деления с целыми и длинными целыми числами.

PEP 372: добавление упорядоченного словаря в коллекции

Обычные словари Python перебирают пары ключ/значение в произвольном порядке. За прошедшие годы ряд авторов написали альтернативные реализации, которые запоминают порядок первоначальной вставки ключей. На основе опыта данных реализаций в версии 2.7 представлен новый класс OrderedDict в модуле collections.

API OrderedDict предоставляет тот же интерфейс, что и обычные словари, но перебирает ключи и значения в гарантированном порядке в зависимости от того, когда ключ был впервые вставлен:

>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
...                  ('second', 2),
...                  ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]

Если новая запись перезаписывает существующую запись, исходная позиция вставки остаётся неизменной:

>>> d['second'] = 4
>>> d.items()
[('first', 1), ('second', 4), ('third', 3)]

Удаление записи и повторная вставка переместит её в конец:

>>> del d['second']
>>> d['second'] = 5
>>> d.items()
[('first', 1), ('third', 3), ('second', 5)]

Метод popitem() имеет необязательный аргумент last, который по умолчанию равен True. Если last имеет значение истина, последний добавленный ключ возвращается и удаляется; если ложно, выбирается самый старый ключ:

>>> od = OrderedDict([(x,0) for x in range(20)])
>>> od.popitem()
(19, 0)
>>> od.popitem()
(18, 0)
>>> od.popitem(last=False)
(0, 0)
>>> od.popitem(last=False)
(1, 0)

При сравнении двух упорядоченных словарей проверяются как ключи, так и значения, и требуется, чтобы порядок вставки был одинаковым:

>>> od1 = OrderedDict([('first', 1),
...                    ('second', 2),
...                    ('third', 3)])
>>> od2 = OrderedDict([('third', 3),
...                    ('first', 1),
...                    ('second', 2)])
>>> od1 == od2
False
>>> # Переместить 'third' ключ в конец
>>> del od2['third']; od2['third'] = 3
>>> od1 == od2
True

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

Как работает OrderedDict? Он поддерживает двусвязный список ключей, добавляя новые ключи в список по мере их вставки. Дополнительный словарь сопоставляет ключи с соответствующим узлом списка, поэтому удаление не должно проходить через весь связанный список и, следовательно, остаётся O(1).

Стандартная библиотека теперь поддерживает использование упорядоченных словарей в нескольких модулях.

  • Модуль ConfigParser использует их по умолчанию, а это означает, что файлы конфигурации теперь можно читать, изменять и записывать обратно в исходном порядке.
  • Метод _asdict() для collections.namedtuple() теперь возвращает упорядоченный словарь со значениями, расположенными в том же порядке, что и базовые индексы кортежа.
  • Конструктор класса JSONDecoder модуля json был расширен параметром object_pairs_hook, что позволяет декодеру создавать экземпляры OrderedDict. Также была добавлена поддержка сторонних инструментов, таких как PyYAML.

См.также

PEP 372 — Добавление упорядоченного словаря в коллекции
PEP, написанный Армином Ронахером и Рэймондом Хеттингером; реализован Раймондом Хеттингером.

PEP 378: спецификатор формата для разделителя тысяч

Чтобы сделать вывод программы более читаемым, может быть полезно добавить разделители к большим числам, отображая их как 18,446,744,073,709,551,616 вместо 18446744073709551616.

Полностью общим решением для этого является модуль locale, который может использовать разные разделители («,» в Северной Америке, «.» в Европе) и разные размеры групп, но locale сложен в использовании и не подходит для многопоточных приложений, где разные потоки производят вывод для разных локалей.

Поэтому к мини-языку, используемому методом str.format(), был добавлен простой механизм группировки запятых. При форматировании числа с плавающей запятой просто ставьте запятую между шириной и точностью:

>>> '{:20,.2f}'.format(18446744073709551616.0)
'18,446,744,073,709,551,616.00'

При форматировании целого числа ставьте запятую после ширины:

>>> '{:20,d}'.format(18446744073709551616)
'18,446,744,073,709,551,616'

Данный механизм вообще не адаптируется; запятые всегда используются в качестве разделителя, а группировка всегда состоит из трехзначных групп. Механизм форматирования запятых не такой общий, как в модуле locale, но его проще использовать.

См.также

PEP 378 — Спецификатор формата для разделителя тысяч
PEP, написанный Рэймондом Хеттингером; реализован Эриком Смитом.

PEP 389: Модуль argparse для анализа командных строк

Добавлен модуль argparse для разбора аргументов командной строки в качестве более мощной замены модуля optparse.

Это означает, что Python теперь поддерживает три разных модуля для разбора аргументов командной строки: getopt, optparse и argparse. Модуль getopt очень похож на функцию getopt() библиотеки C, поэтому он остаётся полезным, если вы пишете прототип Python, который в конечном итоге будет переписан на C. это, и нет автоматического способа обновить данные скрипты. (Было обсуждено согласование API argparse с интерфейсом optparse, но оно было отклонено как слишком запутанное и сложное.)

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

Вот пример:

import argparse

parser = argparse.ArgumentParser(description='Command-line example.')

# Добавлены дополнительные переключатели
parser.add_argument('-v', action='store_true', dest='is_verbose',
                    help='produce verbose output')
parser.add_argument('-o', action='store', dest='output',
                    metavar='FILE',
                    help='direct output to FILE instead of stdout')
parser.add_argument('-C', action='store', type=int, dest='context',
                    metavar='NUM', default=0,
                    help='display NUM lines of added context')

# Разрешить любое количество дополнительных аргументов.
parser.add_argument(nargs='*', action='store', dest='inputs',
                    help='input filenames (default is stdin)')

args = parser.parse_args()
print args.__dict__

Если вы не переопределите его, переключатели -h и --help добавляются автоматически и обеспечивают аккуратно отформатированный вывод:

-> ./python.exe argparse-example.py --help
usage: argparse-example.py [-h] [-v] [-o FILE] [-C NUM] [inputs [inputs ...]]

Command-line example.

positional arguments:
  inputs      input filenames (default is stdin)

optional arguments:
  -h, --help  show this help message and exit
  -v          produce verbose output
  -o FILE     direct output to FILE instead of stdout
  -C NUM      display NUM lines of added context

Как и в случае с optparse, переключатели и аргументы командной строки возвращаются в виде объекта с атрибутами, названными параметрами dest:

-> ./python.exe argparse-example.py -v
{'output': None,
 'is_verbose': True,
 'context': 0,
 'inputs': []}

-> ./python.exe argparse-example.py -v -o /tmp/output -C 4 file1 file2
{'output': '/tmp/output',
 'is_verbose': True,
 'context': 4,
 'inputs': ['file1', 'file2']}

argparse имеет гораздо более сложную проверку, чем optparse; вы можете указать точное количество аргументов в виде целого числа, 0 или более аргументов, передав '*', 1 или более аргументов, передав '+', или необязательный аргумент с помощью '?'. Парсер верхнего уровня может содержать вложенные парсеры для определения подкоманд с разными наборами переключателей, например, svn commit, svn checkout и т. д. Вы можете указать тип аргумента как FileType, который будет автоматически открывать для вас файлы и понимать, что '-' означает стандартный ввод или вывод.

См.также

Документация argparse
Страница документации модуля argparse.
Обновление кода optparse
Часть документации Python, определяющая, как конвертировать использующий optparse код.
PEP 389 — argparse — новый модуль синтаксического анализа командной строки
PEP написан и реализован Стивеном Бетардом.

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

Модуль logging очень гибкий; приложения могут определять дерево подсистем ведения журнала, и каждый логгер в этом дереве может отфильтровывать определённые сообщения, форматировать их по-разному и направлять сообщения различному количеству обработчиков.

Вся гибкость может потребовать много настроек. Вы можете написать операторы Python для создания объектов и установки их свойств, но сложная настройка требует многословного, но скучного кода. logging также поддерживает функцию fileConfig(), которая анализирует файл, но формат файла не поддерживает настройку фильтров, и программно генерировать его сложнее.

Python 2.7 добавляет функцию dictConfig(), которая использует словарь для настройки ведения журнала. Есть много способов создать словарь из разных источников: создать словарь с помощью кода; разобрать файл, содержащий JSON; или используйте библиотеку синтаксического анализа YAML, если она установлена. Для получения дополнительной информации см. Функции конфигурации.

В следующем примере настраиваются два логгера: корневой логгер и логгер с именем «сеть». Сообщения, отправленные корневому регистратору, будут отправляться в системный журнал с использованием протокола syslog, а сообщения в «сетевой» логгер будут записываться в файл network.log, который будет чередоваться, как только журнал достигнет 1 МБ.

import logging
import logging.config

configdict = {
 'version': 1,    # Используемая схема конфигурации; должно быть 1 на данный момент
 'formatters': {
     'standard': {
         'format': ('%(asctime)s %(name)-15s '
                    '%(levelname)-8s %(message)s')}},

 'handlers': {'netlog': {'backupCount': 10,
                     'class': 'logging.handlers.RotatingFileHandler',
                     'filename': '/logs/network.log',
                     'formatter': 'standard',
                     'level': 'INFO',
                     'maxBytes': 1000000},
              'syslog': {'class': 'logging.handlers.SysLogHandler',
                         'formatter': 'standard',
                         'level': 'ERROR'}},

 # Указать все подчиненные логгеры
 'loggers': {
             'network': {
                         'handlers': ['netlog']
             }
 },
 # Указать свойства корневого логгера
 'root': {
          'handlers': ['syslog']
 },
}

# Настроить конфигурацию
logging.config.dictConfig(configdict)

# Например, записать два сообщения об ошибках
logger = logging.getLogger('/')
logger.error('Database not found')

netlogger = logging.getLogger('network')
netlogger.error('Connection failed')

Три небольших усовершенствования модуля logging, реализованные Винаем Саджипом:

  • Класс SysLogHandler теперь поддерживает системное ведение журнала через TCP. Конструктор имеет параметр socktype, указывающий тип используемого сокета: socket.SOCK_DGRAM для UDP или socket.SOCK_STREAM для TCP. Протокол по умолчанию остаётся UDP.

  • Экземпляры Logger получили метод getChild(), который извлекает дочерний логгер с использованием относительного пути. Например, когда вы получаете логгер, выполнив log = getLogger('app'), вызов log.getChild('network.listen') эквивалентен getLogger('app.network.listen').

    Класс LoggerAdapter получил метод isEnabledFor(), который принимает level и возвращает, будет ли базовый логгер обрабатывать сообщение такого уровня важности.

См.также

PEP 391 — конфигурация на основе словаря для ведения журнала
PEP написан и реализован Винаем Саджипом.

PEP 3106: представления словаря

Методы словаря keys(), values() и items() отличаются в Python 3.x. Они возвращают объект с именем view вместо полностью материализованного списка.

Невозможно изменить возвращаемые значения keys(), values() и items() в Python 2.7, потому что слишком много кода может сломаться. Вместо этого были добавлены версии 3.x под новыми именами viewkeys(), viewvalues() и viewitems().

>>> d = dict((i*10, chr(65+i)) for i in range(26))
>>> d
{0: 'A', 130: 'N', 10: 'B', 140: 'O', 20: ..., 250: 'Z'}
>>> d.viewkeys()
dict_keys([0, 130, 10, 140, 20, 150, 30, ..., 250])

Представления можно повторять, но представления ключей и элементов также ведут себя как множества. Оператор & выполняет пересечение, а | выполняет объединение:

>>> d1 = dict((i*10, chr(65+i)) for i in range(26))
>>> d2 = dict((i**.5, i) for i in range(1000))
>>> d1.viewkeys() & d2.viewkeys()
set([0.0, 10.0, 20.0, 30.0])
>>> d1.viewkeys() | range(0, 30)
set([0, 1, 130, 3, 4, 5, 6, ..., 120, 250])

Представление отслеживает словарь, и его содержимое изменяется по мере изменения словаря:

>>> vk = d.viewkeys()
>>> vk
dict_keys([0, 130, 10, ..., 250])
>>> d[260] = '&'
>>> vk
dict_keys([0, 130, 260, 10, ..., 250])

Однако обратите внимание, что вы не можете добавлять или удалять ключи во время перебора представления:

>>> for k in vk:
...     d[k*2] = k
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

Вы можете использовать методы представления в коде Python 2.x, и преобразователь 2to3 изменит их на стандартные методы keys(), values() и items().

См.также

PEP 3106 — обновление dict.keys(), .values() и .items()
PEP, написанный Гвидо ван Россумом. Обратно портирован на 2.7 Александром Вассалотти; bpo-1967.

PEP 3137: объект memoryview

Объект memoryview предоставляет представление содержимого памяти другого объекта, которое соответствует интерфейсу типа bytes.

>>> import string
>>> m = memoryview(string.letters)
>>> m
<memory at 0x37f850>
>>> len(m)           # Возвращает длину базового объекта
52
>>> m[0], m[25], m[26]   # Индексация возвращает один байт
('a', 'z', 'A')
>>> m2 = m[0:26]         # Нарезка возвращает другое memoryview
>>> m2
<memory at 0x37f080>

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

>>> m2.tobytes()
'abcdefghijklmnopqrstuvwxyz'
>>> m2.tolist()
[97, 98, 99, 100, 101, 102, 103, ... 121, 122]
>>>

Объекты memoryview позволяют изменять базовый объект, если он является изменяемым объектом.

>>> m2[0] = 75
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot modify read-only memory
>>> b = bytearray(string.letters)  # Создание изменяемого объекта
>>> b
bytearray(b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
>>> mb = memoryview(b)
>>> mb[0] = '*'         # Назначить для просмотра, изменив bytearray.
>>> b[0:5]              # Bytearray был изменён.
bytearray(b'*bcde')
>>>

См.также

PEP 3137 — неизменяемые байты и изменяемый буфер
PEP, написанный Гвидо ван Россумом. Реализован Трэвисом Олифантом, Антуаном Питру и другими. Обратно перенесено на версию 2.7 Антуаном Питру; bpo-2396.

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

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

  • Синтаксис для заданных литералов был перенесен из Python 3.x. Содержимое результирующего изменяемого множества заключено в фигурные скобки; Литералы set отличаются от словарей тем, что не содержат двоеточий и значений. {} продолжает представлять пустой словарь; используйте set() для пустого множества.
  >>> {1, 2, 3, 4, 5}
  set([1, 2, 3, 4, 5])
  >>> set() # пустое множество
  set([])
  >>> {}    # пустой словарь
  {}

Поддержано Александром Вассалотти; :issue:`2335`.
  • Словарные включения и множеств — ещё одна функция, перенесенная из версии 3.x и обобщающая включения списков/генераторов для использования литерального синтаксиса для множеств и словарей.

    >>> {x: x*x for x in range(6)}
    {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
    >>> {('a'*x) for x in range(6)}
    set(['', 'a', 'aa', 'aaa', 'aaaa', 'aaaaa'])
    

    Поддержано Александром Вассалотти; bpo-2333.

  • Оператор with теперь может использовать несколько менеджеров контекста в одном операторе. Менеджеры контекста обрабатываются слева направо, и каждый рассматривается как начало нового оператора with. Это значит, что:

    with A() as a, B() as b:
        ... множество утверждений ...
    

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

    with A() as a:
        with B() as b:
            ... множество утверждений ...
    

    Функция contextlib.nested() предоставляет очень похожую функцию, поэтому она больше не нужна и устарела.

    (Предложено в 53094; реализовано Георгом Брандлом.)

  • Преобразования между числами с плавающей запятой и строками теперь корректно округляются на большинстве платформ. Данные преобразования происходят в разных местах: str() для чисел с плавающей запятой и комплексных чисел; конструкторы float и complex; числовое форматирование; сериализация и десериализация вещественных и комплексных чисел с использованием модулей marshal, pickle и json; парсинг float и мнимых литералов в коде Python; и преобразование Decimal в число с плавающей запятой.

    В связи с этим repr() числа с плавающей запятой x теперь возвращает результат, основанный на самой короткой десятичной строке, которая гарантированно округляется до x при правильном округлении (в режиме округления от половины до четного). Раньше он давал строку, основанную на округлении x до 17 десятичных цифр.

    Библиотека округления, отвечающая за это улучшение, работает на платформах Windows и Unix с использованием компиляторов gcc, icc или suncc. Может быть небольшое количество платформ, на которых нельзя гарантировать правильную работу этого кода, поэтому код не используется в таких системах. Вы можете узнать, какой код используется, проверив sys.float_repr_style, который будет short, если новый код используется, и legacy, если нет.

    Реализовано Эриком Смитом и Марком Дикинсоном с использованием библиотеки dtoa.c Дэвида Гея; bpo-7117.

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

    >>> n = 295147905179352891391
    >>> float(n)
    2.9514790517935283e+20
    >>> n - long(float(n))
    65535L
    

    Результат с плавающей запятой Python 2.7 больше, но гораздо ближе к истинному значению:

    >>> n = 295147905179352891391
    >>> float(n)
    2.9514790517935289e+20
    >>> n - long(float(n))
    -1L
    

    (Реализовано Марком Дикинсоном; bpo-3166.)

    Целочисленное деление также более точно при округлении. (Также реализовано Марком Дикинсоном; bpo-1811.)

  • Убрано неявное приведение комплексных чисел; интерпретатор больше не будет пытаться вызывать метод __coerce__() для сложных объектов. (Удалено Меадором Инге и Марком Дикинсоном; bpo-5211.)

  • Метод str.format() теперь поддерживает автоматическую нумерацию замещающих полей. Это делает использование str.format() более похожим на форматирование %s:

    >>> '{}:{}:{}'.format(2009, 04, 'Sunday')
    '2009:4:Sunday'
    >>> '{}:{}:{day}'.format(2009, 4, day='Sunday')
    '2009:4:Sunday'
    

    Автоматическая нумерация принимает поля слева направо, поэтому первый спецификатор {...} будет использовать первый аргумент для str.format(), следующий спецификатор будет использовать следующий аргумент и так далее. Вы не можете смешивать автоматическую нумерацию и явную нумерацию — либо нумеровать все поля спецификатора, либо ни одного из них — но вы можете смешивать автоматическую нумерацию и именованные поля, как во втором примере выше. (Предоставлено Эриком Смитом; bpo-5237.)

    Комплексные числа теперь правильно поддерживают использование с format() и по умолчанию выравниваются по правому краю. Указание точности или разделения запятыми применяется как к действительной, так и к мнимой части числа, но указанная ширина поля и выравнивание применяются ко всему выходному результату 1.5+3j. (Предоставлено Эриком Смитом; bpo-1588 и bpo-7988.)

    Код формата «F» теперь всегда форматирует свой вывод с использованием символов верхнего регистра, поэтому теперь он будет создавать «INF» и «NAN». (Предоставлено Эриком Смитом; bpo-3382.)

    Низкоуровневое изменение: метод object.__format__() теперь вызывает PendingDeprecationWarning, если ему передана строка формата, потому что метод __format__() для object преобразует объект в строковое представление и форматирует его. Ранее метод автоматически применял строку формата к строковому представлению, но это могло скрыть ошибки в коде Python. Если вы предоставляете информацию о форматировании, такую как выравнивание или точность, вероятно, вы ожидаете, что форматирование будет применяться каким-то специфичным для объекта способом. (Исправлено Эриком Смитом; bpo-7994.)

  • Типы int() и long() получили метод bit_length, который возвращает количество битов, необходимых для представления его аргумента в двоичном виде:

    >>> n = 37
    >>> bin(n)
    '0b100101'
    >>> n.bit_length()
    6
    >>> n = 2**123-1
    >>> n.bit_length()
    123
    >>> (n+1).bit_length()
    124
    

    (Предоставлено Фредриком Йоханссоном и Виктором Стиннером; bpo-3439.)

  • Оператор import больше не будет пытаться выполнить абсолютный импорт в случае сбоя относительного импорта (например, from .os import sep). Это исправляет ошибку, но может привести к поломке некоторых операторов import, которые работали только случайно. (Исправлено Meador Inge; bpo-7902.)

  • Теперь подкласс встроенного типа unicode может переопределить метод __unicode__(). (Реализовано Виктором Стиннером; bpo-1583863.)

  • Метод translate() типа bytearray теперь принимает None в качестве первого аргумента. (Исправлено Георгом Брандлом; bpo-4759.)

  • При использовании @classmethod и @staticmethod для переноса методов в виде классов или статических методов объект-оболочка теперь предоставляет обернутую функцию как свой атрибут __func__. (Предоставлено Амори Форжо д«Арк по предложению Джорджа Саккиса; bpo-5982.)

  • Если с помощью __slots__ был установлен ограниченный множество атрибутов, удаление неустановленного атрибута не вызовет AttributeError, как можно было бы ожидать. Исправлено Бенджамином Петерсоном; bpo-7604.)

  • Теперь поддерживаются две новые кодировки: «cp720», используемая в основном для арабского текста; и «cp858», вариант CP 850 с добавлением символа евро. (CP720 предоставлен Александром Бельченко и Амори Форжо д«Арк в bpo-1616979; CP858 предоставлен Тимом Хэтчем в bpo-8016.)

  • Объект file теперь будет устанавливать атрибут filename в исключении IOError при попытке открыть каталог на платформах POSIX (отмечено Яном Калишевски; bpo-4764), и теперь явно проверяет и запрещает запись в файловые объекты, доступные только для чтения, вместо того, чтобы доверять C библиотека для обнаружения и сообщения об ошибке (исправлено Stefan Krah; bpo-5677).

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

  • Дополнительные скобки в определениях функций запрещены в Python 3.x, а это означает, что вы получить синтаксическую ошибку из def f((x)): pass. В режиме предупреждения Python3 Python 2.7 теперь будет предупреждать об этом странном использовании. (Отмечено Джеймсом Лингардом; bpo-7362.)

  • Теперь можно создавать слабые ссылки на объекты классов в старом стиле. Классы нового стиля всегда были слабоссылочными. (Исправлено Антуаном Питру; bpo-8268.)

  • Когда объект модуля подвергается сборке мусора, словарь модуля теперь очищается только в том случае, если ни у кого больше нет ссылки на словарь (bpo-7140).

Изменения интерпретатора

Новая переменная среды PYTHONWARNINGS позволяет управлять предупреждениями. Он должен быть установлен в строку, содержащую настройки предупреждений, эквивалентные используемым с переключателем -W, разделенные запятыми. (Предоставлено Брайаном Кертином; bpo-7301.)

Например, следующий параметр будет печатать предупреждения каждый раз, когда они появляются, но превращать предупреждения из модуля Cookie в ошибку. (Точный синтаксис для установки переменной среды зависит от операционной системы и оболочки.)

export PYTHONWARNINGS=all,error:::Cookie:0

Оптимизации

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

  • Был добавлен новый код операции для выполнения первоначальной настройки операторов with, поиска методов __enter__() и __exit__(). (Предоставлено Бенджамином Петерсоном.)

  • Сборщик мусора теперь работает лучше для одного распространенного шаблона использования: когда выделяется много объектов, не освобождая ни один из них. Раньше сборка мусора занимала квадратичное время, но теперь количество полных сборок мусора уменьшается по мере роста количества объектов в куче. Новая логика выполняет полный цикл сборки мусора только в том случае, если среднее поколение было собрано 10 раз и когда количество уцелевших объектов среднего поколения превышает 10 % от количества объектов самого старого поколения. (Предложено Мартином фон Лёвисом и реализовано Антуаном Питру; bpo-4074.)

  • Сборщик мусора пытается избежать отслеживания простых контейнеров, которые не могут быть частью цикла. В Python 2.7 это теперь верно для кортежей и словарей, содержащих атомарные типы (целые числа, строки и т. д.). Транзитивно, dict, содержащий кортежи атомарных типов, также не будет отслеживаться. Это помогает снизить стоимость каждой сборки мусора за счет уменьшения количества объектов, которые должны быть рассмотрены и пройдены сборщиком. (Предоставлено Антуаном Питру; bpo-4688.)

  • Длинные целые числа теперь хранятся внутри либо в базе 2**15, либо в базе 2**30, база определяется во время сборки. Раньше они всегда хранились в базе 2**15. Использование основание 2**30 дает значительное повышение производительности на 64-разрядных машинах, но результаты тестов на 32-разрядных машинах были неоднозначными. Поэтому по умолчанию используется база 2**30 на 64-разрядных машинах и база 2**15 на 32-разрядных машинах; в Unix появилась новая опция настройки --enable-big-digits, которую можно использовать для переопределения этого значения по умолчанию.

    Помимо улучшения производительности, это изменение должно быть незаметно для конечных пользователей, за одним исключением: для целей тестирования и отладки существует новый structseq sys.long_info, который предоставляет информацию о внутреннем формате, предоставляя количество битов на цифру и размер в байтах. Тип C используется для хранения каждой цифры:

    >>> import sys
    >>> sys.long_info
    sys.long_info(bits_per_digit=30, sizeof_digit=4)
    

    (Предоставлено Марком Дикинсоном; bpo-4258.)

    Другой множество изменений сделал длинные объекты на несколько байтов меньше: на 2 байта меньше в 32-битных системах и на 6 байтов в 64-битных. (Предоставлено Марком Дикинсоном; bpo-5260.)

  • Алгоритм деления длинных целых чисел стал быстрее за счет сокращения внутреннего цикла, выполнения сдвигов вместо умножения и исправления ненужной дополнительной итерации. Различные тесты показывают ускорение от 50% до 150% для длинных целочисленных делений и операций по модулю. (Предоставлено Марком Дикинсоном; bpo-5512.) Побитовые операции также значительно быстрее (исходный патч Грегори Смита; bpo-1087418).

  • Реализация % проверяет, является ли левый операнд строкой Python, и обрабатывает его в особых случаях; это приводит к увеличению производительности на 1-3% для приложений, которые часто используют % со строками, например, библиотеки шаблонов. (Реализовано Коллином Винтером; bpo-5176.)

  • Включение списка с условием if компилируется в более быстрый байт-код. (Исправление Антуана Питру, обратное портирование на версию 2.7 Джеффри Ясскином; bpo-4715.)

  • Преобразование целого числа или длинного целого числа в десятичную строку стало быстрее благодаря основанию 10 в специальном регистре вместо использования обобщенной функции преобразования, которая поддерживает произвольные основания. (Патч от Гавейна Болтона; bpo-6713.)

  • Методы split(), replace(), rindex(), rpartition() и rsplit() строкоподобных типов (строки, строки Юникод и объекты bytearray) теперь используют алгоритм быстрого обратного поиска вместо посимвольного сканирования. Иногда это происходит в 10 раз быстрее. (Добавлено Флоран Шиклуна; bpo-7462 и bpo-7622.)

  • Модули pickle и cPickle теперь автоматически интернируют строки, используемые для имён атрибутов, уменьшая использование памяти объектами, полученными в результате распаковки. (Предоставлено Джейком Макгуайром; bpo-5084.)

  • Модуль cPickle теперь использует специальные словари, почти вдвое сокращая время, необходимое для их обработки. (Предоставлено Коллином Винтером; bpo-5670.)

Новые и улучшенные модули

Как и в каждом выпуске, стандартная библиотека Python получила ряд улучшений и исправлений ошибок. Вот неполный список наиболее заметных изменений, отсортированных в алфавитном порядке по имени модуля. Обратитесь к файлу Misc/NEWS в дереве исходного кода, чтобы получить более полный список изменений, или просмотрите все подробности в журналах Subversion.

  • Базовый класс отладки модуля bdb Bdb получил функцию пропуска модулей. Конструктор теперь принимает итерируемый объект, содержащий шаблоны в стиле glob, например, django.*; отладчик не будет входить в фреймы стека из модуля, соответствующего одному из данных шаблонов. (Предоставлено Мару Ньюби по предложению Сентила Кумарана; bpo-5142.)

  • Модуль binascii теперь поддерживает API буфера, поэтому его можно использовать с экземплярами memoryview и другими подобными объектами буфера. (Бэкпорт из 3.x Флораном Шиклуной; bpo-7703.)

  • Обновленный модуль: модуль bsddb обновлен с 4.7.2devel9 до версии 4.8.4 пакет pybsddb. В новой версии улучшена совместимость с Python 3.x, исправлены различные ошибки, а также добавлено несколько новых флагов и методов BerkeleyDB. (Обновлено Хесусом Сеа Авионом; bpo-8156. Журнал изменений pybsddb можно прочитать по адресу http://hg.jcea.es/pybsddb/file/tip/ChangeLog.)

  • BZ2File модуля bz2 теперь поддерживает протокол управления контекстом, поэтому вы можете написать with bz2.BZ2File(...) as f:. (Предоставлено Хагеном Фюрстенау; bpo-3860.)

  • Новый класс: класс Counter в модуле collections полезен для подсчета данных. Экземпляры Counter ведут себя в основном как словари, но возвращают ноль для отсутствующих ключей вместо создания KeyError:

    >>> from collections import Counter
    >>> c = Counter()
    >>> for letter in 'here is a sample of english text':
    ...   c[letter] += 1
    ...
    >>> c 
    Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2,
    'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1,
    'p': 1, 'r': 1, 'x': 1})
    >>> c['e']
    5
    >>> c['z']
    0
    

    Существует три дополнительных метода Counter. most_common() возвращает N наиболее распространенных элементов и их количество. elements() возвращает итератор для содержащихся элементов, повторяя каждый элемент столько раз, сколько его количество. subtract() принимает итерируемый объект и вычитает единицу для каждого элемента вместо добавления; если аргументом является словарь или другой Counter, счетчики вычитаются.

    >>> c.most_common(5)
    [(' ', 6), ('e', 5), ('s', 3), ('a', 2), ('i', 2)]
    >>> c.elements() ->
       'a', 'a', ' ', ' ', ' ', ' ', ' ', ' ',
       'e', 'e', 'e', 'e', 'e', 'g', 'f', 'i', 'i',
       'h', 'h', 'm', 'l', 'l', 'o', 'n', 'p', 's',
       's', 's', 'r', 't', 't', 'x'
    >>> c['e']
    5
    >>> c.subtract('very heavy on the letter e')
    >>> c['e']    # Счетчик теперь меньше
    -1
    

    Предоставлено Рэймондом Хеттингером; bpo-1696199.

    Новый класс: OrderedDict описан в предыдущем разделе PEP 372: добавление упорядоченного словаря в коллекции.

    Новый метод: тип данных deque теперь имеет метод count(), возвращающий количество содержащихся элементов, равное предоставленному аргументу x, и метод reverse(), меняющий местами элементы двухсторонней очереди. deque также предоставляет свою максимальную длину как доступный только для чтения атрибут maxlen. (Обе функции добавлены Рэймондом Хеттингером.)

    Класс namedtuple теперь имеет необязательный параметр rename. Если rename имеет значение истина, имена полей, которые являются недопустимыми из-за того, что они повторяются или не являются допустимыми идентификаторами Python, будут переименованы в допустимые имена, полученные на основе позиции поля в списке полей:

    >>> from collections import namedtuple
    >>> T = namedtuple('T', ['field1', '$illegal', 'for', 'field2'], rename=True)
    >>> T._fields
    ('field1', '_1', '_2', 'field2')
    

    (Добавлено Рэймондом Хеттингером; bpo-1818.)

    Наконец, абстрактный базовый класс Mapping теперь возвращает NotImplemented, если сопоставление сравнивается с другим типом, отличным от Mapping. (Исправлено Даниэлем Штуцбахом; bpo-8729.)

  • Конструкторы для классов парсеров в модуле ConfigParser теперь принимают параметр allow_no_value, по умолчанию равный false; если true, будут разрешены опции без значений. Например:

    >>> import ConfigParser, StringIO
    >>> sample_config = """
    ... [mysqld]
    ... user = mysql
    ... pid-file = /var/run/mysqld/mysqld.pid
    ... skip-bdb
    ... """
    >>> config = ConfigParser.RawConfigParser(allow_no_value=True)
    >>> config.readfp(StringIO.StringIO(sample_config))
    >>> config.get('mysqld', 'user')
    'mysql'
    >>> print config.get('mysqld', 'skip-bdb')
    None
    >>> print config.get('mysqld', 'unknown')
    Traceback (most recent call last):
      ...
    NoOptionError: No option 'unknown' in section: 'mysqld'
    

    (Предоставлено Матсом Киндалом; bpo-7005.)

  • Устаревшая функция: contextlib.nested(), которая позволяет обрабатывать более одного менеджера контекста с помощью одного оператора with, устарела, поскольку оператор with теперь поддерживает несколько менеджеров контекста.

  • Модуль cookielib теперь игнорирует cookie с недопустимым полем версии, которое не содержит целочисленного значения. (Исправлено Джоном Дж. Ли; bpo-3924.)

  • Функция deepcopy() модуля copy теперь будет корректно копировать привязанные методы экземпляра. (Реализовано Робертом Коллинзом; bpo-1515.)

  • Модуль ctypes теперь всегда преобразует None в указатель C NULL для аргументов, объявленных как указатели. (Изменено Томасом Хеллером; bpo-4606.) Базовая библиотека libffi был обновлен до версии 3.0.9, содержащей различные исправления для разных платформ. (Обновлено Маттиасом Клозе; bpo-8142.)

  • Новый метод: класс timedelta модуля datetime получил метод total_seconds(), который возвращает количество секунд в продолжительности. (Предоставлено Брайаном Куинланом; bpo-5788.)

  • Новый метод: класс Decimal получил метод класса from_float(), который выполняет точное преобразование числа с плавающей запятой в Decimal. Это точное преобразование стремится к ближайшему десятичному приближению к значению представления с плавающей запятой; результирующее десятичное значение будет по-прежнему включать неточность, если таковая имеется. Например, Decimal.from_float(0.1) возвращает Decimal('0.1000000000000000055511151231257827021181583404541015625'). (Реализован Раймондом Хеттингером; bpo-4796.)

    Сравнение экземпляров Decimal с числами с плавающей запятой теперь дает разумные результаты на основе числовых значений операндов. Раньше такие сравнения возвращались к правилам Python по умолчанию для сравнения объектов, которые давали произвольные результаты в зависимости от их типа. Обратите внимание, что вы по-прежнему не можете комбинировать Decimal и числа с плавающей запятой в других операциях, таких как сложение, т. к. вы должны явно выбрать способ преобразования между числами с плавающей запятой и Decimal. (Исправлено Марком Дикинсоном; bpo-2531.)

    Конструктор для Decimal теперь принимает числа с плавающей запятой (добавлено Рэймондом Хеттингером; bpo-8257) и неевропейские символы Юникод, например, арабско-индийские цифры (предоставлено Марком Дикинсоном; bpo-6595).

    Большинство методов класса Context теперь принимают целые числа, а также экземпляры Decimal; единственными исключениями являются методы canonical() и is_canonical(). (Заплатка Хуана Хосе Конти; bpo-7633.)

    При использовании экземпляров Decimal со строковым методом format() выравнивание по умолчанию ранее было выравниванием по левому краю. Это было изменено на выравнивание по правому краю, что более удобно для числовых типов. (Изменено Марком Дикинсоном; bpo-6857.)

    Сравнения, включающие сигнальное значение NaN (или sNAN), теперь сигнализируют InvalidOperation вместо молчаливого возврата истинного или ложного значения в зависимости от оператора сравнения. Тихие значения NaN (или NaN) теперь можно хэшировать. (Исправлено Марком Дикинсоном; bpo-7279.)

  • Модуль difflib теперь производит выходные данные, более совместимые с современными инструментами diff/patch, за счет одного небольшого изменения, используя символ табуляции вместо пробелов в качестве разделителя в заголовке, указывающем имя файла. (Исправил Анатолий Техтоник; bpo-7585.)

  • Команда Distutils sdist теперь всегда регенерирует файл MANIFEST, поскольку даже если файлы MANIFEST.in или setup.py не были изменены, пользователь мог создать некоторые новые файлы, которые следует включить. (Исправлено Тареком Зиаде; bpo-8688.)

  • Флаг IGNORE_EXCEPTION_DETAIL модуля doctest теперь будет игнорировать имя модуля, содержащего проверяемое исключение. (Исправление Леннарта Регебро; bpo-7490.)

  • Класс Message модуля email теперь будет принимать полезную нагрузку со значением Юникод, автоматически преобразовывая полезную нагрузку в кодировку, указанную output_charset. (Добавлено Р. Дэвидом Мюрреем; bpo-1368247.)

  • Класс Fraction теперь принимает одно число с плавающей запятой или экземпляр Decimal или два рациональных числа в качестве аргументов своего конструктора. (Реализовано Марком Дикинсоном; рациональные числа добавлены в bpo-5812, а числа с плавающей/десятичной запятой — в bpo-8294.)

    Упорядочивание сравнений (<, <=, >, >=) между дробями и комплексными числами теперь вызывает TypeError. Это исправляет оплошность, делая Fraction совпадающим с другими числовыми типами.

  • Новый класс: FTP_TLS в модуле ftplib обеспечивает безопасные FTP-соединения с использованием TLS-инкапсуляции аутентификации, а также последующего управления и передачи данных. (Предоставлено Джампаоло Родола; bpo-2054.)

    Метод storbinary() для загрузки двоичных файлов теперь может перезапускать загрузку благодаря добавленному параметру rest (исправление Пабло Музо; bpo-6845.)

  • Новый декоратор класса: total_ordering() в модуле functools принимает класс, определяющий метод __eq__() и один из __lt__(), __le__(), __gt__() или __ge__(), и создаёт отсутствующие методы сравнения. Поскольку метод __cmp__() устарел в Python 3.x, данный декоратор упрощает определение упорядоченных классов. (Добавлено Рэймондом Хеттингером; bpo-5479.)

    Новая функция: cmp_to_key() будет принимать функцию сравнения старого стиля, ожидающая два аргумента, и возвращающая новый вызываемый объект, используемый в качестве параметра key для таких функций, как sorted(), min() и max() и т. д. код, совместимый с Python 3.x. (Добавлено Рэймондом Хеттингером)

  • Новая функция: is_tracked() модуля gc возвращает истина, если данный экземпляр отслеживается сборщиком мусора, и ложь в противном случае. (Предоставлено Антуаном Питру; bpo-4688.)

  • GzipFile модуля gzip теперь поддерживает протокол управления контекстом, поэтому вы можете написать with gzip.GzipFile(...) as f: (предоставлено Хаген Фюрстенау; bpo-3860), и теперь он реализует io.BufferedIOBase ABC, поэтому вы можете обернуть его io.BufferedReader для более быстрой обработки (предоставлено Нир Аидес; bpo-7471). Также теперь можно переопределить время модификации, записанное в gzip-файле, предоставив конструктору необязательную метку времени. (Предоставлено Жаком Фреше; bpo-4272.)

    Файлы в формате gzip могут быть дополнены завершающими нулевыми байтами; модуль gzip теперь будет потреблять данные замыкающие байты. (Исправлено Тадеком Петрашеком и Брайаном Кертином; bpo-2846.)

  • Новый атрибут: у модуля hashlib теперь есть атрибут algorithms, содержащий кортеж с именами поддерживаемых алгоритмов. В Python 2.7 hashlib.algorithms содержит ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512'). (Предоставлено Карлом Шене; bpo-7418.)

  • Класс HTTPResponse по умолчанию, используемый модулем httplib, теперь поддерживает буферизацию, что приводит к более быстрому чтению ответов HTTP. (Предоставлено Кристьяном Валуром Йонссоном; bpo-4879.)

    Классы HTTPConnection и HTTPSConnection теперь поддерживают параметр source_address, состоящий из двух кортежей (host, port), задающий исходный адрес, который будет использоваться для соединения. (Предоставлено Элдоном Зиглером; bpo-3972.)

  • Модуль ihooks теперь поддерживает относительный импорт. Обратите внимание, что ihooks — это более старый модуль для настройки импорта, замененный модулем imputil, добавленным в Python 2.0. (Относительная поддержка импорта добавлена Нилом Шеменауэром)

  • Модуль imaplib теперь поддерживает адреса IPv6. (Предоставлено Дереком Морром; bpo-1655.)

  • Новая функция: getcallargs() модуля inspect принимает вызываемый объект, его позиционные и ключевые аргументы и вычисляет, какие из параметров вызываемого объекта получат каждый аргумент, возвращая словарь, отображающий имена аргументов в их значения. Например:

    >>> from inspect import getcallargs
    >>> def f(a, b=1, *pos, **named):
    ...     pass
    >>> getcallargs(f, 1, 2, 3)
    {'a': 1, 'b': 2, 'pos': (3,), 'named': {}}
    >>> getcallargs(f, a=2, x=4)
    {'a': 2, 'b': 1, 'pos': (), 'named': {'x': 4}}
    >>> getcallargs(f)
    Traceback (most recent call last):
    ...
    TypeError: f() takes at least 1 argument (0 given)
    

    Предоставлено Джорджем Саккисом; bpo-3135.

  • Обновленный модуль: библиотека io обновлена до версии, поставляемой с Python 3.1. Для версии 3.1 библиотека ввода-вывода была полностью переписана на C и работает от 2 до 20 раз быстрее в зависимости от выполняемой задачи. Первоначальная версия Python была переименована в модуль _pyio.

    Одно незначительное изменение: класс io.TextIOBase теперь имеет атрибут errors, задающий настройку ошибки, используемую для ошибок кодирования и декодирования (один из 'strict', 'replace', 'ignore').

    Класс io.FileIO теперь вызывает OSError при передаче недопустимого файлового дескриптора. (Реализовано Бенджамином Петерсоном; bpo-4991.) Метод truncate() теперь сохраняет позицию в файле; ранее он менял позицию файла на конец нового файла. (Исправлено Паскалем Шамбоном; bpo-6939.)

  • Новая функция: itertools.compress(data, selectors) принимает два итератора. Элементы data возвращаются, если соответствующее значение в selectors истинно:

    itertools.compress('ABCDEF', [1,0,1,0,1,1]) =>
      A, C, E, F
    

    Новая функция: itertools.combinations_with_replacement(iter, r) возвращает все возможные комбинации элементов длиной r из итерируемого iter. В отличие от combinations(), отдельные элементы могут повторяться в сгенерированных комбинациях:

    itertools.combinations_with_replacement('abc', 2) =>
      ('a', 'a'), ('a', 'b'), ('a', 'c'),
      ('b', 'b'), ('b', 'c'), ('c', 'c')
    

    Обратите внимание, что элементы считаются уникальными в зависимости от их положения во входных данных, а не от их фактических значений.

    У функции itertools.count() теперь есть аргумент step, который позволяет увеличивать отличные от 1 значения. count() также теперь позволяет использовать аргументы ключевых слов и использовать нецелочисленные значения, такие, как числа с плавающей запятой или экземпляры Decimal. (Реализован Раймондом Хеттингером; bpo-5032.)

    itertools.combinations() и itertools.product() ранее поднимали ValueError для значений r, превышающих входную итерацию. Это было сочтено ошибкой спецификации, поэтому теперь они возвращают пустой итератор. (Исправлено Рэймондом Хеттингером; bpo-4816.)

  • Обновленный модуль: модуль json был обновлен до версии 2.0.9 пакета simplejson, который включает расширение C, ускоряющее кодирование и декодирование. (Предоставлено Бобом Ипполито; bpo-4136.)

    Для поддержки нового типа collections.OrderedDict в json.load() теперь есть необязательный параметр object_pairs_hook, который будет вызываться с любым литералом объекта, декодируемым в список пар. (Предоставлено Рэймондом Хеттингером; bpo-5381.)

  • Класс Maildir модуля mailbox теперь записывает отметку времени в каталогах, которые он читает, и перечитывает их только в том случае, если время модификации впоследствии изменилось. Это вызывает производительность, позволяя избежать ненужного сканирования каталогов. (Исправлено А. М. Кухлингом и Антуаном Питру; bpo-1607951, bpo-6896.)

  • Новые функции: модуль math получил erf() и erfc() для функции ошибок и дополнительной функции ошибок, expm1(), который вычисляет e**x - 1 с большей точностью, чем при использовании exp() и вычитании 1, gamma() для гамма-функции и lgamma() для естественного логарифма гамма-функции. (Предоставлено Марком Дикинсоном и nirinA raseliarison; bpo-3366.)

  • Классы Manager* модуля multiprocessing теперь могут передавать вызываемый объект, вызываемый при каждом запуске подпроцесса, вместе с набором передаваемых вызываемому объекту аргументов. (Предоставлено lekma; bpo-5585.)

    Класс Pool, управляющий пулом рабочих процессов, теперь имеет необязательный параметр maxtasksperchild. Рабочие процессы выполнят указанное количество задач, а затем завершатся, в результате чего Pool запустит новый рабочий процесс. Это полезно, если задачи могут привести к утечке памяти или других ресурсов, или если некоторые задачи приведут к тому, что рабочий процесс станет очень большим. (Предоставлено Чарльзом Кэзабоном; bpo-6963.)

  • Модуль nntplib теперь поддерживает адреса IPv6. (Предоставлено Дереком Морром; bpo-1664.)

  • Новые функции: модуль os оборачивает следующие системные вызовы POSIX: getresgid() и getresuid(), возвращающие реальные, действующие и сохраненные GID и UID; setresgid() и setresuid(), устанавливающие новые значения реальных, действующих и сохраненных GID и UID; initgroups(), которые инициализируют список группового доступа для текущего процесса. (Функции GID/UID предоставлены Трэвис Х.; bpo-6508. Поддержка групп инициализации добавлена Жан-Поль Кальдероне; bpo-7333.)

    Функция os.fork() теперь повторно инициализирует блокировку импорта в дочернем процессе; это устраняет проблемы в Solaris, когда fork() вызывается из потока. (Исправлено Жолтом Черной; bpo-7242.)

  • В модуле os.path функции normpath() и abspath() теперь сохраняют Юникод; если их входной путь является строкой Юникод, возвращаемое значение также является строкой Юникод. (normpath() исправлено Matt Giuca в bpo-5827; abspath() исправлено Ezio Melotti в bpo-3426.)

  • Модуль pydoc теперь содержит справку по различным символам, которые использует Python. Например, теперь вы можете ввести help('<<') или help('@'). (Предоставлено Дэвидом Лабаном; bpo-4739.)

  • split(), sub() и subn() модуля re теперь принимают необязательный аргумент flags для согласованности с другими функциями модуля. (Добавлено Грегори П. Смитом)

  • Новая функция: run_path() в модуле runpy будет выполнять код с предоставленным аргументом path. path может быть путём к исходному файлу Python (example.py), скомпилированному файлу байт-кода (example.pyc), каталогу (./package/) или zip-архиву (example.zip). Если указан каталог или почтовый путь, он будет добавлен в начало sys.path, а модуль __main__ будет импортирован. Ожидается, что каталог или zip-файл содержат __main__.py; если это не так, некоторые другие __main__.py могут быть импортированы из расположения позже в sys.path. Это делает больше механизмов runpy доступными для сценариев, имитирующим возможности командной строки Python обрабатывать явное имя пути. (Добавлено Ником Когланом; bpo-6816.)

  • Новая функция: в модуле shutil make_archive() принимает имя файла, тип архива (формат zip или tar) и путь к каталогу и создаёт архив, содержащий содержимое каталога. (Добавлено Тареком Зиаде.)

    Функции shutil copyfile() и copytree() теперь вызывают исключение SpecialFileError при запросе на копирование именованного канала. Раньше код обрабатывал именованные каналы как обычный файл, открывая их для чтения, и это блокировалось на неопределенный срок. (Исправлено Антуаном Питру; bpo-3002.)

  • Модуль signal больше не переустанавливает обработчик сигнала, если это действительно необходимо, что исправляет ошибку, из-за которой было невозможно надежно перехватить сигнал EINTR. (Исправлено Шарлем-Франсуа Натали; bpo-8354.)

  • Новые функции: в модуле site три новые функции возвращают различные пути для сайтов и пользователей. getsitepackages() возвращает список, содержащий все глобальные каталоги site-packages, getusersitepackages() возвращает путь к пользовательскому каталогу site-packages, а getuserbase() возвращает значение переменной среды USER_BASE, указывающее путь к каталогу, который можно использовать для хранения данных. (Предоставлено Тареком Зиаде; bpo-6693.)

    Модуль site теперь сообщает об исключениях, возникающих при импорте модуля sitecustomize, и больше не будет перехватывать и принимать исключение KeyboardInterrupt. (Исправлено Виктором Стиннером; bpo-3137.)

  • Функция create_connection() получила параметр source_address, состоящий из двух кортежей (host, port), указывающий исходный адрес, который будет использоваться для соединения. (Предоставлено Элдоном Зиглером; bpo-3972.)

    Методы recv_into() и recvfrom_into() теперь будут записывать в объекты, поддерживающие API-интерфейс буфера, наиболее полезными являются объекты bytearray и memoryview. (Реализован Антуаном Питру; bpo-8104.)

  • Класс TCPServer модуля SocketServer теперь поддерживает таймауты сокетов и отключение алгоритма Nagle. Атрибут класса disable_nagle_algorithm по умолчанию имеет значение False; если переопределено значение истина, для новых соединений запроса будет установлена опция TCP_NODELAY, чтобы предотвратить буферизацию множества небольших посылок в один TCP-пакет. Атрибут класса timeout может содержать время ожидания в секундах, которое будет применяться к сокету запроса; если в течение этого времени запрос не будет получен, будет вызван handle_timeout(), а handle_request() вернется. (Предоставлено Кристьяном Валуром Йонссоном; bpo-6192 и bpo-6267.)

  • Обновленный модуль: модуль sqlite3 обновлен до версии 2.6.0 файла пакета pysqlite. Версия 2.6.0 включает ряд исправлений и добавляет возможность загружать расширения SQLite из общих библиотек. Вызвать метод enable_load_extension(True), чтобы включить расширения, а затем вызвать load_extension(), чтобы загрузить определенную общую библиотеку. (Обновлено Герхардом Херингом)

  • Объекты SSLSocket модуля ssl теперь поддерживают API- интерфейс буфера, в котором устранен сбой тестового набора (исправлено Antoine Pitrou; bpo-7133) и автоматически установлен SSL_MODE_AUTO_RETRY OpenSSL, что предотвратит возвращение кода ошибки из операций recv(), запускающих повторное согласование SSL (исправлено Антуан Питру; bpo-8222).

    Функция-конструктор ssl.wrap_socket() теперь принимает аргумент ciphers, представляющий собой строку со списком разрешенных алгоритмов шифрования; формат строки описан в документации по OpenSSL. (Добавлено Антуаном Питру; bpo-8322.)

    Другое изменение заставляет расширение загружать все шифры и алгоритмы дайджеста OpenSSL, чтобы они были доступны. Не удалось проверить некоторые SSL-сертификаты, сообщая об ошибке «неизвестный алгоритм». (Сообщено Бедой Косата, исправлено Антуаном Питру; bpo-8484.)

    Используемая версия OpenSSL теперь доступна в виде атрибутов модуля ssl.OPENSSL_VERSION (строка), ssl.OPENSSL_VERSION_INFO (кортеж из 5) и ssl.OPENSSL_VERSION_NUMBER (целое число). (Добавлено Антуаном Питру; bpo-8321.)

  • Модуль struct больше не будет молча игнорировать ошибки переполнения, когда значение слишком велико для определенного кода целочисленного формата (одного из bBhHiIlLqQ); теперь он всегда вызывает исключение struct.error. (Изменено Марком Дикинсоном; bpo-1523.) Функция pack() также попытается использовать __index__() для преобразования и упаковки нецелых чисел, прежде чем пытаться использовать метод __int__() или сообщать об ошибке. (Изменено Марком Дикинсоном; bpo-8300.)

  • Новая функция: check_output() модуля subprocess запускает команду с указанным набором аргументов и возвращает результат команды в виде строки, если команда выполняется без ошибок, или вызывает исключение CalledProcessError в противном случае.

    >>> subprocess.check_output(['df', '-h', '.'])
    'Filesystem     Size   Used  Avail Capacity  Mounted on\n
    /dev/disk0s2    52G    49G   3.0G    94%    /\n'
    
    >>> subprocess.check_output(['df', '-h', '/bogus'])
      ...
    subprocess.CalledProcessError: Command '['df', '-h', '/bogus']' returned non-zero exit status 1
    

    (Предоставлено Грегори П. Смитом.)

    Модуль subprocess теперь будет повторять свои внутренние системные вызовы при получении сигнала EINTR. (Сообщено несколькими людьми; последний патч от Грегори П. Смита в bpo-1068268.)

  • Новая функция: is_declared_global() в модуле symtable возвращает истина для переменных, явно объявленных глобальными, и ложь для тех, которые неявно являются глобальными. (Предоставлено Джереми Хилтоном)

  • Модуль syslog теперь будет использовать значение sys.argv[0] в качестве идентификатора вместо предыдущего значения по умолчанию 'python'. (Изменено Шоном Рейфшнайдером; bpo-8451.)

  • Значение sys.version_info теперь является именованным кортежем с атрибутами major, minor, micro, releaselevel и serial. (Предоставлено Россом Лайтом; bpo-4285.)

    sys.getwindowsversion() также возвращает именованный кортеж с атрибутами major, minor, build, platform, service_pack, service_pack_major, service_pack_minor, suite_mask и product_type. (Предоставлено Брайаном Кертином; bpo-7766.)

  • Обработка ошибок по умолчанию модуля tarfile изменена, чтобы больше не подавлять фатальные ошибки. Раньше уровень ошибок по умолчанию был равен 0, что означало, что ошибки приводили только к записи сообщения в журнал отладки, но поскольку журнал отладки по умолчанию не активирован, данные ошибки остаются незамеченными. Уровень ошибки по умолчанию теперь равен 1, что вызывает исключение в случае ошибки. (Изменено Ларсом Густебелем; bpo-7357.)

    tarfile теперь поддерживает фильтрацию объектов TarInfo, добавляемых в tar-файл. Когда вы вызываете add(), вы можете указать необязательный аргумент filter, который является вызываемым. Вызываемый объект filter будет передавать TarInfo для каждого добавляемого файла и может изменять и возвращать его. Если вызываемый объект возвращает None, файл будет исключен из результирующего архива. Это более мощный аргумент, чем существующий аргумент exclude, который поэтому устарел. (Добавлено Lars Gustäbel; bpo-6856.) Класс TarFile также теперь поддерживает протокол управления контекстом. (Добавлено Ларсом Густебелем; bpo-7232.)

  • Метод wait() класса threading.Event теперь возвращает внутренний флаг при выходе. Это означает, что метод обычно возвращает истина, потому что wait() должен блокироваться до тех пор, пока внутренний флаг не станет истинным. Возвращаемое значение будет ложным только в том случае, если был предоставлен тайм-аут и время ожидания операции истекло. (Предоставлено Тимом Лешером; bpo-1674032.)

  • База данных Юникод, предоставляемая модулем unicodedata, теперь используется для внутреннего использования, чтобы определить, какие символы являются цифрами, пробелами или символами разрыва строки. База данных также включает информацию из файла данных Unihan.txt (исправление Андерса Хригстрема и Амори Форжо д«Арк; bpo-1571184) и обновлена до версии 5.2.0 (обновлена Флораном Шиклуной; bpo-8024).

  • urlsplit() модуля urlparse теперь обрабатывает неизвестные схемы URL-адресов в соответствии с RFC 3986: если URL-адрес имеет форму "<something>://...", текст перед :// обрабатывается как схема, даже если это выдуманная схема, которую модуль не поддерживает. знать о. Это изменение может нарушить работу кода, работавшего в обход старого поведения. Например, Python 2.6.4 или 2.5 вернёт следующее:

    >>> import urlparse
    >>> urlparse.urlsplit('invented://host/filename?query')
    ('invented', '', '//host/filename?query', '', '')
    

    Python 2.7 (и Python 2.6.5) вернётся:

    >>> import urlparse
    >>> urlparse.urlsplit('invented://host/filename?query')
    ('invented', 'host', '/filename?query', '', '')
    

    (Python 2.7 на самом деле выдает немного другой результат, поскольку возвращает именованный кортеж вместо стандартного кортежа.)

    Модуль urlparse также поддерживает литеральные адреса IPv6, определённые в RFC 2732 (предоставлено Senthil Kumaran; bpo-2987).

    >>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo')
    ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]',
                path='/foo', params='', query='', fragment='')
    
  • Новый класс: класс WeakSet в модуле weakref — это множество, который содержит только слабые ссылки на свои элементы; элементы будут удалены, если на них не будет ссылок. (Первоначально реализовано в Python 3.x Рэймондом Хеттингером и перенесено в версию 2.7 Майклом Фурдом)

  • Библиотека ElementTree, xml.etree, больше не пропускает амперсанды и угловые скобки при выводе инструкции обработки XML (выглядит как <?xml- stylesheet href="#style1"?>) или комментария (выглядит как <!-- comment -->). (Исправление Нила Мюллера; bpo-2746.)

  • Клиент и сервер XML-RPC, предоставляемые модулями xmlrpclib и SimpleXMLRPCServer, имеют улучшенную производительность за счет поддержки активности HTTP/1.1 и дополнительного использования кодирования gzip для сжатия передаваемого XML. Сжатие gzip управляется атрибутом encode_threshold SimpleXMLRPCRequestHandler, который содержит размер в байтах; ответы большего размера будут сжаты. (Предоставлено Кристьяном Валуром Йонссоном; bpo-6267.)

  • ZipFile модуля zipfile теперь поддерживает протокол управления контекстом, поэтому вы можете написать with zipfile.ZipFile(...) as f:. (Предоставлено Брайаном Кертином; bpo-5511.)

    zipfile теперь также поддерживает архивирование пустых каталогов и правильно извлекает их. (Исправлено Kuba Wieczorek; bpo-4710.) Чтение файлов из архива стало быстрее, а чередование read() и readline() теперь работает правильно. (Предоставлено Ниром Эйдесом; bpo-7610.)

    Функция is_zipfile() теперь принимает файловый объект в дополнение к именам путей, принятым в более ранних версиях. (Предоставлено Габриэлем Дженеллиной; bpo-4756.)

    Метод writestr() теперь имеет необязательный параметр compress_type, который позволяет переопределить метод сжатия по умолчанию, указанный в конструкторе ZipFile. (Предоставлено Рональдом Уссореном; bpo-6003.)

Новый модуль: importlib

Python 3.1 включает пакет importlib, повторную реализацию логики, лежащей в основе инструкции Python import. importlib полезен для разработчиков интерпретаторов Python и для пользователей, пишущим новые средства импорта, которые могут участвовать в процессе импорта. Python 2.7 не содержит полного пакета importlib, а вместо этого имеет небольшое подмножество, содержащее единственную функцию, import_module().

import_module(name, package=None) импортирует модуль. name — это строка, содержащая имя модуля или пакета. Можно выполнить относительный импорт, предоставив строку, начинающуюся с символа ., например ..utils.errors. Для относительного импорта необходимо указать аргумент package, являющийся именем пакета, используемый в качестве привязки для относительного импорта. import_module() вставляет импортированный модуль в sys.modules и возвращает объект модуля.

Вот несколько примеров:

>>> from importlib import import_module
>>> anydbm = import_module('anydbm')  # Стандартный абсолютный импорт
>>> anydbm
<module 'anydbm' from '/p/python/Lib/anydbm.py'>
>>> # Relative import
>>> file_util = import_module('..file_util', 'distutils.command')
>>> file_util
<module 'distutils.file_util' from '/python/Lib/distutils/file_util.pyc'>

importlib был реализован Бреттом Кэнноном и представлен в Python 3.1.

Новый модуль: sysconfig

Модуль sysconfig был удален из пакета Distutils, став новым самостоятельным модулем верхнего уровня. sysconfig предоставляет функции для получения информации о процессе сборки Python: параметры компилятора, пути установки, имя платформы и то, запущен ли Python из исходного каталога.

Некоторые из функций в модуле:

  • get_config_var() возвращает переменные из Makefile Python и файла pyconfig.h.
  • get_config_vars() возвращает словарь, содержащий все переменные конфигурации.
  • get_path() возвращает сконфигурированный путь для модуля определенного типа: стандартная библиотека, модули для сайтов, модули для платформ и т. д.
  • is_python_build() возвращает значение истина, если вы запускаете двоичный файл из исходного дерева Python, и значение ложь в противном случае.

Обратитесь к документации sysconfig для получения более подробной информации и полного списка функций.

Пакет Distutils и sysconfig теперь поддерживаются Тареком Зиаде, который также запустил пакет Distutils2 (репозиторий исходного кода на distutils2) для разработки версии Distutils следующего поколения.

ttk: Тематические виджеты для Tk

Tcl/Tk 8.5 включает в себя множество тематических виджетов, которые повторно реализуют базовые виджеты Tk, но имеют более настраиваемый внешний вид и поэтому могут больше напоминать виджеты родной платформы. Данное множество виджетов изначально назывался Tile, но был переименован в Ttk (от «тематического Tk») после добавления в Tcl/Tck версии 8.5.

Чтобы узнать больше, прочитайте документацию модуля ttk. Вы также можете прочитать справочную страницу Tcl/Tk с описанием движка темы Ttk, доступную по адресу. Некоторые скриншоты используемого кода Python/Ttk находятся по адресу.

Модуль ttk был написан Гильерме Поло и добавлен в bpo-2983. Альтернативная версия под названием Tile.py, написанная Мартином Франклином и поддерживаемая Кевином Уолцером, была предложена для включения в bpo-2618, но авторы утверждали, что работа Гильерме Поло была более полной.

Обновлённый модуль unittest

Модуль unittest был значительно улучшен; было добавлено много новых функций. Большинство данных функций были реализованы Майклом Фурдом, если не указано иное. Расширенную версию модуля можно загрузить отдельно для использования с Python версий 2.4–2.6, упакованную в виде пакета unittest2, с unittest2.

При использовании из командной строки модуль может автоматически обнаруживать тесты. Он не такой навороченный, как py.test или nose, но предоставляет простой способ запуска тестов, хранящихся в множестве каталогов пакетов. Например, следующая команда будет искать в подкаталоге test/ любые импортируемые тестовые файлы с именем test*.py:

python -m unittest discover -s test

Дополнительные сведения см. в документации по модулю unittest. (Разработано в bpo-6001.)

Функция main() поддерживает некоторые другие новые параметры:

  • -b или --buffer будут буферизовать стандартный вывод и стандартные потоки ошибок во время каждого теста. Если тест пройден, любой результирующий вывод будет отброшен; в случае сбоя будет отображаться буферизованный вывод.

  • -c или --catch приведут к тому, что прерывание control-C будет обрабатываться более изящно. Вместо немедленного прерывания процесса тестирования текущий тест будет завершён, а затем будут сообщены частичные результаты до прерывания. Если вы нетерпеливы, повторное нажатие Control-C вызовет немедленное прерывание.

    Данный обработчик control-C пытается избежать проблем, когда тестируемый код или выполняемые тесты определяют собственный обработчик сигнала, замечая, что обработчик сигнала уже установлен, и вызывая его. Если это не сработает для вас, есть декоратор removeHandler(), используемый для пометки тестов, для которых должна быть отключена обработка control-C.

  • -f или --failfast немедленно останавливают выполнение теста в случае сбоя теста вместо продолжения выполнения дальнейших тестов. (Предложено Клиффом Дайером и реализовано Майклом Фурдом; bpo-8074.)

Сообщения о ходе выполнения теперь показывают «x» для ожидаемых сбоев и «u» для неожиданных успехов при запуске в подробном режиме. (Предоставлено Бенджамином Петерсоном.)

Тестовые случаи могут вызывать исключение SkipTest для пропуска теста (bpo-1034053).

Сообщения об ошибках assertEqual(), assertTrue() и assertFalse() теперь содержат больше информации. Если вы устанавливает для атрибута longMessage ваших классов TestCase значение истина, при сбоях будет напечатано как стандартное сообщение об ошибке, так и любое дополнительное сообщение, которое вы предоставите. (Добавлено Майклом Фурдом; bpo-5663.)

Метод assertRaises() теперь возвращает обработчик контекста при вызове без предоставления вызываемого объекта для запуска. Например, вы можете написать это:

with self.assertRaises(KeyError):
    {}['foo']

(Реализован Антуаном Питру; bpo-4444.)

Теперь поддерживаются приспособления для установки и демонтажа на уровне модуля и класса. Модули могут содержать функции setUpModule() и tearDownModule(). Классы могут иметь методы setUpClass() и tearDownClass(), которые должны быть определены как методы класса (с использованием @classmethod или эквивалентного). Данные функции и методы вызываются, когда средство выполнения тестов переключается на тестовый пример в другом модуле или классе.

Добавлены методы addCleanup() и doCleanups(). addCleanup() позволяет добавлять функции очистки, которые будут вызываться безоговорочно (после setUp() в случае сбоя setUp(), в противном случае после tearDown()). Это позволяет значительно упростить выделение и освобождение ресурсов во время тестов (bpo-5679).

Добавлен ряд новых методов, обеспечивающих более специализированные тесты. Многие из данных методов были написаны инженерами Google для использования в своих тестовых наборах; Грегори П. Смит, Майкл Фурд и GvR работали над их объединением в версию unittest для Python.

  • assertIsNone() и assertIsNotNone() берут одно выражение и проверяют, соответствует ли результат None или нет.
  • assertIs() и assertIsNot() принимают два значения и проверяют, относятся ли данные два значения к одному и тому же объекту или нет. (Добавлено Майклом Фурдом; bpo-2578.)
  • assertIsInstance() и assertNotIsInstance() проверяют, является ли результирующий объект экземпляром определенного класса или одного из кортежа классов. (Добавлено Георгом Брандлом; bpo-7031.)
  • assertGreater(), assertGreaterEqual(), assertLess() и assertLessEqual() сравнивают два количества.
  • assertMultiLineEqual() сравнивает две строки и, если они не равны, отображает полезное сравнение, которое выделяет различия в двух строках. Это сравнение теперь используется по умолчанию при сравнении строк Юникод с assertEqual().
  • assertRegexpMatches() и assertNotRegexpMatches() проверяют, является ли первый аргумент строкой, соответствующей или не соответствующей регулярному выражению, указанному в качестве второго аргумента (bpo-8038).
  • assertRaisesRegexp() проверяет, возникло ли исключение, а затем также проверяет, соответствует ли строковое представление исключения предоставленному регулярному выражению.
  • assertIn() и assertNotIn() проверяют, входит ли first в second.
  • assertItemsEqual() проверяет, содержат ли две предоставленные последовательности одни и те же элементы.
  • assertSetEqual() сравнивает, равны ли два множества, и сообщает о различиях между множествами только в случае ошибки.
  • Точно так же assertListEqual() и assertTupleEqual() сравнивают указанные типы и объясняют любые различия, не обязательно выводя их полные значения; данные методы теперь используются по умолчанию при сравнении списков и кортежей с помощью assertEqual(). В более общем смысле assertSequenceEqual() сравнивает две последовательности и может дополнительно проверять, относятся ли обе последовательности к определённому типу.
  • assertDictEqual() сравнивает два словаря и сообщает о различиях; теперь он используется по умолчанию при сравнении двух словарей с помощью assertEqual(). assertDictContainsSubset() проверяет, все ли пары ключ/значение в first найдены в second.
  • assertAlmostEqual() и assertNotAlmostEqual() проверяют, приблизительно ли равны first и second. Данный метод может либо округлить их разницу до необязательно указанного числа places (по умолчанию — 7) и сравнить его с нулем, либо потребовать, чтобы разница была меньше предоставленного значения delta.
  • loadTestsFromName() правильно учитывает атрибут suiteClass TestLoader. (Исправлено Марком Родди; bpo-6866.)
  • Новый хук позволяет расширить метод assertEqual() для обработки новых типов данных. Метод addTypeEqualityFunc() принимает объект типа и функцию. Функция будет использоваться, когда оба сравниваемых объекта относятся к указанному типу. Данная функция должна сравнивать два объекта и вызывать исключение, если они не совпадают; полезно, чтобы функция предоставляла дополнительную информацию о том, почему два объекта не совпадают, как это делают новые методы сравнения последовательностей.

unittest.main() теперь принимает необязательный аргумент exit. Если ложь, main() не вызывает sys.exit(), позволяя использовать main() из интерактивного интерпретатора. (Предоставлено Дж. Пабло Фернандесом; bpo-3379.)

TestResult содержит новые методы startTestRun() и stopTestRun(), которые вызываются непосредственно перед и после выполнения теста. (Предоставлено Робертом Коллинзом; bpo-5728.)

Со всеми изменениями unittest.py становился неприлично большим, поэтому модуль превратили в пакет, а код разделили на несколько файлов (автор Benjamin Peterson). Это не влияет на то, как модуль импортируется или используется.

См.также

unittest2
Определяет новые функции, как их использовать и обоснование различных дизайнерских решений. (Майкл Форд.)

Обновленный модуль ElementTree 1.3

Версия библиотеки ElementTree, входящая в состав Python, была обновлена до версии 1.3. Некоторые из новых функций:

  • Различные функции синтаксического анализа теперь принимают ключевой аргумент parser, дающий экземпляр XMLParser, который будет использоваться. Это позволяет переопределить внутреннюю кодировку файла:

    p = ET.XMLParser(encoding='utf-8')
    t = ET.XML("""<root/>""", parser=p)
    

    Ошибки при парсинге XML теперь вызывают исключение ParseError, экземпляры которого имеют атрибут position, содержащий кортеж (line, column), указывающий местонахождение проблемы.

  • Код ElementTree для преобразования деревьев в строку был значительно переработан, во многих случаях он стал примерно в два раза быстрее. Методы ElementTree.write() и Element.write() теперь имеют параметр method, который может быть «xml» (по умолчанию), «html» или «текст». В режиме HTML пустые элементы будут выводиться как <empty></empty> вместо <empty/>, а в текстовом режиме элементы будут пропущены и будут выведены только фрагменты текста. Если вы устанавливает для атрибута tag элемента значение None, но оставите его дочерние элементы на месте, данный элемент будет пропущен при записи дерева, поэтому вам не нужно выполнять более обширную перестановку для удаления одного элемента.

    Обработка пространств имён также была улучшена. Все объявления xmlns:<whatever> теперь выводятся в корневом элементе, а не разбросаны по результирующему XML. Вы можете установить пространство имён по умолчанию для дерева, установив атрибут default_namespace, и можете зарегистрировать новые префиксы с помощью register_namespace(). В режиме XML вы можете использовать параметр истина/ложь xml_declaration, чтобы подавить объявление XML.

  • Новый метод Element: extend() добавляет элементы из последовательности к дочерним элементам элемента. Сами элементы ведут себя как последовательности, поэтому легко перемещать дочерние элементы от одного элемента к другому:

    from xml.etree import ElementTree as ET
    
    t = ET.XML("""<list>
      <item>1</item> <item>2</item>  <item>3</item>
    </list>""")
    new = ET.XML('<root/>')
    new.extend(t)
    
    # Выведет <root><item>1</item>...</root>
    print ET.tostring(new)
    
  • Новый метод Element: iter() возвращает дочерние элементы элемента в качестве генератора. Также можно написать for child in elem: для перебора дочерних элементов элемента. Существующий метод getiterator() теперь устарел, как и getchildren(), который создаёт и возвращает список дочерних элементов.

  • Новый метод Element: itertext() возвращает все фрагменты текста, являющиеся потомками элемента. Например:

    t = ET.XML("""<list>
      <item>1</item> <item>2</item>  <item>3</item>
    </list>""")
    
    # Выведет ['\n  ', '1', ' ', '2', '  ', '3', '\n']
    print list(t.itertext())
    
  • Устарело: использование элемента в качестве логического значения (например, if elem:) вернёт истину, если у элемента есть дочерние элементы, или ложь, если дочерних элементов нет. Такое поведение сбивает с толку — None ложно, но так ли это и бездетный элемент? Так что теперь он вызовет FutureWarning. В вашем коде вы должны быть явными: напишите len(elem) != 0, если вас интересует количество дочерних элементов, или elem is not None.

Фредрик Лунд разрабатывает ElementTree и выпустил версию 1.3; вы можете прочитать его статью с описанием версии 1.3 по адресу. (Флоран Шиклуна обновил версию, включенную в Python, после обсуждений на python-dev и в bpo-6472.)

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

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

  • Последний релиз отладчика GNU, GDB 7, может быть скриптом с использованием Python. Когда вы начинаете отладку исполняемой программы P, GDB ищет файл с именем P-gdb.py и автоматически читает его. Дэйв Малкольм предоставил python-gdb.py, который добавляет ряд команд, полезных при отладке самого Python. Например, py-up и py-down идут вверх или вниз по одному кадру стека Python, что обычно соответствует нескольким кадрам стека C. py-print выводит значение переменной Python, а py-bt выводит трассировку стека Python. (Добавлено в результате bpo-8032.)

  • Если вы используете файл .gdbinit, поставляемый с Python, макрос «pyo» в версии 2.7 теперь работает правильно, когда отлаживаемый поток не содержит GIL; макрос теперь получает его перед печатью. (Предоставлено Виктором Стиннером; bpo-3632.)

  • Py_AddPendingCall() теперь является потокобезопасным, позволяя любому рабочему потоку отправлять уведомления в основной поток Python. Это особенно полезно для асинхронных операций ввода-вывода. (Предоставлено Кристьяном Валуром Йонссоном; bpo-4293.)

  • Новая функция: PyCode_NewEmpty() создаёт пустой объект кода; требуются только имя файла, имя функции и номер первой строки. Это полезно для модулей расширения, которые пытаются создать более полезный стек трассировки. Ранее такие расширения требовали вызова PyCode_New(), у которого было гораздо больше аргументов. (Добавлено Джеффри Яскиным.)

  • Новая функция: PyErr_NewExceptionWithDoc() создаёт новый класс исключений, как это делает существующий PyErr_NewException(), но принимает дополнительный аргумент char *, содержащий строку документации для нового класса исключений. (Добавлено «lekma» в систему отслеживания ошибок Python; bpo-7033.)

  • Новая функция: PyFrame_GetLineNumber() принимает объект фрейма и возвращает номер строки, которую фрейм выполняет в данный момент. Ранее код должен был получить индекс выполняемой в данный момент инструкции байт-кода, а затем найти номер строки, соответствующий этому адресу. (Добавлено Джеффри Яскиным.)

  • Новые функции: PyLong_AsLongAndOverflow() и PyLong_AsLongLongAndOverflow() аппроксимируют длинное целое число Python как C long или long long. Если число слишком велико для выходного типа, устанавливается флаг overflow, который возвращается вызывающей стороне. (Предоставлено Кейсом Ван Хорсеном; bpo-7528 и bpo-7767.)

  • Новая функция: в результате перезаписи преобразования строки в число с плавающей запятой была добавлена новая функция PyOS_string_to_double(). Старые функции PyOS_ascii_strtod() и PyOS_ascii_atof() теперь устарели.

  • Новая функция: PySys_SetArgvEx() задаёт значение sys.argv и может дополнительно обновить sys.path, чтобы включить каталог, содержащий сценарий, названный sys.argv[0], в зависимости от значения параметра updatepath.

    Данная функция была добавлена, чтобы закрыть дыру в безопасности для приложений, в которые встроен Python. Старая функция, PySys_SetArgv(), всегда обновляла sys.path, а иногда добавляла текущий каталог. Это означало, что если вы запустили приложение, встраивающее Python, в каталог, контролируемый кем-то другим, злоумышленники могли поместить троянский модуль в каталог (скажем, файл с именем os.py), который ваше приложение затем импортировало и запускало.

    Если вы поддерживаете в C/C++ приложении встроенный Python, проверьте, вызываете ли вы PySys_SetArgv(), и внимательно подумайте, должно ли приложение использовать PySys_SetArgvEx() с updatepath, для которого установлено ложное значение.

    О проблеме безопасности сообщается в CVE-2008-5983; обсуждалось в bpo-5753 и исправлено Антуан Питру.

  • Новые макросы: заголовочные файлы Python теперь определяют следующие макросы: Py_ISALNUM, Py_ISALPHA, Py_ISDIGIT, Py_ISLOWER, Py_ISSPACE, Py_ISUPPER, Py_ISXDIGIT, Py_TOLOWER и Py_TOUPPER. Все данные функции аналогичны стандартным макросам C для классификации символов, но игнорируют текущую настройку локали, поскольку в некоторых местах Python должен анализировать символы независимым от локали способом. (Добавлено Эриком Смитом; bpo-5793.)

  • Удалена функция: PyEval_CallObject теперь доступен только в виде макроса. Версия функции сохранялась, чтобы сохранить совместимость привязки ABI, но это было в 1997 году; это, безусловно, может быть удалено сейчас. (Удалено Антуаном Питру; bpo-8276.)

  • Новые коды форматов: функции PyFormat_FromString(), PyFormat_FromStringV() и PyErr_Format() теперь принимают коды форматов %lld и %llu для отображения типов C long long. (Предоставлено Марком Дикинсоном; bpo-7228.)

  • Изменено сложное взаимодействие между потоками и разветвлением процессов. Раньше дочерний процесс, созданный с помощью os.fork(), мог завершиться ошибкой, поскольку дочерний процесс создавался только с одним запущенным потоком, потоком, выполняющим os.fork(). Если бы другие потоки удерживали блокировку, например блокировку импорта Python, при выполнении разветвления блокировка все равно была бы помечена как «удерживаемая» в новом процессе. Но в дочернем процессе ничто никогда не освободит блокировку, поскольку другие потоки не будут реплицированы, и дочерний процесс больше не сможет выполнять импорт.

    Python 2.7 получает блокировку импорта перед выполнением os.fork(), а также очищает все блокировки, созданные с помощью модуля threading. Модули расширения C, содержащие внутренние блокировки или сами вызывающие fork(), не выиграют от этой очистки.

    (Исправлено Томасом Воутерсом; bpo-1590864.)

  • Функция Py_Finalize() теперь вызывает внутреннюю функцию threading._shutdown(); это предотвращает возникновение некоторых исключений при завершении работы интерпретатора. (Исправление Адама Олсена; bpo-1722344.)

  • При использовании структуры PyMemberDef для определения атрибутов типа Python больше не позволит вам попытаться удалить или установить атрибут T_STRING_INPLACE.

  • Глобальные символы, определённые модулем ctypes, теперь имеют префикс Py или _ctypes. (Реализовано Томасом Хеллером; bpo-3102.)

  • Новый параметр настройки: переключатель --with-system-expat позволяет создать модуль pyexpat для использования системной библиотеки Expat. (Предоставил Арфревер Фрехтес Тайферсар Арахезис; bpo-7609.)

  • Новая опция конфигурации: опция --with-valgrind теперь отключает распределитель pymalloc, который детектору ошибок памяти Valgrind трудно проанализировать правильно. Поэтому Valgrind будет лучше обнаруживать утечки и переполнение памяти. (Предоставлено Джеймсом Хенстриджем; bpo-2422.)

  • Новая опция настройки: теперь вы можете указать пустую строку для --with-dbmliborder=, чтобы отключить все различные модули DBM. (Добавлено Арфревер Фрехтес Тайферсар Арахесис; bpo-6491.)

  • Сценарий configure теперь проверяет наличие ошибок округления с плавающей запятой на некоторых 32-разрядных чипах Intel и определяет определение препроцессора X87_DOUBLE_ROUNDING. В настоящее время ни один код не использует это определение, но оно доступно, если кто-то захочет его использовать. (Добавлено Марком Дикинсоном; bpo-2937.)

    configure теперь также устанавливает переменную Makefile LDCXXSHARED для поддержки компоновки C++. (Предоставил Арфревер Фрехтес Тайферсар Арахезис; bpo-1222585.)

  • Теперь процесс сборки создаёт необходимые файлы для поддержки pkg-config. (Предоставлено Клинтоном Роем; bpo-3585.)

  • Процесс сборки теперь поддерживает Subversion 1.7. (Предоставил Арфревер Фрехтес Тайферсар Арахезис; bpo-6094.)

Капсулы

Python 3.1 добавляет новый тип данных C, PyCapsule, для предоставления C API для модуля расширения. Капсула, по сути, является держателем указателя C void * и доступна как атрибут модуля; например, API модуля socket отображается как socket.CAPI, а unicodedata — как ucnhash_CAPI. Другие расширения могут импортировать модуль, получить доступ к его словарю, чтобы получить объект капсулы, а затем получить указатель void *, который обычно указывает на массив указателей на различные функции API модуля.

Для этого уже используется тип данных PyCObject, но он не обеспечивает безопасность типов. Злой код, написанный на чистом Python, может вызвать ошибку сегментации, взяв PyCObject из модуля A и каким-то образом заменив его на PyCObject в модуле B. Капсулы знают свое имя, и для получения указателя требуется указать имя:

void *vtable;

if (!PyCapsule_IsValid(capsule, "mymodule.CAPI") {
        PyErr_SetString(PyExc_ValueError, "argument type invalid");
        return NULL;
}

vtable = PyCapsule_GetPointer(capsule, "mymodule.CAPI");

Вы уверены, что vtable указывает на то, что вы ожидаете. Если бы была передана другая капсула, PyCapsule_IsValid() обнаружит несовпадающее имя и вернёт ложь. Обратитесь к Предоставление C API для модуля расширения для получения дополнительной информации об использовании данных объектов.

Python 2.7 теперь использует капсулы внутри для предоставления различных API- интерфейсов модулей расширения, но PyCObject_AsVoidPtr() был изменён для обработки капсул, сохраняя совместимость во время компиляции с интерфейсом CObject. Использование PyCObject_AsVoidPtr() будет означать PendingDeprecationWarning, который по умолчанию не используется.

Реализовано на Python 3.1 и портировано на версию 2.7 Ларри Хастингсом; обсуждалось в bpo-5630.

Изменения, относящиеся к порту: Windows

  • Модуль msvcrt теперь содержит некоторые константы из заголовочного файла crtassem.h: CRT_ASSEMBLY_VERSION, VC_ASSEMBLY_PUBLICKEYTOKEN и LIBRARIES_ASSEMBLY_NAME_PREFIX. (Предоставлено Дэвидом Курнапо; bpo-4365.)
  • Модуль _winreg для доступа к реестру теперь реализует функции CreateKeyEx() и DeleteKeyEx(), расширенные версии ранее поддерживаемых функций, которые принимают несколько дополнительных аргументов. DisableReflectionKey(), EnableReflectionKey() и QueryReflectionKey() также были протестированы и задокументированы. (Реализовано Брайаном Кертином: bpo-7347.)
  • Новый API _beginthreadex() используется для запуска потоков, и теперь используются собственные функции локального хранения потока. (Предоставлено Кристьяном Валуром Йонссоном; bpo-3582.)
  • Функция os.kill() теперь работает в Windows. Значением сигнала могут быть константы CTRL_C_EVENT, CTRL_BREAK_EVENT или любое целое число. Первые две константы будут отправлять события нажатия клавиш Control-C и Control-Break подпроцессам; любое другое значение будет использовать API TerminateProcess(). (Предоставлено Мики Тебека; bpo-1220212.)
  • Функция os.listdir() теперь корректно завершается ошибкой для пустого пути. (Исправлено Хирокадзу Ямамото; bpo-5913.)
  • Модуль mimelib теперь будет считывать базу данных MIME из реестра Windows при инициализации. (Патч Габриэля Дженеллины; bpo-4969.)

Изменения, относящиеся к порту: Mac OS X

  • Путь /Library/Python/2.7/site-packages теперь добавляется к sys.path, чтобы совместно использовать добавленные пакеты между установкой системы и установленной пользователем копией той же версии. (Изменено Рональдом Уссореном; bpo-4865.)

    Изменено в версии 2.7.13: Начиная с версии 2.7.13 это изменение было удалено. /Library/Python/2.7/site-packages, каталог site-packages, используемый поставляемой Apple системой Python 2.7, больше не добавляется к sys.path для установленных пользователем Python, таких как установщики python.org. Начиная с macOS 10.12, Apple изменила настройку системного каталога site-packages, что могло привести к сбою установки компонентов pip, таких как setuptools. Пакеты, установленные для системного Python, больше не будут использоваться совместно с Python, установленным пользователем. (bpo-28440)

Изменения, относящиеся к порту: FreeBSD

  • Константа SO_SETFIB FreeBSD 7.1, используемая с getsockopt()/setsockopt() для выбора альтернативной таблицы маршрутизации, теперь доступна в модуле socket. (Добавлено Кайлом Вандербиком; bpo-8235.)

Другие изменения и исправления

  • Два тестовых сценария, iobench и ccbench, были добавлены в каталог Tools. iobench измеряет скорость встроенных файловых объектов ввода-вывода, возвращаемых open(), при выполнении различных операций, а ccbench — это тест параллелизма, который пытается измерить вычислительную пропускную способность, задержку переключения потоков и пропускную способность обработки ввода-вывода при выполнении нескольких задач с использованием различных количество потоков.
  • Сценарий Tools/i18n/msgfmt.py теперь понимает формы множественного числа в файлах .po. (Исправлено Мартином фон Лёвисом; bpo-5464.)
  • При импорте модуля из файла .pyc или .pyo с существующим аналогом .py атрибуты co_filename результирующих объектов кода перезаписываются, когда исходное имя файла устаревает. Это может произойти, если файл был переименован, перемещен или доступ к нему осуществляется по другим путям. (Патч от Сига Зейльнахт и Жан-Поль Кальдероне; bpo-1180193.)
  • Сценарий regrtest.py теперь принимает переключатель -- randseed=, принимающий целое число, используемый в качестве случайного начального числа для параметра -r, выполняющего тесты в случайном порядке. Параметр -r также сообщает об использованном начальном значении (добавлено Коллином Винтером).
  • Другой переключатель regrtest.py-j, который принимает целое число, указывающее, сколько тестов выполняется параллельно. Это позволяет сократить общее время работы на многоядерных машинах. Опция совместима с несколькими другими опциями, включая переключатель -R, который, как известно, обеспечивает длительное время работы. (Добавлено Antoine Pitrou, bpo-6152.) Это также можно использовать с новой опцией -F, которая запускает выбранные тесты в цикле до тех пор, пока они не завершатся ошибкой. (Добавлено Антуаном Питру; bpo-7312.)
  • При выполнении в виде скрипта модуль py_compile.py теперь принимает '-' в качестве аргумента, который будет считывать стандартный ввод для списка имён файлов, подлежащих компиляции. (Предоставил Пётр Ожаровский; bpo-8233.)

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

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

  • Функция range() более последовательно обрабатывает свои аргументы; теперь он будет вызывать __int__() для аргументов, не являющихся числами с плавающей запятой, которые ему предоставлены. (Исправил Александр Белопольский; bpo-1533.)
  • Строковый метод format() изменил точность по умолчанию, используемую для чисел с плавающей запятой и комплексных чисел, с 6 знаков после запятой до 12, что соответствует точности, используемой str(). (Изменено Эриком Смитом; bpo-5920.)
  • Из-за оптимизации оператора with специальные методы __enter__() и __exit__() должны принадлежать типу объекта и не могут быть напрямую связаны с экземпляром объекта. Это влияет на классы нового стиля (производные от object) и типы расширений C. (bpo-6101.)
  • Из-за ошибки в Python 2.6 параметр exc_value для методов __exit__() часто был строковым представлением исключения, а не экземпляром. Это было исправлено в версии 2.7, поэтому exc_value будет экземпляром, как и ожидалось. (Исправлено Флораном Шиклуной; bpo-7853.)
  • Если с помощью __slots__ был установлен ограниченный множество атрибутов, удаление неустановленного атрибута не вызовет AttributeError, как можно было бы ожидать. (Исправлено Бенджамином Петерсоном; bpo-7604.)

В стандартной библиотеке:

  • Операции с экземплярами datetime, в результате которых год выходил за пределы поддерживаемого диапазона, не всегда вызывали OverflowError. Такие ошибки теперь проверяются более тщательно и вызывают исключение. (Сообщено Марком Леандером, исправление Ананда Б. Пиллаи и Александра Белопольского; bpo-7150.)

  • При использовании экземпляров Decimal со строковым методом format() выравнивание по умолчанию ранее было выравниванием по левому краю. Это было изменено на выравнивание по правому краю, что может изменить вывод ваших программ. (Изменено Марком Дикинсоном; bpo-6857.)

    Сравнения, включающие сигнальное значение NaN (или sNAN), теперь сигнализируют InvalidOperation вместо молчаливого возврата истинного или ложного значения в зависимости от оператора сравнения. Тихие значения NaN (или NaN) теперь можно хэшировать. (Исправлено Марком Дикинсоном; bpo-7279.)

  • Библиотека ElementTree, xml.etree, больше не пропускает амперсанды и угловые скобки при выводе инструкции по обработке XML (выглядит как <?xml- stylesheet href=«#style1»?>) или комментария (выглядит как <!– комментарий –>). (Исправление Нила Мюллера; bpo-2746.)

  • Метод readline() объектов StringIO теперь ничего не делает, когда запрашивается отрицательная длина, как это делают другие файловые объекты. (bpo-7348).

  • Модуль syslog теперь будет использовать значение sys.argv[0] в качестве идентификатора вместо предыдущего значения по умолчанию 'python'. (Изменено Шоном Рейфшнайдером; bpo-8451.)

  • Обработка ошибок по умолчанию модуля tarfile изменена, чтобы больше не подавлять фатальные ошибки. Раньше уровень ошибок по умолчанию был равен 0, что означало, что ошибки приводили только к записи сообщения в журнал отладки, но поскольку журнал отладки по умолчанию не активирован, данные ошибки остаются незамеченными. Уровень ошибки по умолчанию теперь равен 1, что вызывает исключение в случае ошибки. (Изменено Ларсом Густебелем; bpo-7357.)

  • urlsplit() модуля urlparse теперь обрабатывает неизвестные схемы URL-адресов в соответствии с RFC 3986: если URL-адрес имеет форму "<something>://...", текст перед :// обрабатывается как схема, даже если это выдуманная схема, которую модуль не поддерживает. знать о. Это изменение может нарушить работу кода, работавшего в обход старого поведения. Например, Python 2.6.4 или 2.5 вернёт следующее:

    >>> import urlparse
    >>> urlparse.urlsplit('invented://host/filename?query')
    ('invented', '', '//host/filename?query', '', '')
    

    Python 2.7 (и Python 2.6.5) вернётся:

    >>> import urlparse
    >>> urlparse.urlsplit('invented://host/filename?query')
    ('invented', 'host', '/filename?query', '', '')
    

    (Python 2.7 на самом деле выдает немного другой результат, поскольку возвращает именованный кортеж вместо стандартного кортежа.)

Для C расширений:

  • Расширения C, которые используют коды целочисленного формата с семейством функций PyArg_Parse*, теперь вызывают исключение TypeError вместо запуска DeprecationWarning (bpo-5080).
  • Используйте новую функцию PyOS_string_to_double() вместо старых функций PyOS_ascii_strtod() и PyOS_ascii_atof(), которые сейчас устарели.

Для приложений, в которые встроен Python:

  • Была добавлена функция PySys_SetArgvEx(), позволяющая приложениям закрыть дыру в безопасности при использовании существующей функции PySys_SetArgv(). Проверить, вызываете ли вы PySys_SetArgv(), и внимательно подумайте, должно ли приложение использовать PySys_SetArgvEx() с updatepath, для которого задано значение ложь.

Новые функции, добавленные в отладочные версии Python 2.7

Новые функции могут быть добавлены в отладочные версии Python 2.7, когда этого действительно требует ситуация. Любые такие дополнения должны пройти процесс предложения по улучшению Python и привести убедительные доводы в пользу того, почему они не могут быть адекватно решены либо путём добавления новой функции исключительно в Python 3, либо путём публикации её в индексе пакетов Python.

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

Две новые переменные среды для режима отладки

В режиме отладки статистика [xxx refs] по умолчанию не пишется, переменная окружения PYTHONSHOWREFCOUNT теперь также должна быть установлена. (Предоставлено Виктором Стиннером; bpo-31733.)

Когда Python скомпилирован с определенным COUNT_ALLOC, счетчики распределения больше не выгружаются по умолчанию: теперь также должна быть установлена переменная среды PYTHONSHOWALLOCCOUNT. Более того, счетчики аллокаций теперь выводятся в stderr, а не в stdout. (Предоставлено Виктором Стиннером; bpo-31692.)

Добавлено в версии 2.7.15.

PEP 434: исключение расширения IDLE для всех ветвей

PEP 434 определяет общее исключение для изменений, внесенных в среду разработки IDLE, поставляемую вместе с Python. Это исключение позволяет разработчикам IDLE обеспечить более единообразный пользовательский интерфейс во всех поддерживаемых версиях Python 2 и 3.

Для получения подробной информации о любых изменениях IDLE обратитесь к файлу NEWS для заданного релиза.

PEP 466: улучшения сетевой безопасности для Python 2.7

PEP 466 определяет ряд предложений по улучшению сетевой безопасности, которые были одобрены для включения в отладочные релизы Python 2.7, причем первое из данных изменений появилось в выпуске Python 2.7.7.

Функции, связанные с PEP 466, добавлены в Python 2.7.7:

  • hmac.compare_digest() был перенесен из Python 3, чтобы сделать операцию сравнения, устойчивую к атакам по времени, доступной для приложений Python 2. (Предоставлено Алексом Гейнором; bpo-21306.)
  • OpenSSL 1.0.1g был обновлен в официальных установщиках Windows, опубликованных на python.org. (Предоставлено Закари Уэр; bpo-21462.)

Функции, связанные с PEP 466, добавлены в Python 2.7.8:

  • hashlib.pbkdf2_hmac() был бэкпортирован из Python 3, чтобы сделать алгоритм хэширования, пригодный для безопасного хранения паролей, широко доступным для приложений Python 2. (Предоставлено Алексом Гейнором; bpo-21304.)
  • OpenSSL 1.0.1h был обновлен для официальных установщиков Windows, опубликованных на python.org. (Предоставлено Закари Уэр в bpo-21671 для CVE-2014-0224)

Функции, связанные с PEP 466, добавлены в Python 2.7.9:

  • Большая часть модуля ssl Python 3.4 была портирована обратно. Это означает, что ssl теперь поддерживает указание имени сервера, настройки TLS1.x, доступ к хранилищу сертификатов платформы, класс SSLContext и другие функции. (Предоставлено Алексом Гейнором и Дэвидом Ридом; bpo-21308.)

    Дополнительные сведения см. в примечаниях «Добавлена версия: 2.7.9» в документации модуля.

  • os.urandom() был изменён для кэширования дескриптора файла на /dev/urandom вместо повторного открытия /dev/urandom при каждом вызове. (Предоставлено Алексом Гейнором; bpo-21305.)

  • hashlib.algorithms_guaranteed и hashlib.algorithms_available были перенесены из Python 3, чтобы приложениям Python 2 было проще выбирать самый надежный доступный хеш-алгоритм. (Предоставлено Алексом Гейнором в bpo-21307)

PEP 477: Обратный перенос ensurepip (PEP 453) на Python 2.7

PEP 477 одобряет включение модуля surepip PEP 453 и улучшенной документации, которая была включена с его помощью, в отладочные релизы Python 2.7, впервые появившиеся в выпуске Python 2.7.9.

Начальная загрузка pip по умолчанию

Новый модуль ensurepip (определённый в PEP 453) предоставляет стандартный кроссплатформенный механизм для начальной загрузки установщика pip в установки Python. Версия pip, включенная в Python 2.7.9, — это pip 1.5.6, а будущие релизы обслуживания 2.7.x будут обновлять связанную версию до последней версии pip, доступной на момент создания кандидата на релиз.

По умолчанию команды pip, pipX и pipX.Y будут установлены на всех платформах (где X.Y означает версию установки Python) вместе с пакетом Python pip и его зависимостями.

Для CPython исходный код построен на системах POSIX команды make install и make altinstall не загружают pip по умолчанию. Этим поведением можно управлять с помощью параметров конфигурации и переопределять с помощью параметров Makefile.

В Windows и Mac OS X установщики CPython теперь по умолчанию устанавливают pip вместе с самим CPython (пользователи могут отказаться от его установки в процессе установки). Пользователям Windows необходимо согласиться на автоматические модификации PATH, чтобы pip был доступен из командной строки по умолчанию, в противном случае к нему по-прежнему можно получить доступ через средство запуска Python для Windows как py -m pip.

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

Изменения в документации

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

Однако, поскольку миграция в настоящее время все ещё не завершена, устаревшие версии данных руководств остаются доступными как Установка модулей Python (устаревшая версия) и Распространение Python модулей (устаревшая версия).

См.также

PEP 453 – Явная загрузка pip в установках Python
PEP, написанный Дональдом Стаффтом и Ником Когланом, реализованный компанией Дональд Стаффт, Ник Коглан, Мартин фон Лёвис и Нед Дейли.

PEP 476: включение проверки сертификата по умолчанию для http-клиентов stdlib

PEP 476 обновил httplib и использующие его модули urllib2 и xmlrpclib, для проверки, что сервер представляет подписанный центром сертификации в хранилище доверенных сертификатов платформы сертификат, и чье имя хоста соответствует имени хоста, запрашиваемому по умолчанию, что значительно вызывает безопасность для многих приложений. Это изменение было сделано в версии Python 2.7.9.

Для приложений, которым требуется старое предыдущее поведение, они могут передавать альтернативный контекст:

import urllib2
import ssl

# Это отключает все проверки
context = ssl._create_unverified_context()

# Это позволяет использовать определённый сертификат для хоста,
# который не обязательно должен находиться в хранилище доверенных сертификатов
context = ssl.create_default_context(cafile="/path/to/file.crt")

urllib2.urlopen("https://invalid-cert", context=context)

PEP 493: инструменты миграции проверки HTTPS для Python 2.7

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

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

Для приложений и служб, которые вообще нельзя изменить, для новой переменной среды PYTHONHTTPSVERIFY может быть задано значение 0, чтобы возвращает весь процесс Python обратно к разрешительному поведению по умолчанию в Python 2.7.8 и более ранних версиях.

В случаях, когда код установления соединения нельзя изменить, но можно изменить все приложение, можно использовать новую функцию ssl._https_verify_certificates() для настройки поведения по умолчанию во время выполнения.

Новая цель сборки make regen-all

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

Вместо этого была добавлена новая команда make regen-all для принудительной регенерации данных файлов при необходимости (например, после того, как начальная версия Python уже была собрана на основе предварительно созданных версий).

Также определены более избирательные цели регенерации — подробности см. в Makefile.pre.in.

(Предоставлено Виктором Стиннером в bpo-23404.)

Добавлено в версии 2.7.14.

Удаление цели сборки make touch

Цель сборки make touch, которая ранее использовалась для запроса неявной регенерации сгенерированных файлов путём обновления времени их модификации, была удалена.

Он был заменен новой целью make regen-all.

(Предоставлено Виктором Стиннером в bpo-23404.)

Изменено в версии 2.7.14.

Благодарности

Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь с различными черновиками этой статьи: Ник Коглан, Филип Дженви, Райан Ловетт, Р. Дэвид Мюррей, Хью Секер-Уокер.