2to3 — Автоматизированный перевод кода с Python 2 на 3

2-3 - это программа на 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

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

Будет напечатано сравнение с исходным файлом. 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)

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

По умолчанию от 2 до 3 запускается набор из predefined fixers. Флаг -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 не может исправить это автоматически. В этом случае 2to3 выводит предупреждение под diff для файла. Вам следует обратить внимание на предупреждение, чтобы получить совместимый код 3.x.

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

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

Поскольку некоторые команды print могут быть проанализированы как вызовы функций или инструкции, 2to3 не всегда может прочитать файлы, содержащие функцию print. Когда 2-3 обнаруживает наличие директивы компилятора 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

Фиксаторы

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

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 похож, но не совсем такой же, как у 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().

set_literal

Заменяет использование конструктора set литералами 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 — библиотека 2to3

Исходный код: 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 следует считать нестабильным и может кардинально измениться в будущем.

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