2to3 — Automated Python 2 to 3 code translation¶
2to3 — це програма Python, яка зчитує вихідний код Python 2.x і застосовує серію фіксаторів, щоб перетворити його на дійсний код Python 3.x. Стандартна бібліотека містить багатий набір фіксаторів, які оброблять майже весь код. Бібліотека підтримки 2to3 lib2to3
, однак, є гнучкою та загальною бібліотекою, тому можна написати власні фіксатори для 2to3.
Застаріло з версії 3.11, буде видалено у версії 3.13: The lib2to3
module was marked pending for deprecation in Python 3.9
(raising PendingDeprecationWarning
on import) and fully deprecated
in Python 3.11 (raising DeprecationWarning
). The 2to3
tool is
part of that. It will be removed in Python 3.13.
Використовуючи 2 до 3¶
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)
Коментарі та точні відступи зберігаються протягом усього процесу перекладу.
За замовчуванням 2to3 запускає набір передвизначених фіксаторів. Прапорець -l
містить список усіх доступних фіксаторів. Явний набір фіксаторів для запуску можна надати за допомогою -f
. Так само -x
явно вимикає фіксатор. У наступному прикладі запускаються лише фіксатори imports
і has_key
:
$ 2to3 -f imports -f has_key example.py
Ця команда запускає всі фіксатори, крім фіксатора apply
:
$ 2to3 -x apply example.py
Деякі фіксатори є явними, що означає, що вони не запускаються за замовчуванням і повинні бути зазначені в командному рядку для запуску. Тут, на додаток до типових фіксаторів, запускається фіксатор ідіом
:
$ 2to3 -f all -f idioms example.py
Зверніть увагу, як передача all
вмикає всі стандартні фіксатори.
Іноді 2to3 знаходить місце у вашому вихідному коді, яке потрібно змінити, але 2to3 не може виправити автоматично. У цьому випадку 2to3 надрукує попередження під diff для файлу. Вам слід усунути попередження, щоб мати сумісний код 3.x.
2to3 також може виконувати рефакторинг doctests. Щоб увімкнути цей режим, використовуйте прапорець -d
. Зауважте, що тільки doctests будуть перероблені. Для цього також не потрібно, щоб модуль був дійсним Python. Наприклад, приклади, схожі на doctest, у документі reST також можуть бути перероблені за допомогою цієї опції.
Опція -v
дозволяє виводити більше інформації про процес перекладу.
Оскільки деякі оператори друку можна проаналізувати як виклики функцій або оператори, 2to3 не завжди може читати файли, що містять функцію друку. Коли 2to3 виявляє наявність директиви компілятора from __future__ import print_function
, він змінює свою внутрішню граматику, щоб інтерпретувати print()
як функцію. Цю зміну також можна ввімкнути вручну за допомогою позначки -p
. Використовуйте -p
, щоб запустити фіксатори для коду, оператори друку якого вже перетворені. Також -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
перераховує їх. Як задокументовано вище, кожен з них можна вмикати та вимикати окремо. Тут вони описані більш детально.
- 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¶
Перетворює
крім X, T
накрім X як 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)
наключ у 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 для x в 1, 2]» перетворюється на «[x для x в (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’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
слід вважати нестабільним і може кардинально змінитися в майбутньому.