Содержание страницы
2to3 – автоматическое преобразование кода Python 2 в 3¶2to3 - Automated Python 2 to 3 code translation
2to3 – это программа на Python, которая читает исходный код Python 2.x и применяет серию
преобразователей для преобразования его в корректный код Python 3.x. Стандартная библиотека
содержит богатый набор преобразователей, которые справятся почти с любым кодом. 2to3 – поддерживающая
библиотека lib2to3, однако, представляет собой гибкую и обобщённую библиотеку, поэтому
можно написать собственные преобразователи для 2to3. lib2to3 также можно
адаптировать для пользовательских приложений, в которых требуется редактировать код Python
автоматически.
Использование 2to3¶Using 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)assertEquals(a, b)failIfEqual(a, b)assertNotEquals(a, b)failUnless(a)assert_(a)failIf(a)failUnlessRaises(exc, cal)failUnlessAlmostEqual(a, b)assertAlmostEquals(a, b)failIfAlmostEqual(a, b)assertNotAlmostEquals(a, b)
-
buffer¶ Преобразует
bufferвmemoryview. Этот фиксер необязателен, поскольку APImemoryviewпохож, но не полностью совпадает с APIbuffer.
-
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.
-
execfile¶ Удаляет использование
execfile(). Аргументexecfile()оборачивается в вызовыopen(),compile()иexec().
-
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().
-
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)].
-
raise¶ Преобразует
raise E, Vвraise E(V)иraise E, V, Tвraise E(V).with_traceback(T). ЕслиEявляется кортежем, перевод будет некорректным, поскольку замена кортежами исключений была удалена в версии 3.0.
-
reduce¶ Обрабатывает перемещение
reduce()вfunctools.reduce().
-
reload¶ Преобразует
reload()вimportlib.reload().
-
renames¶ Заменяет
sys.maxintнаsys.maxsize.
-
set_literal¶ Заменяет использование конструктора
setна литералы множества. Этот фиксер является необязательным.
-
sys_exc¶ Изменяет устаревшие
sys.exc_value,sys.exc_type,sys.exc_tracebackна использованиеsys.exc_info().
-
throw¶ Исправляет изменение API в методе
throw()генератора.
-
tuple_params¶ Удаляет неявную распаковку параметров кортежа. Этот фиксер вставляет временные переменные.
-
ws_comma¶ Удаляет лишние пробелы из элементов, разделённых запятыми. Этот фиксер необязателен.
-
xreadlines¶ Заменяет
for x in file.xreadlines()наfor x in file.
lib2to3 – библиотека 2to3¶lib2to3 - 2to3’s library
Исходный код: Lib/lib2to3/
Примечание
API lib2to3 следует считать нестабильным; в будущем оно может кардинально
измениться.