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

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

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

Использование 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 также может рефакторить доктесты. Чтобы включить этот режим, используйте флаг -d. Обратите внимание, что рефакторингу подвергнутся только доктесты. Для этого также не требуется, чтобы модуль был корректным Python. Например, примеры, оформленные как доктесты в 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

Преобразователи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.

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), а isinstance(x, (int, float, int)) преобразуется в isinstance(x, (int, float)).

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.abc. Выполняется следующее отображение:

Из

В

operator.isCallable(obj)

callable(obj)

operator.sequenceIncludes(obj)

operator.contains(obj)

operator.isSequenceType(obj)

isinstance(obj, collections.abc.Sequence)

operator.isMappingType(obj)

isinstance(obj, collections.abc.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() в importlib.reload().

renames

Заменяет sys.maxint на sys.maxsize.

repr

Заменяет 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.

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

Исходный код: Lib/lib2to3/


Примечание

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