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

26.6. 2to3 – автоматический перевод кода с Python 2 на Python 32to3 - Automated Python 2 to 3 code translation

2to3 – это программа на Python, которая читает исходный код Python 2.x и применяет ряд фиксеров, чтобы преобразовать его в корректный код Python 3.x. Стандартная библиотека содержит богатый набор фиксеров, которые обрабатывают почти любой код. Однако вспомогательная библиотека lib2to3 является гибкой и универсальной, поэтому можно написать собственные фиксеры для 2to3. lib2to3 также можно адаптировать для пользовательских приложений, где требуется автоматическое редактирование кода Python.

26.6.1. Использование 2to3Using 2to3

2to3 обычно устанавливается вместе с интерпретатором Python как скрипт. Он также находится в каталоге Tools/scripts корневого каталога Python.

Основные аргументы 2to3 – это список файлов или каталогов для преобразования. Каталоги обходятся рекурсивно в поисках исходников Python.

Вот пример исходного файла Python 2.x, example.py:

def greet(name):
    print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)

Его можно преобразовать в код Python 3.x с помощью 2to3 в командной строке:

$ 2to3 example.py

Выводится diff относительно исходного файла. 2to3 также может сразу записать необходимые изменения в исходный файл. (Резервная копия исходного файла создаётся, если не указан флаг -n.) Запись изменений включается флагом -w:

$ 2to3 -w example.py

После преобразования example.py выглядит так:

def greet(name):
    print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)

Комментарии и точные отступы сохраняются на протяжении всего процесса преобразования.

По умолчанию 2to3 запускает набор предопределённых фиксеров. Флаг -l выводит список всех доступных фиксеров. Явный набор фиксеров для запуска можно задать с помощью -f. Аналогично, -x явно отключает фиксер. В следующем примере запускаются только фиксеры imports и has_key:

$ 2to3 -f imports -f has_key example.py

Эта команда запускает все фиксеры, кроме фиксера apply:

$ 2to3 -x apply example.py

Некоторые фиксеры являются явными, то есть они не запускаются по умолчанию, и их необходимо указать в командной строке для запуска. Здесь, помимо фиксеров по умолчанию, запускается фиксер idioms:

$ 2to3 -f all -f idioms example.py

Обратите внимание, что передача all включает все фиксеры по умолчанию.

Иногда 2to3 находит в исходном коде место, которое нужно изменить, но не может исправить автоматически. В этом случае 2to3 выводит предупреждение под diff для файла. Следует обработать это предупреждение, чтобы получить корректный код 3.x.

2to3 также может рефакторить doctest'ы. Для включения этого режима используйте флаг -d. Обратите внимание, что только doctest'ы будут подвергнуты рефакторингу. При этом модуль не обязан быть корректным Python. Например, примеры в стиле doctest в reST-документе также можно рефакторить с помощью этой опции.

Опция -v включает вывод дополнительной информации о процессе перевода.

Поскольку некоторые операторы print можно разобрать как вызовы функций или как инструкции, 2to3 не всегда может читать файлы, содержащие функцию print. Когда 2to3 обнаруживает указание компилятора from __future__ import print_function, он изменяет свою внутреннюю грамматику, чтобы интерпретировать print() как функцию. Это изменение также можно включить вручную с помощью флага -p. Используйте -p для запуска фиксеров на коде, в котором операторы print уже преобразованы.

Опция -o или --output-dir позволяет указать альтернативный каталог для записи обработанных выходных файлов. Флаг -n обязателен при использовании этой опции, так как резервные копии не имеют смысла, если исходные файлы не перезаписываются.

Новое в версии 3.2.3: Добавлена опция -o.

Флаг -W или --write-unchanged-files указывает 2to3 всегда записывать выходные файлы, даже если в файл не требовалось вносить изменения. Это наиболее полезно в сочетании с -o, чтобы скопировать всё дерево исходного кода Python с переводом из одного каталога в другой. Эта опция подразумевает флаг -w, поскольку иначе она не имела бы смысла.

Новое в версии 3.2.3: Добавлен флаг -W.

Опция --add-suffix задаёт строку, которая будет добавлена ко всем именам выходных файлов. Флаг -n обязателен при указании этой опции, так как резервные копии не нужны, если запись ведётся в файлы с другими именами. Пример:

$ 2to3 -n -W --add-suffix=3 example.py

В результате будет записан преобразованный файл с именем example.py3.

Новое в версии 3.2.3: Добавлена опция --add-suffix.

Чтобы преобразовать весь проект из одного дерева каталогов в другое, используйте:

$ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode

26.6.2. ФиксерыFixers

Каждый шаг преобразования кода инкапсулирован в фиксере. Команда 2to3 -l выводит их список. Как уже описано выше, каждый можно включить или отключить по отдельности. Ниже они описаны подробнее.

apply

Удаляет использование apply(). Например, apply(function, *args, **kwargs) преобразуется в function(*args, **kwargs).

asserts

Заменяет устаревшие имена методов unittest на корректные.

Из В
failUnlessEqual(a, b) assertEqual(a, b)
assertEquals(a, b) assertEqual(a, b)
failIfEqual(a, b) assertNotEqual(a, b)
assertNotEquals(a, b) assertNotEqual(a, b)
failUnless(a) assertTrue(a)
assert_(a) assertTrue(a)
failIf(a) assertFalse(a)
failUnlessRaises(exc, cal) assertRaises(exc, cal)
failUnlessAlmostEqual(a, b) assertAlmostEqual(a, b)
assertAlmostEquals(a, b) assertAlmostEqual(a, b)
failIfAlmostEqual(a, b) assertNotAlmostEqual(a, b)
assertNotAlmostEquals(a, b) assertNotAlmostEqual(a, b)
basestring

Преобразует basestring в str.

buffer

Преобразует buffer в memoryview. Этот фиксер необязателен, поскольку API memoryview похож, но не полностью совпадает с API buffer.

callable

Преобразует callable(x) в isinstance(x, collections.Callable), добавляя импорт collections при необходимости. Обратите внимание, что callable(x) была возвращена в Python 3.2, поэтому если не планируется поддержка Python 3.1, этот фиксер можно отключить.

dict

Исправляет методы итерации словарей. dict.iteritems() преобразуется в dict.items(), dict.iterkeys() в dict.keys(), а dict.itervalues() в dict.values(). Аналогично, dict.viewitems(), dict.viewkeys() и dict.viewvalues() преобразуются соответственно в dict.items(), dict.keys() и dict.values(). Кроме того, он оборачивает существующие использования dict.items(), dict.keys() и dict.values() в вызов list.

except

Преобразует except X, T в except X as T.

exec

Преобразует инструкцию exec в функцию exec().

execfile

Удаляет использование execfile(). Аргумент execfile() оборачивается вызовами open(), compile() и exec().

exitfunc

Заменяет присваивание sys.exitfunc на использование модуля atexit.

filter

Оборачивает использование filter() в вызов list.

funcattrs

Исправляет атрибуты функций, которые были переименованы. Например, my_function.func_closure преобразуется в my_function.__closure__.

future

Удаляет операторы from __future__ import new_feature.

getcwdu

Переименовывает os.getcwdu() в os.getcwd().

has_key

Заменяет dict.has_key(key) на key in dict.

idioms

Этот дополнительный фиксер выполняет несколько преобразований, делающих код Python более идиоматичным. Сравнения типов, такие как type(x) is SomeClass и type(x) == SomeClass, преобразуются в isinstance(x, SomeClass). while 1 становится while True. Этот фиксер также старается использовать sorted() в подходящих местах. Например, этот блок

L = list(some_iterable)
L.sort()

изменяется на

L = sorted(some_iterable)
import

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

imports

Обрабатывает переименования модулей в стандартной библиотеке.

imports2

Обрабатывает переименования других модулей в стандартной библиотеке. Он отделён от фиксера imports только из-за технических ограничений.

input

Преобразует input(prompt) в eval(input(prompt)).

intern

Преобразует intern() в sys.intern().

isinstance

Исправляет дублирующиеся типы во втором аргументе isinstance(). Например, isinstance(x, (int, int)) преобразуется в isinstance(x, (int)).

itertools_imports

Удаляет импорты itertools.ifilter(), itertools.izip() и itertools.imap(). Импорты itertools.ifilterfalse() также заменяются на itertools.filterfalse().

itertools

Заменяет использование itertools.ifilter(), itertools.izip() и itertools.imap() на их встроенные эквиваленты. itertools.ifilterfalse() заменяется на itertools.filterfalse().

long

Переименовывает long в int.

map

Оборачивает map() в вызов list. Также заменяет map(None, x) на list(x). Использование from future_builtins import map отключает этот фиксер.

metaclass

Преобразует старый синтаксис метакласса (__metaclass__ = Meta в теле класса) в новый (class X(metaclass=Meta)).

methodattrs

Исправляет старые имена атрибутов методов. Например, meth.im_func преобразуется в meth.__func__.

ne

Преобразует старый синтаксис неравенства, <>, в !=.

next

Преобразует использование методов next() итератора в функцию next(). Также переименовывает методы next() в __next__().

nonzero

Переименовывает __nonzero__() в __bool__().

numliterals

Преобразует восьмеричные литералы в новый синтаксис.

operator

Преобразует вызовы различных функций из модуля operator в другие, но эквивалентные вызовы функций. При необходимости добавляются соответствующие операторы import, например import collections. Выполняются следующие преобразования:

Из В
operator.isCallable(obj) hasattr(obj, '__call__')
operator.sequenceIncludes(obj) operator.contains(obj)
operator.isSequenceType(obj) isinstance(obj, collections.Sequence)
operator.isMappingType(obj) isinstance(obj, collections.Mapping)
operator.isNumberType(obj) isinstance(obj, numbers.Number)
operator.repeat(obj, n) operator.mul(obj, n)
operator.irepeat(obj, n) operator.imul(obj, n)
paren

Добавляет дополнительные круглые скобки там, где они требуются в списковых включениях. Например, [x for x in 1, 2] становится [x for x in (1, 2)].

print

Преобразует инструкцию print в функцию print().

raise

Преобразует raise E, V в raise E(V), а raise E, V, T в raise E(V).with_traceback(T). Если E – кортеж, преобразование будет некорректным, так как подстановка кортежей вместо исключений была удалена в версии 3.0.

raw_input

Преобразует raw_input() в input().

reduce

Обрабатывает перенос reduce() в functools.reduce().

reload

Преобразует reload() в imp.reload().

renames

Изменяет sys.maxint на sys.maxsize.

repr

Заменяет обратные кавычки на функцию repr().

set_literal

Заменяет использование конструктора set на литералы множеств. Этот фиксер является необязательным.

standarderror

Переименовывает StandardError в Exception.

sys_exc

Изменяет устаревшие sys.exc_value, sys.exc_type, sys.exc_traceback на использование sys.exc_info().

throw

Исправляет изменение API в методе throw() генератора.

tuple_params

Удаляет неявную распаковку параметров кортежа. Этот фиксер вставляет временные переменные.

types

Исправляет код, сломанный удалением некоторых членов модуля types.

unicode

Переименовывает unicode в str.

urllib

Обрабатывает переименование urllib и urllib2 в пакет urllib.

ws_comma

Удаляет лишние пробелы из элементов, разделённых запятыми. Этот фиксер необязателен.

xrange

Переименовывает xrange() в range() и оборачивает существующие вызовы range() в list.

xreadlines

Изменяет for x in file.xreadlines() на for x in file.

zip

Оборачивает использование zip() в вызов list. Это отключается, когда встречается from future_builtins import zip.

26.6.3. lib2to3 – библиотека 2to3lib2to3 - 2to3’s library

Примечание

API lib2to3 следует считать нестабильным и может существенно измениться в будущем.