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

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

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

Использование 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 уже были преобразованы. Также -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)

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/


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