Содержание страницы
2to3 – автоматическое преобразование кода Python 2 в 3¶2to3 – Automated Python 2 to 3 code translation
2to3 – это программа на Python, которая читает исходный код Python 2.x и применяет ряд
преобразователей для преобразования его в корректный код Python 3.x. Стандартная библиотека
содержит богатый набор преобразователей, которые обрабатывают почти любой код. Библиотека поддержки 2to3
lib2to3, однако, представляет собой гибкую и универсальную библиотеку, поэтому
можно писать собственные преобразователи для 2to3.
Устарело с версии 3.11, будет удалено в версии 3.13: Модуль lib2to3 был отмечен как намечаемый к устареванию в Python 3.9
(вызывает PendingDeprecationWarning при импорте) и полностью устарел
в Python 3.11 (вызывает DeprecationWarning). Инструмент 2to3 является частью этого. Он будет удалён в Python 3.13.
Использование 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 уже были преобразованы. Также -e можно использовать, чтобы сделать exec() функцией.
Опция -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/
Устарело с версии 3.11, будет удалено в версии 3.13: В Python 3.9 перешли на PEG-парсер (см. PEP 617), в то время как lib2to3 использует менее гибкий LL(1)-парсер. Python 3.10 содержит новый синтаксис языка, который не может быть разобран LL(1)-парсером lib2to3 (см. PEP 634).
Модуль lib2to3 был помечен как ожидающий устаревания в Python 3.9 (при импорте вызывал PendingDeprecationWarning) и полностью устарел в Python 3.11 (вызывает DeprecationWarning).
Он будет удалён из стандартной библиотеки в Python 3.13.
Рассмотрите сторонние альтернативы, такие как LibCST или parso.
Примечание
API lib2to3 следует считать нестабильным; в будущем оно может кардинально
измениться.