Документация Python неофициальный перевод
Содержание страницы

Что нового в Python 2.7What’s New in Python 2.7

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

В этой статье описываются новые возможности Python 2.7. Финальный релиз 2.7 на данный момент запланирован на июль 2010 года; подробный план описан в PEP 373.

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

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

Эта статья не претендует на полное описание новых возможностей, а предоставляет удобный обзор. За полными подробностями следует обращаться к документации Python 2.7 по адресу http://docs.python.org. Если вы хотите понять обоснование проектирования и реализации, обратитесь к PEP для конкретной новой возможности или к задаче на http://bugs.python.org, в которой обсуждалось изменение. По возможности «Что нового в Python» ссылается на ошибку/патч для каждого изменения.

Будущее Python 2.xThe Future for Python 2.x

Python 2.7 планируется как последний крупный релиз в серии 2.x. Разработчики Python намерены сосредоточить свои будущие усилия на серии Python 3.x.

Это означает, что 2.7 останется надолго, обеспечивая работу продукционных систем, которые не были портированы на Python 3.x. Два следствия долгосрочной значимости 2.7:

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

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

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

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

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

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

Подобно тому, как 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: Adding an Ordered Dictionary to collections.
  • Новый спецификатор формата ",", описанный в PEP 378: Format Specifier for Thousands Separator.
  • Объект memoryview.
  • Небольшая часть модуля importlib, описанная ниже.
  • Результат repr() числа float 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: Добавление упорядоченного словаря в collectionsPEP 372: Adding an Ordered Dictionary to collections

Обычные словари Python перебирают пары ключ/значение в произвольном порядке. За эти годы ряд авторов написали альтернативные реализации, которые запоминают порядок, в котором ключи были изначально вставлены. Основываясь на опыте этих реализаций, 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 равен True, возвращается и удаляется самый последний добавленный ключ; если False – выбирается самый старый ключ:

>>> 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 – Добавление упорядоченного словаря в collections
PEP написан Армином Ронахером и Рэймондом Хеттингером; реализован Рэймондом Хеттингером.

PEP 378: Спецификатор формата для разделителя тысячPEP 378: Format Specifier for Thousands Separator

Чтобы сделать вывод программы более читаемым, может быть полезно добавлять разделители в большие числа, отображая их как 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 для разбора командной строкиPEP 389: The argparse Module for Parsing Command Lines

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

Это означает, что теперь Python поддерживает три разных модуля для разбора аргументов командной строки: getopt, optparse и argparse. Модуль getopt очень похож на функцию getopt() из библиотеки C, поэтому он остаётся полезным при написании прототипа на Python, который впоследствии будет переписан на C. optparse становится избыточным, но планов по его удалению нет, потому что многие скрипты всё ещё его используют, и нет автоматического способа их обновить. (Обсуждалась возможность привести 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

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

PEP 391: Конфигурация логирования на основе словарейPEP 391: Dictionary-Based Configuration For Logging

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

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

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

Следующий пример настраивает два логгера: корневой логгер и логгер с именем «network». Сообщения, отправленные корневому логгеру, будут отправляться в системный журнал через протокол syslog, а сообщения логгеру «network» будут записываться в файл 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': 1024*1024},
              '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, все реализованные Винаем Саджипом (Vinay Sajip):

  • Класс 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: Представления словарейPEP 3106: Dictionary Views

Методы словаря 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 Александром Вассалотти; issue 1967.

PEP 3137: Объект memoryviewPEP 3137: The memoryview Object

Объект 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 Антуаном Питру; issue 2396.

Прочие изменения языка Other Language Changes

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

  • Синтаксис литералов множеств перенесён из Python 3.x. Фигурные скобки используются для окружения содержимого результирующего изменяемого множества; литералы множеств отличаются от словарей отсутствием двоеточий и значений. {} по-прежнему представляет пустой словарь; используйте 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'])
    

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

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

    with A() as a, B() as b:
        ... suite of statements ...
    

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

    with A() as a:
        with B() as b:
            ... suite of statements ...
    

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

    (Предложено в http://codereview.appspot.com/53094; реализовано Георгом Брандлом.)

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

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

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

    Реализовано Эриком Смитом и Марком Дикинсоном с использованием библиотеки dtoa.c Дэвида Гея; issue 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
    

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

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

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

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

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

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

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

    Код формата ‘F’ теперь всегда форматирует вывод прописными буквами, поэтому теперь он будет выдавать ‘INF’ и ‘NAN’. (Предложено Эриком Смитом; issue 3382.)

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

    (Предложено Фредриком Юханссоном и Виктором Штиннером; issue 3439.)

  • Инструкция import больше не будет пытаться выполнить абсолютный импорт, если относительный импорт (например, from .os import sep) завершается неудачей. Это исправляет ошибку, но может сломать некоторые инструкции import, которые работали только случайно. (Исправлено Мидором Инге; issue 7902.)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    (Предложено Mark Dickinson; issue 4258.)

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

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

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

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

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

  • Методы split(), replace(), rindex(), rpartition() и rsplit() у строкоподобных типов (строки, строки Unicode и объекты bytearray) теперь используют быстрый алгоритм обратного поиска вместо посимвольного сканирования. Это иногда быстрее в 10 раз. (Добавлено Florent Xicluna; тикет 7462 и тикет 7622.)

  • Модули pickle и cPickle теперь автоматически интернируют строки, используемые для имён атрибутов, уменьшая потребление памяти объектами, полученными в результате распаковки (unpickling). (Автор: Jake McGuire; тикет 5084.)

  • Модуль cPickle теперь обрабатывает словари особым образом, почти вдвое сокращая время, необходимое для их упаковки (pickle). (Автор: Collin Winter; тикет 5670.)

Новые и улучшенные модулиNew and Improved Modules

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

  • Базовый класс отладки Bdb модуля bdb получил возможность пропускать модули. Теперь конструктор принимает итерируемый объект, содержащий шаблоны в стиле glob, например django.*; отладчик не будет заходить в стековые фреймы из модуля, соответствующего одному из этих шаблонов. (Автор: Maru Newby после предложения Senthil Kumaran; тикет 5142.)

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

  • Обновлённый модуль: модуль bsddb обновлён с версии 4.7.2devel9 до версии 4.8.4 пакета pybsddb. Новая версия отличается лучшей совместимостью с Python 3.x, различными исправлениями ошибок и добавляет несколько новых флагов и методов BerkeleyDB. (Обновлено Jesús Cea Avión; тикет 8156. Журнал изменений pybsddb можно прочитать по адресу http://hg.jcea.es/pybsddb/file/tip/ChangeLog.)

  • Класс BZ2File модуля bz2 теперь поддерживает протокол управления контекстом, поэтому можно писать with bz2.BZ2File(...) as f:. (Автор: Hagen Fürstenau; тикет 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
    

    Автор: Raymond Hettinger; тикет 1696199.

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

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

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

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

    (Добавлено Raymond Hettinger; тикет 1818.)

    Наконец, абстрактный базовый класс Mapping теперь возвращает NotImplemented, если отображение сравнивается с другим типом, не являющимся Mapping. (Исправлено Daniel Stutzbach; тикет 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'
    

    (Автор: Mats Kindahl; тикет 7005.)

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

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

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

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

  • Новый метод: класс timedelta модуля datetime получил метод total_seconds(), который возвращает количество секунд в промежутке времени. (Автор: Brian Quinlan; тикет 5788.)

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

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

    Конструктор Decimal теперь принимает числа с плавающей запятой (добавлено Raymond Hettinger; тикет 8257) и неевропейские символы Unicode, такие как арабо-индийские цифры (автор: Mark Dickinson; тикет 6595).

    Большинство методов класса Context теперь принимают целые числа наряду с экземплярами Decimal; единственные исключения – это методы canonical() и is_canonical(). (Патч от Juan José Conti; тикет 7633.)

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

    Сравнения, включающие сигнальное значение NaN (или sNAN), теперь вызывают InvalidOperation вместо молчаливого возврата true или false в зависимости от оператора сравнения. Тихие значения NaN (или NaN) теперь хешируемы. (Исправлено Mark Dickinson; тикет 7279.)

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

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

  • Флаг IGNORE_EXCEPTION_DETAIL модуля doctest теперь игнорирует имя модуля, содержащего проверяемое исключение. (Патч от Lennart Regebro; issue 7490.)

  • Класс Message модуля email теперь принимает полезную нагрузку в кодировке Unicode, автоматически преобразуя её в кодировку, заданную параметром output_charset. (Добавлено R. David Murray; issue 1368247.)

  • Класс Fraction теперь принимает в качестве аргументов конструктора один экземпляр float или Decimal, либо два рациональных числа. (Реализовано Mark Dickinson; рациональные числа добавлены в issue 5812, а float/decimal – в issue 8294.)

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

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

    Метод storbinary() для бинарной загрузки теперь может возобновлять передачу благодаря добавленному параметру rest (патч от Pablo Mouzo; issue 6845).

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

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

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

  • Класс GzipFile модуля gzip теперь поддерживает протокол контекстного менеджера, поэтому можно писать with gzip.GzipFile(...) as f: (предоставлено Hagen Fürstenau; issue 3860), а также теперь реализует абстрактный базовый класс io.BufferedIOBase, поэтому его можно обернуть в io.BufferedReader для более быстрой обработки (предоставлено Nir Aides; issue 7471). Также теперь можно переопределить время модификации, записанное в gzip-файле, передав конструктору необязательную временную метку. (Предоставлено Jacques Frechet; issue 4272.)

    Файлы в формате gzip могут дополняться завершающими нулевыми байтами; модуль gzip теперь будет корректно обрабатывать эти завершающие байты. (Исправлено Tadek Pietraszek и Brian Curtin; issue 2846.)

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

  • Класс HTTPResponse, используемый по умолчанию модулем httplib, теперь поддерживает буферизацию, что обеспечивает гораздо более быстрое чтение HTTP-ответов. (Предоставлено Kristján Valur Jónsson; issue 4879.)

    Классы HTTPConnection и HTTPSConnection теперь поддерживают параметр source_address – кортеж из двух элементов (host, port), задающий исходный адрес, который будет использоваться для соединения. (Предоставлено Eldon Ziegler; issue 3972.)

  • Модуль ihooks теперь поддерживает относительные импорты. Обратите внимание, что ihooks – это более старый модуль для настройки импортов, заменённый модулем imputil, добавленным в Python 2.0. (Поддержка относительных импортов добавлена Neil Schemenauer.)

  • Модуль imaplib теперь поддерживает IPv6-адреса. (Предоставлено Derek Morr; issue 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)
    

    Предоставлено George Sakkis; issue 3135.

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

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

    Класс io.FileIO теперь вызывает OSError при передаче недопустимого файлового дескриптора. (Реализовано Benjamin Peterson; issue 4991.) Метод truncate() теперь сохраняет позицию в файле; ранее он изменял позицию на конец нового файла. (Исправлено Pascal Chambon; issue 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. (Реализовано Raymond Hettinger; issue 5032.)

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

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

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

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

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

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

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

  • Модуль nntplib теперь поддерживает IPv6-адреса. (Предоставлено Derek Morr; issue 1664.)

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

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

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

  • У модуля pydoc теперь есть справка по различным символам, которые использует Python. Теперь можно, например, сделать help('<<') или help('@'). (Добавлено David Laban; issue 4739.)

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

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

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

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

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

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

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

  • Функция create_connection() получила параметр source_address – кортеж из двух элементов (host, port), задающий исходный адрес, который будет использоваться для подключения. (Добавлено Eldon Ziegler; issue 3972.)

    Методы recv_into() и recvfrom_into() теперь будут записывать данные в объекты, поддерживающие буферный API, наиболее полезно – в объекты bytearray и memoryview. (Реализовано Antoine Pitrou; issue 8104.)

  • Класс TCPServer модуля SocketServer теперь поддерживает таймауты сокетов и отключение алгоритма Нейгла. Атрибут класса disable_nagle_algorithm по умолчанию имеет значение False; если переопределить его в True, новые входящие соединения будут иметь установленный параметр TCP_NODELAY, чтобы предотвратить буферизацию множества мелких отправок в один TCP-пакет. Атрибут класса timeout может содержать таймаут в секундах, который будет применён к сокету запроса; если за это время не поступит ни одного запроса, будет вызван метод handle_timeout(), и метод handle_request() вернёт управление. (Добавлено Kristján Valur Jónsson; issue 6192 и issue 6267.)

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

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

    Функция-конструктор ssl.wrap_socket() теперь принимает аргумент ciphers – строку, перечисляющую разрешённые алгоритмы шифрования; формат строки описан в документации OpenSSL. (Добавлено Antoine Pitrou; issue 8322.)

    Ещё одно изменение заставляет расширение загружать все шифры и алгоритмы дайджеста OpenSSL, чтобы все они были доступны. Некоторые SSL-сертификаты не могли быть проверены, выдавая ошибку «неизвестный алгоритм». (Сообщено Beda Kosata, исправлено Antoine Pitrou; issue 8484.)

    Используемая версия OpenSSL теперь доступна как атрибуты модуля: ssl.OPENSSL_VERSION (строка), ssl.OPENSSL_VERSION_INFO (кортеж из 5 элементов) и ssl.OPENSSL_VERSION_NUMBER (целое число). (Добавлено Antoine Pitrou; issue 8321.)

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

  • Новая функция: check_output() модуля подпроцесс запускает команду с указанным набором аргументов и возвращает вывод команды в виде строки, если команда выполняется без ошибок, в противном случае вызывает исключение 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
    

    (Автор: Грегори П. Смит.)

    Модуль подпроцесс теперь будет повторять свои внутренние системные вызовы при получении сигнала EINTR. (Сообщено несколькими людьми; окончательный патч от Gregory P. Smith в issue 1068268.)

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

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

  • The sys.version_info value is now a named tuple, with attributes named major, minor, micro, releaselevel, and serial. (Contributed by Ross Light; issue 4285.)

    sys.getwindowsversion() также возвращает именованный кортеж с атрибутами major, minor, build, platform, service_pack, service_pack_major, service_pack_minor, suite_mask и product_type. (Добавлено Brian Curtin; issue 7766.)

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

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

  • Метод wait() класса threading.Event теперь возвращает внутренний флаг при выходе. Это означает, что метод обычно будет возвращать true, поскольку wait() должен блокироваться, пока внутренний флаг не станет истинным. Возвращаемое значение будет false только в том случае, если был указан таймаут и операция превысила его. (Добавлено Tim Lesher; issue 1674032.)

  • База данных Unicode, предоставляемая модулем unicodedata, теперь используется внутри для определения того, какие символы являются числовыми, пробельными или представляют разрывы строк. База данных также включает информацию из файла данных Unihan.txt (патч от Anders Chrigström и Amaury Forgeot d’Arc; issue 1571184) и обновлена до версии 5.2.0 (обновлено Florent Xicluna; issue 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 на самом деле выдаёт немного другой вывод, поскольку он возвращает именованный кортеж вместо стандартного кортежа.)

    The urlparse module also supports IPv6 literal addresses as defined by RFC 2732 (contributed by Senthil Kumaran; issue 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 -->). (Патч от Нила Мюллера; issue 2746.)

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

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

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

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

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

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

Python 3.1 включает пакет importlib – повторную реализацию логики, лежащей в основе оператора import Python. 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'>
>>> # Относительный импорт
>>> 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.

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

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

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

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

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

Пакет Distutils и sysconfig теперь поддерживает Тарек Зиаде; он также начал разработку пакета Distutils2 (исходный репозиторий по адресу http://hg.python.org/distutils2/) для создания следующего поколения Distutils.

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

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

Чтобы узнать больше, прочитайте документацию модуля ttk. Возможно, вы также захотите прочитать страницу руководства Tcl/Tk, описывающую механизм тем Ttk, доступную по адресу http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_intro.htm. Некоторые скриншоты использования кода Python/Ttk можно найти по адресу http://code.google.com/p/python-ttk/wiki/Screenshots.

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

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

Модуль unittest был значительно доработан; добавлен ряд новых возможностей. Большинство этих возможностей реализовано Михаэлем Фордом, если не указано иное. Расширенная версия модуля доступна для отдельной загрузки для Python 2.4–2.6 в виде пакета unittest2 по адресу http://pypi.python.org/pypi/unittest2.

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

python -m unittest discover -s test

Обратитесь к документации модуля unittest для получения более подробной информации. (Разработано в issue 6001.)

Функция main() поддерживает ещё несколько новых опций:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

unittest.main() теперь принимает необязательный аргумент exit. Если False, то main() не вызывает sys.exit(), что позволяет использовать main() из интерактивного интерпретатора. (Вклад J. Pablo Fernández; issue 3379.)

TestResult получил новые методы startTestRun() и stopTestRun(), которые вызываются непосредственно перед и после прогона тестов. (Автор: Robert Collins; issue 5728).

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

См. также

http://www.voidspace.org.uk/python/articles/unittest2.shtml
Описывает новые возможности, как их использовать, и обоснование различных проектных решений. (Автор: Майкл Форд.)

Обновлённый модуль: ElementTree 1.3Updated module: 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» или «text». Режим HTML будет выводить пустые элементы как <empty></empty> вместо <empty/>, а текстовый режим пропускает элементы и выводит только текстовые фрагменты. Если установить атрибут tag элемента в None, но оставить его дочерние элементы на месте, элемент будет опущен при записи дерева, так что не нужно выполнять более обширную перестройку для удаления одного элемента.

    Обработка пространств имён также была улучшена. Все объявления xmlns:<whatever> теперь выводятся в корневом элементе, а не разбросаны по всему результирующему XML. Можно задать пространство имён по умолчанию для дерева, установив атрибут default_namespace, и зарегистрировать новые префиксы с помощью register_namespace(). В режиме XML можно использовать параметр xml_declaration (true/false) для подавления 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:) раньше возвращало true, если элемент имел дочерние элементы, и false, если их не было. Такое поведение сбивает с толку – None это false, но и элемент без детей тоже? – поэтому теперь это будет вызывать FutureWarning. В вашем коде следует быть явным: пишите len(elem) != 0, если вас интересует количество дочерних элементов, или elem is not None.

Фредрик Лунд развивает ElementTree и выпустил версию 1.3; его статью с описанием 1.3 можно прочитать по адресу http://effbot.org/zone/elementtree-13-intro.htm. Флоран Сиклуна обновил версию, включённую в Python, после обсуждений в python-dev и в issue 6472).

Изменения в сборке и C APIBuild and C API Changes

Изменения процесса сборки 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. (Добавлено в результате issue 8032).

  • Если вы используете файл .gdbinit, поставляемый с Python, макрос «pyo» в версии 2.7 теперь работает корректно, когда отлаживаемый поток не удерживает GIL; макрос теперь захватывает его перед выводом. (Автор: Victor Stinner; issue 3632).

  • Py_AddPendingCall() теперь потокобезопасна: любой рабочий поток может отправлять уведомления главному потоку Python. Это особенно полезно для асинхронных операций ввода-вывода. (Автор: Kristján Valur Jónsson; issue 4293.)

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

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

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

  • Новые функции: PyLong_AsLongAndOverflow() и PyLong_AsLongLongAndOverflow() преобразуют длинное целое Python в C-типы long или long long. Если число слишком велико для целевого типа, устанавливается флаг overflow и возвращается вызывающей стороне. (Автор: Case Van Horsen; issue 7528 и issue 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, установленным в false.

    Проблема безопасности зарегистрирована как CVE-2008-5983; обсуждалась в issue 5753; исправлено Антуаном Питу.

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

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

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

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

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

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

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

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

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

  • Новый параметр configure: ключ --with-system-expat позволяет собрать модуль pyexpat с использованием системной библиотеки Expat. (Автор: Arfrever Frehtes Taifersar Arahesis; issue 7609.)

  • Новый параметр configure: опция --with-valgrind теперь отключает аллокатор pymalloc, который сложно корректно анализировать детектору ошибок памяти Valgrind. Таким образом, Valgrind сможет лучше обнаруживать утечки памяти и переполнения буфера. (Автор: James Henstridge; issue 2422.)

  • Новый параметр configure: теперь можно передать пустую строку в --with-dbmliborder=, чтобы отключить все модули DBM. (Добавлено Arfrever Frehtes Taifersar Arahesis; issue 6491.)

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

    configure также теперь устанавливает переменную Makefile LDCXXSHARED для поддержки линковки C++. (Автор: Arfrever Frehtes Taifersar Arahesis; issue 1222585.)

  • Процесс сборки теперь создаёт необходимые файлы для поддержки pkg-config. (Автор: Clinton Roy; issue 3585.)

  • Процесс сборки теперь поддерживает Subversion 1.7. (Автор: Arfrever Frehtes Taifersar Arahesis; issue 6094.)

КапсулыCapsules

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() обнаружит несоответствие имени и вернёт false. Обратитесь к Providing a C API for an Extension Module за дополнительной информацией об использовании этих объектов.

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

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

Изменения для конкретных платформ: WindowsPort-Specific Changes: Windows

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

Изменения для конкретных платформ: Mac OS XPort-Specific Changes: Mac OS X

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

Изменения для конкретных платформ: FreeBSDPort-Specific Changes: FreeBSD

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

Другие изменения и исправленияOther Changes and Fixes

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

Перенос на Python 2.7Porting to Python 2.7

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

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

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

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

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

    Сравнения, включающие сигнальное значение NaN (или sNAN), теперь вызывают InvalidOperation вместо молчаливого возврата true или false в зависимости от оператора сравнения. Тихие значения NaN (или NaN) теперь хешируемы. (Исправлено Mark Dickinson; тикет 7279.)

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

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

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

  • Обработка ошибок по умолчанию в модуле tarfile изменилась: теперь фатальные ошибки не подавляются. Раньше уровень ошибок по умолчанию был 0, что означало, что ошибки только записывались в отладочный журнал, но поскольку отладочный журнал по умолчанию не активирован, эти ошибки оставались незамеченными. Теперь уровень ошибок по умолчанию равен 1, что вызывает исключение при возникновении ошибки. (Изменено Ларсом Густабелем; issue 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 (issue 5080).
  • Используйте новую функцию PyOS_string_to_double() вместо старых функций PyOS_ascii_strtod() и PyOS_ascii_atof(), которые теперь устарели.

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

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

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

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