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)

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

Перетворює крім X, T на крім X як 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) на ключ у 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 для x в 1, 2]» перетворюється на «[x для x в (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 — 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 слід вважати нестабільним і може кардинально змінитися в майбутньому.