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

Автор

А.М. Кучлинг (amk at amk.ca)

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

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

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

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

Будущее для Python 2.x

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

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

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

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

  • Как отмечалось выше, релиз 2.7 имеет гораздо более длительный период поддержки по сравнению с более ранними версиями 2.x. В настоящее время ожидается, что Python 2.7 будет поддерживаться основной командой разработчиков (получая обновления безопасности и другие исправления ошибок) по крайней мере до 2020 года (10 лет после его первоначального выпуска, по сравнению с более типичным периодом поддержки в 18-24 месяца).

  • По мере старения стандартной библиотеки Python 2.7 эффективное использование индекса пакетов Python (напрямую или через редистрибьютора) становится все более важным для пользователей Python 2. Помимо широкого спектра пакетов сторонних разработчиков для различных задач, доступные пакеты включают бэкпорты новых модулей и функций из стандартной библиотеки Python 3, совместимых с Python 2, а также различные инструменты и библиотеки, которые могут облегчить переход на Python 3. В Python Packaging User Guide содержится руководство по загрузке и установке программного обеспечения из индекса пакетов Python.

  • Хотя предпочтительным подходом к улучшению Python 2 в настоящее время является публикация новых пакетов в Python Package Index, этот подход не обязательно работает во всех случаях, особенно в тех, которые связаны с сетевой безопасностью. В исключительных случаях, которые не могут быть адекватно решены путем публикации новых или обновленных пакетов на PyPI, можно использовать процесс Python Enhancement Proposal для обоснования необходимости добавления новых функций непосредственно в стандартную библиотеку Python 2. Любые такие дополнения, а также выпуски сопровождения, в которых они были добавлены, будут отмечены в разделе Новые возможности, добавленные в обновленные версии Python 2.7 ниже.

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

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

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

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

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

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

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

Особенности Python 3.1

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

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

  • Синтаксис для литералов множеств ({1,2,3} является изменяемым множеством).

  • Понимание словарей и множеств ({i: i*2 for i in range(3)}).

  • Несколько менеджеров контекста в одном операторе with.

  • Новая версия библиотеки io, переписанная на языке C для повышения производительности.

  • Тип упорядоченного словаря, описанный в PEP 372: Добавление упорядоченного словаря в коллекции.

  • Новый спецификатор формата ",", описанный в PEP 378: Спецификатор формата для разделителя тысяч.

  • Объект memoryview.

  • Небольшое подмножество модуля importlib, described below.

  • Во многих случаях repr() поплавка x короче: теперь оно основано на самой короткой десятичной строке, которая гарантированно округляется до x. Как и в предыдущих версиях Python, гарантируется, что float(repr(x)) восстанавливает x.

  • Преобразования из плавающей строки в строку и из строки в плавающую строку округляются правильно. Функция round() также теперь правильно округляется.

  • Тип PyCapsule, используемый для предоставления API на языке C для модулей расширения.

  • Функция API Си PyLong_AsLongAndOverflow().

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

  • operator.isCallable() и operator.sequenceIncludes(), которые не поддерживаются в 3.x, теперь вызывают предупреждения.

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

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

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

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

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

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

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

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

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

Метод popitem() имеет необязательный аргумент last, который по умолчанию равен True. Если last равен 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
>>> # Move 'third' key to the end
>>> del od2['third']; od2['third'] = 3
>>> od1 == od2
True

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

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

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

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

  • Метод _asdict() для collections.namedtuple() теперь возвращает упорядоченный словарь со значениями, расположенными в том же порядке, что и индексы кортежей.

  • Конструктор класса json модуля JSONDecoder был дополнен параметром object_pairs_hook, чтобы экземпляры OrderedDict могли быть построены декодером. Также была добавлена поддержка сторонних инструментов, таких как PyYAML.

См.также

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

PEP написан Армином Ронахером и Раймондом Хеттингером; реализован Раймондом Хеттингером.

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

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

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

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

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

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

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

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

См.также

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

PEP написан Раймондом Хеттингером; реализован Эриком Смитом.

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

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

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

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

Вот пример:

import argparse

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

# Add optional switches
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')

# Allow any number of additional arguments.
parser.add_argument(nargs='*', action='store', dest='inputs',
                    help='input filenames (default is stdin)')

args = parser.parse_args()
print args.__dict__

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

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

Command-line example.

positional arguments:
  inputs      input filenames (default is stdin)

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

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

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

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

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

См.также

argparse документация

Страница документации модуля argparse.

Обновление кода optparse

Часть документации по Python, описывающая, как преобразовать код, использующий optparse.

PEP 389 - argparse - новый модуль разбора командной строки

PEP написан и реализован Стивеном Бетардом.

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

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

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

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

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

import logging
import logging.config

configdict = {
 'version': 1,    # Configuration schema in use; must be 1 for now
 'formatters': {
     'standard': {
         'format': ('%(asctime)s %(name)-15s '
                    '%(levelname)-8s %(message)s')}},

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

 # Specify all the subordinate loggers
 'loggers': {
             'network': {
                         'handlers': ['netlog']
             }
 },
 # Specify properties of the root logger
 'root': {
          'handlers': ['syslog']
 },
}

# Set up configuration
logging.config.dictConfig(configdict)

# As an example, log two error messages
logger = logging.getLogger('/')
logger.error('Database not found')

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

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

  • Класс SysLogHandler теперь поддерживает передачу syslogging по 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(), который принимает уровень и возвращает, будет ли базовый регистратор обрабатывать сообщение с таким уровнем важности.

См.также

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

PEP написан и реализован Винаем Саджипом.

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

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

В Python 2.7 невозможно изменить возвращаемые значения keys(), values() и items(), так как слишком много кода будет сломано. Вместо этого версии для версии 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 написан Гвидо ван Россумом. Backported to 2.7 by Alexandre Vassalotti; bpo-1967.

PEP 3137: Объект просмотра памяти

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

>>> import string
>>> m = memoryview(string.letters)
>>> m
<memory at 0x37f850>
>>> len(m)           # Returns length of underlying object
52
>>> m[0], m[25], m[26]   # Indexing returns one byte
('a', 'z', 'A')
>>> m2 = m[0:26]         # Slicing returns another 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)  # Creating a mutable object
>>> b
bytearray(b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
>>> mb = memoryview(b)
>>> mb[0] = '*'         # Assign to view, changing the bytearray.
>>> b[0:5]              # The bytearray has been changed.
bytearray(b'*bcde')
>>>

См.также

PEP 3137 - Неизменяемые байты и изменяемый буфер

PEP написан Гвидо ван Россумом. Реализовано Трэвисом Олифантом, Антуаном Питру и другими. Бэкпортирован в 2.7 Антуаном Питру; bpo-2396.

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

Некоторые более мелкие изменения, внесенные в основной язык Python, следующие:

  • Синтаксис литералов множеств был перенесен из Python 3.x. Фигурные скобки используются для окружения содержимого результирующего изменяемого множества; литералы множеств отличаются от словарей тем, что не содержат двоеточий и значений. {} продолжает представлять пустой словарь; для пустого множества используйте set().

    >>> {1, 2, 3, 4, 5}
    set([1, 2, 3, 4, 5])
    >>> set() # empty set
    set([])
    >>> {}    # empty dict
    {}
    

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

  • Понимание словарей и множеств - это еще одна возможность, перенесенная из 3.x, которая обобщает понимание списков/генераторов для использования буквального синтаксиса для множеств и словарей.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    (Выполнено Марком Дикинсоном; bpo-3166).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • При использовании @classmethod и @staticmethod для обертывания методов как методов класса или статических методов, объект-обертка теперь раскрывает обернутую функцию как свой атрибут __func__. (Внесено Amaury Forgeot d’Arc, по предложению George Sakkis; bpo-5982).

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

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

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

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

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

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

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

Изменения в работе переводчика

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

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

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

Оптимизации

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

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

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

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

  • Длинные целые числа теперь хранятся внутри либо в базе 2**15, либо в базе 2**30, база определяется во время сборки. Ранее они всегда хранились в base 2**15. Использование base 2**30 дает значительный прирост производительности на 64-битных машинах, но результаты тестирования на 32-битных машинах были неоднозначными. Поэтому по умолчанию используется base 2**30 на 64-битных машинах и base 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)
    

    (Внесено Марком Дикинсоном; bpo-4258).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    >>> c.most_common(5)
    [(' ', 6), ('e', 5), ('s', 3), ('a', 2), ('i', 2)]
    >>> c.elements() ->
       'a', 'a', ' ', ' ', ' ', ' ', ' ', ' ',
       'e', 'e', 'e', 'e', 'e', 'g', 'f', 'i', 'i',
       'h', 'h', 'm', 'l', 'l', 'o', 'n', 'p', 's',
       's', 's', 'r', 't', 't', 'x'
    >>> c['e']
    5
    >>> c.subtract('very heavy on the letter e')
    >>> c['e']    # Count is now lower
    -1
    

    Внесено Раймондом Хеттингером; bpo-1696199.

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

    Новый метод: Тип данных 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')
    

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

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

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

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

    (При участии Матса Киндала; bpo-7005).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Внесено Джорджем Саккисом; bpo-3135.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Новая функция: 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 обрабатывает явное имя пути. (Добавлено Ником Когланом; bpo-6816).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Новая функция: subprocess модуля 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
    

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

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

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

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

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

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

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

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

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

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

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

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

    Python 2.7 (и Python 2.6.5) будет возвращаться:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

>>> from importlib import import_module
>>> anydbm = import_module('anydbm')  # Standard absolute import
>>> anydbm
<module 'anydbm' from '/p/python/Lib/anydbm.py'>
>>> # Relative import
>>> file_util = import_module('..file_util', 'distutils.command')
>>> file_util
<module 'distutils.file_util' from '/python/Lib/distutils/file_util.pyc'>

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

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

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

Некоторые из функций модуля следующие:

  • get_config_var() возвращает переменные из Makefile Python и файла pyconfig.h.

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

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

  • is_python_build() возвращает true, если вы запускаете двоичный файл из дерева исходников Python, и false в противном случае.

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

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

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

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

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

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

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

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

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

python -m unittest discover -s test

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Был добавлен ряд новых методов, обеспечивающих более специализированные тесты. Многие из этих методов были написаны инженерами Google для использования в их наборах тестов; Gregory P. Smith, Michael Foord и GvR работали над их включением в Python-версию unittest.

  • assertIsNone() и assertIsNotNone() берут одно выражение и проверяют, что результат является или не является None.

  • assertIs() и assertIsNot() принимают два значения и проверяют, оценивают ли эти два значения один и тот же объект или нет. (Добавлено Майклом Фоордом; bpo-2578).

  • assertIsInstance() и assertNotIsInstance() проверяют, является ли полученный объект экземпляром определенного класса или одного из кортежа классов. (Добавлено Георгом Брандлом; bpo-7031).

  • assertGreater(), assertGreaterEqual(), assertLess() и assertLessEqual() сравнивают две величины.

  • assertMultiLineEqual() сравнивает две строки, и если они не равны, выводит полезное сравнение, подчеркивающее различия в двух строках. Это сравнение теперь используется по умолчанию, когда строки Unicode сравниваются с помощью assertEqual().

  • assertRegexpMatches() и assertNotRegexpMatches() проверяет, является ли первый аргумент строкой, совпадающей или не совпадающей с регулярным выражением, представленным в качестве второго аргумента (bpo-8038).

  • assertRaisesRegexp() проверяет, возникло ли определенное исключение, а затем также проверяет, соответствует ли строковое представление исключения предоставленному регулярному выражению.

  • assertIn() и assertNotIn() проверяет, находится или нет первое во втором.

  • assertItemsEqual() проверяет, содержат ли две предоставленные последовательности одинаковые элементы.

  • assertSetEqual() сравнивает, равны ли два набора, и в случае ошибки сообщает только о различиях между наборами.

  • Аналогично, assertListEqual() и assertTupleEqual() сравнивают указанные типы и объясняют любые различия, не обязательно выводя их полные значения; эти методы теперь используются по умолчанию при сравнении списков и кортежей с помощью assertEqual(). В более общем случае assertSequenceEqual() сравнивает две последовательности и может опционально проверять, являются ли обе последовательности определенного типа.

  • assertDictEqual() сравнивает два словаря и сообщает о различиях; теперь он используется по умолчанию, когда вы сравниваете два словаря с помощью assertEqual(). assertDictContainsSubset() проверяет, все ли пары ключ/значение в первом встречаются во втором.

  • assertAlmostEqual() и assertNotAlmostEqual() проверяют, являются ли первое и второе приблизительно равными. Этот метод может либо округлить их разность до опционально заданного числа мест (по умолчанию 7) и сравнить ее с нулем, либо потребовать, чтобы разность была меньше заданного значения дельта.

  • loadTestsFromName() правильно учитывает атрибут suiteClass в TestLoader. (Исправлено Марком Родди; bpo-6866).

  • assertEqual() правильно учитывает атрибут addTypeEqualityFunc() в . (Исправлено Марком Родди; ).

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

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

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

См.также

https://web.archive.org/web/20210619163128/http://www.voidspace.org.uk/python/articles/unittest2.shtml

Описываются новые возможности, способы их использования и обоснование различных дизайнерских решений. (Автор Майкл Фоорд.)

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

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

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

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

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

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

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

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

    from xml.etree import ElementTree as ET
    
    t = ET.XML("""<list>
      <item>1</item> <item>2</item>  <item>3</item>
    </list>""")
    new = ET.XML('<root/>')
    new.extend(t)
    
    # Outputs <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>""")
    
    # Outputs ['\n  ', '1', ' ', '2', '  ', '3', '\n']
    print list(t.itertext())
    
  • Deprecated: using an element as a Boolean (i.e., if elem:) would return true if the element had any children, or false if there were no children. This behaviour is confusing – None is false, but so is a childless element? – so it will now trigger a FutureWarning. In your code, you should be explicit: write len(elem) != 0 if you’re interested in the number of children, or elem не None.

Фредрик Лундх разрабатывает ElementTree и выпустил версию 1.3; вы можете прочитать его статью с описанием 1.3 на https://web.archive.org/web/20200703234532/http://effbot.org/zone/elementtree-13-intro.htm. Florent Xicluna обновил версию, поставляемую с Python, после обсуждения на python-dev и в bpo-6472).

Изменения в API Build и C

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Капсулы

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

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

void *vtable;

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

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

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

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

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

Изменения, специфичные для порта: Windows

  • Модуль msvcrt теперь содержит некоторые константы из заголовочного файла crtassem.h: CRT_ASSEMBLY_VERSION, VC_ASSEMBLY_PUBLICKEYTOKEN и LIBRARIES_ASSEMBLY_NAME_PREFIX. (Внесено Дэвидом Курнапо; bpo-4365).

  • Модуль _winreg для доступа к реестру теперь реализует функции CreateKeyEx() и DeleteKeyEx(), расширенные версии ранее поддерживаемых функций, которые принимают несколько дополнительных аргументов. Функции DisableReflectionKey(), EnableReflectionKey() и QueryReflectionKey() также были протестированы и документированы. (Реализовано Брайаном Кертином: bpo-7347).

  • Для запуска потоков используется новый API _beginthreadex(), а для хранения данных теперь используются собственные функции локального хранения потоков. (Внесено Кристьяном Валуром Йонссоном; bpo-3582).

  • Функция os.kill() теперь работает в Windows. Значением сигнала могут быть константы CTRL_C_EVENT, CTRL_BREAK_EVENT или любое целое число. Первые две константы будут посылать события нажатия клавиш Control-C и Control-Break в подпроцессы; любое другое значение будет использовать API TerminateProcess(). (Внесено Мики Тебека; bpo-1220212).

  • Функция os.listdir() теперь корректно не работает при пустом пути. (Исправлено Хироказу Ямамото; bpo-5913).

  • Модуль mimelib теперь будет считывать базу данных MIME из реестра Windows при инициализации. (Исправление от Gabriel Genellina; bpo-4969).

Изменения для конкретного порта: Mac OS X

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

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

Изменения, специфичные для порта: FreeBSD

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

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

  • В каталог iobench были добавлены два эталонных скрипта, ccbench и Tools. iobench измеряет скорость встроенных объектов файлового ввода/вывода, возвращаемых open() при выполнении различных операций, а ccbench - это параллельный бенчмарк, который пытается измерить пропускную способность вычислений, задержку переключения потоков и пропускную способность обработки ввода/вывода при выполнении нескольких задач с использованием различного количества потоков.

  • Скрипт Tools/i18n/msgfmt.py теперь понимает формы множественного числа в файлах .po. (Исправлено Мартином фон Лёвисом; bpo-5464).

  • При импорте модуля из файла .pyc или .pyo с существующим аналогом .py, атрибуты co_filename результирующих объектов кода перезаписываются, если исходное имя файла устарело. Это может произойти, если файл был переименован, перемещен или доступ к нему осуществляется по другим путям. (Исправление Зиги Сейлнахт и Жан-Поля Кальдерона; bpo-1180193).

  • Сценарий regrtest.py теперь принимает переключатель --randseed=, который принимает целое число, которое будет использоваться в качестве случайного зерна для опции -r, которая выполняет тесты в случайном порядке. Опция -r также сообщает об использованном зерне (Добавлено Коллином Винтером.)

  • Другим переключателем regrtest.py является -j, который принимает целое число, указывающее, сколько тестов выполняется параллельно. Это позволяет уменьшить общее время выполнения на многоядерных машинах. Эта опция совместима с некоторыми другими опциями, включая переключатель -R, который, как известно, дает большое время выполнения. (Добавлен Антуаном Питру, bpo-6152.) Его также можно использовать с новым переключателем -F, который запускает выбранные тесты в цикле до тех пор, пока они не завершатся неудачей. (Добавлено Антуаном Питру; bpo-7312).

  • При выполнении в виде сценария модуль py_compile.py теперь принимает в качестве аргумента '-', который будет считывать стандартный ввод для списка имен файлов, подлежащих компиляции. (Внесено Петром Ожаровским; bpo-8233).

Перенос на Python 2.7

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

  • Функция range() обрабатывает свои аргументы более последовательно; теперь она будет вызывать __int__() при передаче не плоских, не целочисленных аргументов. (Исправлено Александром Белопольским; bpo-1533).

  • Метод строк format() изменил точность по умолчанию, используемую для чисел с плавающей точкой и комплексных чисел, с 6 знаков после запятой на 12, что соответствует точности, используемой методом str(). (Изменено Эриком Смитом; bpo-5920).

  • Из-за оптимизации оператора with специальные методы __enter__() и __exit__() должны принадлежать типу объекта и не могут быть непосредственно присоединены к экземпляру объекта. Это касается классов нового стиля (производных от object) и типов расширения языка Си. (bpo-6101.)

  • Из-за ошибки в Python 2.6 параметр exc_value в методах __exit__() часто представлял собой строковое представление исключения, а не экземпляр. Это было исправлено в версии 2.7, поэтому exc_value будет экземпляром, как и ожидалось. (Исправлено Florent Xicluna; bpo-7853).

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

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

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

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

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

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

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

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

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

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

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

    Python 2.7 (и Python 2.6.5) будет возвращаться:

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

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

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

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

  • Используйте новую функцию PyOS_string_to_double() вместо старых функций PyOS_ascii_strtod() и PyOS_ascii_atof(), которые уже устарели.

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

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

Новые возможности, добавленные в обновленные версии Python 2.7

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

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

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

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

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

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

PEP 434: Исключение по усовершенствованию IDLE для всех филиалов

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

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

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

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

PEP 466 связанные возможности, добавленные в Python 2.7.7:

  • hmac.compare_digest() был перенесен из Python 3, чтобы сделать операцию сравнения, устойчивую к атакам на время, доступной для приложений Python 2. (Внесено Алексом Гейнором; bpo-21306).

  • OpenSSL 1.0.1g был обновлен в официальных установщиках для Windows, опубликованных на python.org. (Внесено Закари Уэйром; bpo-21462).

PEP 466 связанные возможности, добавленные в Python 2.7.8:

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

  • OpenSSL 1.0.1h был обновлен для официальных установщиков Windows, опубликованных на python.org. (внесено Закари Уэйром в bpo-21671 для CVE-2014-0224)

PEP 466 связанные возможности, добавленные в Python 2.7.9:

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

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

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

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

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

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

Загрузочный трубопровод по умолчанию

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

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

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

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

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

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

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

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

См.также

PEP 453 – Явная загрузка pip в установках Python

PEP написан Дональдом Стаффтом и Ником Когланом, реализован Дональдом Стаффтом, Ником Когланом, Мартином фон Лёвисом и Недом Дейли.

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

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

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

import urllib2
import ssl

# This disables all verification
context = ssl._create_unverified_context()

# This allows using a specific certificate for the host, which doesn't need
# to be in the trust store
context = ssl.create_default_context(cafile="/path/to/file.crt")

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь в работе над различными черновиками этой статьи: Nick Coghlan, Philip Jenvey, Ryan Lovett, R. David Murray, Hugh Secker-Walker.

Вернуться на верх