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