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

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

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

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

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

Так как некоторые операторы print могут интерпретироваться как вызовы функций или операторы, 2to3 не всегда может читать файлы, содержащие функцию print. Когда 2to3 обнаруживает наличие директивы компилятора from __future__ import print_function, он изменяет свою внутреннюю грамматику, чтобы интерпретировать print() как функцию. Это изменение также можно включить вручную с помощью флага -p. Используйте -p для запуска исправлений на коде, в котором уже преобразованы операторы print.

25.4.2. ФиксерыFixers

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

apply
Удаляет использование apply(). Например, apply(function, *args, **kwargs) преобразуется в function(*args, **kwargs).
basestring
Преобразует basestring в str.
buffer
Преобразует buffer в memoryview. Этот исправитель необязателен, потому что API memoryview похож, но не полностью идентичен API buffer.
callable
Преобразует callable(x) в isinstance(x, collections.Callable), добавляя импорт collections при необходимости.
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)).
itertools_imports
Удаляет импорты itertools.ifilter(), itertools.izip() и itertools.imap(). Импорты itertools.ifilterfalse() также заменяются на itertools.filterfalse().
itertools
Изменяет использование itertools.ifilter(), itertools.izip() и itertools.imap() на их встроенные эквиваленты. itertools.ifilterfalse() заменяется на itertools.filterfalse().
long
Убирает префикс L у длинных литералов и переименовывает 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
Преобразует восьмеричные литералы в новый синтаксис.
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().
renames
Изменяет sys.maxint на sys.maxsize.
repr
Заменяет обратные кавычки на функцию repr().
set_literal
Заменяет использование конструктора set на литералы множеств. Этот фиксер является необязательным.
standard_error
Переименовывает StandardError в исключение.
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.

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

Примечание

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