2to3.md
1> **Источник:** https://python-all.ru/2.7/library/2to3.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 25.4. 2to3 – автоматическое преобразование кода Python 2 в 3892to3 – это программа на Python, которая читает исходный код Python 2.x и применяет серию *преобразователей* для преобразования его в корректный код Python 3.x. Стандартная библиотека содержит богатый набор преобразователей, которые справятся почти с любым кодом. 2to3 – поддерживающая библиотека [`lib2to3`](https://python-all.ru/2.7/library/2to3.html#module-lib2to3), однако, представляет собой гибкую и обобщённую библиотеку, поэтому можно написать собственные преобразователи для 2to3. [`lib2to3`](https://python-all.ru/2.7/library/2to3.html#module-lib2to3) также можно адаптировать для пользовательских приложений, в которых требуется редактировать код Python автоматически.1011## 25.4.1. Использование 2to312132to3 обычно устанавливается вместе с интерпретатором Python как скрипт. Он также находится в каталоге `Tools/scripts` корневой директории Python.1415Основные аргументы 2to3 – это список файлов или каталогов для преобразования. Каталоги обходятся рекурсивно в поисках исходников Python.1617Вот пример исходного файла на Python 2.x, `example.py`:1819```python20def greet(name):21 print "Hello, {0}!".format(name)22print "What's your name?"23name = raw_input()24greet(name)25```2627Его можно преобразовать в код Python 3.x с помощью 2to3 в командной строке:2829```console30$ 2to3 example.py31```3233Выводится diff относительно исходного файла. 2to3 также может записать необходимые изменения прямо в исходный файл. (Резервная копия исходного файла создаётся, если только не указан `-n`.) Запись изменений обратно включается флагом `-w`:3435```console36$ 2to3 -w example.py37```3839После преобразования `example.py` выглядит так:4041```python42def greet(name):43 print("Hello, {0}!".format(name))44print("What's your name?")45name = input()46greet(name)47```4849Комментарии и точные отступы сохраняются на протяжении всего процесса преобразования.5051По умолчанию 2to3 запускает набор [предопределённых преобразователей](https://python-all.ru/2.7/library/2to3.html#to3-fixers). Флаг `-l` выводит список всех доступных преобразователей. Явный набор преобразователей для запуска можно задать с помощью `-f`. Аналогично `-x` явно отключает преобразователь. В следующем примере запускаются только преобразователи `imports` и `has_key`:5253```console54$ 2to3 -f imports -f has_key example.py55```5657Эта команда запускает все преобразователи, кроме `apply`:5859```console60$ 2to3 -x apply example.py61```6263Некоторые преобразователи являются *явными*, то есть они не запускаются по умолчанию и должны быть перечислены в командной строке для запуска. Здесь, помимо преобразователей по умолчанию, запускается преобразователь `idioms`:6465```console66$ 2to3 -f all -f idioms example.py67```6869Обратите внимание: передача `all` включает все преобразователи по умолчанию.7071Иногда 2to3 находит в исходном коде место, которое нужно изменить, но не может исправить автоматически. В этом случае 2to3 выводит предупреждение под diff для файла. Следует обработать это предупреждение, чтобы получить корректный код 3.x.72732to3 также может рефакторить доктесты. Чтобы включить этот режим, используйте флаг `-d`. Обратите внимание, что рефакторингу подвергнутся *только* доктесты. Для этого также не требуется, чтобы модуль был корректным Python. Например, примеры, оформленные как доктесты в reST-документе, также могут быть отрефакторены с помощью этой опции.7475Опция `-v` включает вывод дополнительной информации о процессе преобразования.7677Поскольку некоторые операторы print можно разобрать как вызовы функций или инструкции, 2to3 не всегда может читать файлы, содержащие функцию print. Когда 2to3 обнаруживает наличие директивы компилятора `from __future__ import print_function`, он изменяет свою внутреннюю грамматику, чтобы интерпретировать [`print()`](https://python-all.ru/2.7/library/functions.html#print) как функцию. Это изменение также можно включить вручную с помощью флага `-p`. Используйте `-p` для запуска преобразователей на коде, в котором операторы print уже преобразованы.7879Опция `-o` или `--output-dir` позволяет указать альтернативный каталог для записи выходных файлов. Флаг `-n` обязателен при использовании этого, поскольку резервные копии не имеют смысла, когда исходные файлы не перезаписываются.8081Новое в версии 2.7.3: Добавлена опция `-o`.8283Флаг `-W` или `--write-unchanged-files` предписывает 2to3 всегда записывать выходные файлы, даже если файл не требовал изменений. Это наиболее полезно с `-o`, чтобы всё дерево исходников Python было скопировано с преобразованием из одного каталога в другой. Эта опция подразумевает флаг `-w`, иначе она не имела бы смысла.8485Новое в версии 2.7.3: Добавлен флаг `-W`.8687Опция `--add-suffix` задаёт строку, которая будет добавлена ко всем именам выходных файлов. Флаг `-n` обязателен при указании этой опции, так как резервные копии не нужны при записи в файлы с другими именами. Пример:8889```console90$ 2to3 -n -W --add-suffix=3 example.py91```9293Приведёт к записи преобразованного файла с именем `example.py3`.9495Новое в версии 2.7.3: Добавлена опция `--add-suffix`.9697Чтобы преобразовать весь проект из одного дерева каталогов в другое, используйте:9899```console100$ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode101```102103## 25.4.2. Исправители104105Каждый шаг преобразования кода инкапсулирован в преобразователе. Команда `2to3 -l` выводит их список. Как [описано выше](https://python-all.ru/2.7/library/2to3.html#to3-using), каждый можно включать и отключать по отдельности. Здесь они описаны более подробно.106107**`apply`**108109Удаляет использование [`apply()`](https://python-all.ru/2.7/library/functions.html#apply). Например, `apply(function, *args, **kwargs)` преобразуется в `function(*args, **kwargs)`.110111**`asserts`**112113Заменяет устаревшие имена методов [`unittest`](https://python-all.ru/2.7/library/unittest.html#module-unittest) на корректные.114115| Из | В |116| --- | --- |117| `failUnlessEqual(a, b)` | [`assertEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertEqual) |118| `assertEquals(a, b)` | [`assertEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertEqual) |119| `failIfEqual(a, b)` | [`assertNotEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertNotEqual) |120| `assertNotEquals(a, b)` | [`assertNotEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertNotEqual) |121| `failUnless(a)` | [`assertTrue(a)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertTrue) |122| `assert_(a)` | [`assertTrue(a)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertTrue) |123| `failIf(a)` | [`assertFalse(a)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertFalse) |124| `failUnlessRaises(exc, cal)` | [`assertRaises(exc, cal)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertRaises) |125| `failUnlessAlmostEqual(a, b)` | [`assertAlmostEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertAlmostEqual) |126| `assertAlmostEquals(a, b)` | [`assertAlmostEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertAlmostEqual) |127| `failIfAlmostEqual(a, b)` | [`assertNotAlmostEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) |128| `assertNotAlmostEquals(a, b)` | [`assertNotAlmostEqual(a, b)`](https://python-all.ru/2.7/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) |129130**`basestring`**131132Преобразует [`basestring`](https://python-all.ru/2.7/library/functions.html#basestring) в [`str`](https://python-all.ru/2.7/library/functions.html#str).133134**`buffer`**135136Преобразует [`buffer`](https://python-all.ru/2.7/library/functions.html#buffer) в [`memoryview`](https://python-all.ru/2.7/library/stdtypes.html#memoryview). Этот фиксер необязателен, поскольку API [`memoryview`](https://python-all.ru/2.7/library/stdtypes.html#memoryview) похож, но не полностью совпадает с API [`buffer`](https://python-all.ru/2.7/library/functions.html#buffer).137138**`dict`**139140Исправляет методы итерации словарей. [`dict.iteritems()`](https://python-all.ru/2.7/library/stdtypes.html#dict.iteritems) преобразуется в [`dict.items()`](https://python-all.ru/2.7/library/stdtypes.html#dict.items), [`dict.iterkeys()`](https://python-all.ru/2.7/library/stdtypes.html#dict.iterkeys) – в [`dict.keys()`](https://python-all.ru/2.7/library/stdtypes.html#dict.keys), а [`dict.itervalues()`](https://python-all.ru/2.7/library/stdtypes.html#dict.itervalues) – в [`dict.values()`](https://python-all.ru/2.7/library/stdtypes.html#dict.values). Аналогично, [`dict.viewitems()`](https://python-all.ru/2.7/library/stdtypes.html#dict.viewitems), [`dict.viewkeys()`](https://python-all.ru/2.7/library/stdtypes.html#dict.viewkeys) и [`dict.viewvalues()`](https://python-all.ru/2.7/library/stdtypes.html#dict.viewvalues) преобразуются соответственно в [`dict.items()`](https://python-all.ru/2.7/library/stdtypes.html#dict.items), [`dict.keys()`](https://python-all.ru/2.7/library/stdtypes.html#dict.keys) и [`dict.values()`](https://python-all.ru/2.7/library/stdtypes.html#dict.values). Также он оборачивает существующие использования [`dict.items()`](https://python-all.ru/2.7/library/stdtypes.html#dict.items), [`dict.keys()`](https://python-all.ru/2.7/library/stdtypes.html#dict.keys) и [`dict.values()`](https://python-all.ru/2.7/library/stdtypes.html#dict.values) в вызов `list`.141142**`except`**143144Преобразует `except X, T` в `except X as T`.145146**`exec`**147148Преобразует инструкцию [`exec`](https://python-all.ru/2.7/reference/simple_stmts.html#exec) в функцию `exec()`.149150**`execfile`**151152Удаляет использование [`execfile()`](https://python-all.ru/2.7/library/functions.html#execfile). Аргумент [`execfile()`](https://python-all.ru/2.7/library/functions.html#execfile) оборачивается в вызовы [`open()`](https://python-all.ru/2.7/library/functions.html#open), [`compile()`](https://python-all.ru/2.7/library/functions.html#compile) и `exec()`.153154**`exitfunc`**155156Изменяет присваивание [`sys.exitfunc`](https://python-all.ru/2.7/library/sys.html#sys.exitfunc) на использование модуля [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit).157158**`filter`**159160Оборачивает использование [`filter()`](https://python-all.ru/2.7/library/functions.html#filter) в вызов `list`.161162**`funcattrs`**163164Исправляет переименованные атрибуты функций. Например, `my_function.func_closure` преобразуется в `my_function.__closure__`.165166**`future`**167168Удаляет операторы `from __future__ import new_feature`.169170**`getcwdu`**171172Переименовывает [`os.getcwdu()`](https://python-all.ru/2.7/library/os.html#os.getcwdu) в [`os.getcwd()`](https://python-all.ru/2.7/library/os.html#os.getcwd).173174**`has_key`**175176Заменяет `dict.has_key(key)` на `key in dict`.177178**`idioms`**179180Этот необязательный фиксер выполняет несколько преобразований, делающих код Python более идиоматичным. Сравнения типов, такие как `type(x) is SomeClass` и `type(x) == SomeClass`, преобразуются в `isinstance(x, SomeClass)`. `while 1` становится `while True`. Этот фиксер также старается использовать [`sorted()`](https://python-all.ru/2.7/library/functions.html#sorted) в подходящих местах. Например, этот блок181182```python183L = list(some_iterable)184L.sort()185```186187изменяется на188189```python190L = sorted(some_iterable)191```192193**`import`**194195Обнаруживает импорты соседних модулей и преобразует их в относительные импорты.196197**`imports`**198199Обрабатывает переименования модулей в стандартной библиотеке.200201**`imports2`**202203Обрабатывает переименования других модулей в стандартной библиотеке. Он отделён от фиксера [`imports`](https://python-all.ru/2.7/library/2to3.html#2to3fixer-imports) только из-за технических ограничений.204205**`input`**206207Преобразует `input(prompt)` в `eval(input(prompt))`.208209**`intern`**210211Преобразует [`intern()`](https://python-all.ru/2.7/library/functions.html#intern) в `sys.intern()`.212213**`isinstance`**214215Исправляет дублирование типов во втором аргументе [`isinstance()`](https://python-all.ru/2.7/library/functions.html#isinstance). Например, `isinstance(x, (int, int))` преобразуется в `isinstance(x, (int))`.216217**`itertools_imports`**218219Удаляет импорты [`itertools.ifilter()`](https://python-all.ru/2.7/library/itertools.html#itertools.ifilter), [`itertools.izip()`](https://python-all.ru/2.7/library/itertools.html#itertools.izip) и [`itertools.imap()`](https://python-all.ru/2.7/library/itertools.html#itertools.imap). Импорты [`itertools.ifilterfalse()`](https://python-all.ru/2.7/library/itertools.html#itertools.ifilterfalse) также заменяются на `itertools.filterfalse()`.220221**`itertools`**222223Изменяет использование [`itertools.ifilter()`](https://python-all.ru/2.7/library/itertools.html#itertools.ifilter), [`itertools.izip()`](https://python-all.ru/2.7/library/itertools.html#itertools.izip) и [`itertools.imap()`](https://python-all.ru/2.7/library/itertools.html#itertools.imap) на их встроенные аналоги. [`itertools.ifilterfalse()`](https://python-all.ru/2.7/library/itertools.html#itertools.ifilterfalse) заменяется на `itertools.filterfalse()`.224225**`long`**226227Переименовывает [`long`](https://python-all.ru/2.7/library/functions.html#long) в [`int`](https://python-all.ru/2.7/library/functions.html#int).228229**`map`**230231Оборачивает [`map()`](https://python-all.ru/2.7/library/functions.html#map) в вызов `list`. Также заменяет `map(None, x)` на `list(x)`. Использование `from future_builtins import map` отключает этот фиксер.232233**`metaclass`**234235Преобразует старый синтаксис метакласса (`__metaclass__ = Meta` в теле класса) в новый (`class X(metaclass=Meta)`).236237**`methodattrs`**238239Исправляет старые имена атрибутов методов. Например, `meth.im_func` преобразуется в `meth.__func__`.240241**`ne`**242243Преобразует старый синтаксис неравенства, `<>`, в `!=`.244245**`next`**246247Преобразует использование методов [`next()`](https://python-all.ru/2.7/library/stdtypes.html#iterator.next) итератора в функцию [`next()`](https://python-all.ru/2.7/library/functions.html#next). Также переименовывает методы [`next()`](https://python-all.ru/2.7/library/stdtypes.html#iterator.next) в `__next__()`.248249**`nonzero`**250251Переименовывает [`__nonzero__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__nonzero__) в `__bool__()`.252253**`numliterals`**254255Преобразует восьмеричные литералы в новый синтаксис.256257**`paren`**258259Добавляет дополнительные круглые скобки там, где они необходимы в списковых включениях. Например, `[x for x in 1, 2]` становится `[x for x in (1, 2)]`.260261**`print`**262263Преобразует инструкцию [`print`](https://python-all.ru/2.7/reference/simple_stmts.html#print) в функцию [`print()`](https://python-all.ru/2.7/library/functions.html#print).264265**`raise`**266267Преобразует `raise E, V` в `raise E(V)`, а `raise E, V, T` в `raise E(V).with_traceback(T)`. Если `E` является кортежем, преобразование будет неверным, поскольку в Python 3 удалена подстановка кортежей на место исключений.268269**`raw_input`**270271Преобразует [`raw_input()`](https://python-all.ru/2.7/library/functions.html#raw_input) в [`input()`](https://python-all.ru/2.7/library/functions.html#input).272273**`reduce`**274275Обрабатывает перемещение [`reduce()`](https://python-all.ru/2.7/library/functions.html#reduce) в [`functools.reduce()`](https://python-all.ru/2.7/library/functools.html#functools.reduce).276277**`renames`**278279Заменяет [`sys.maxint`](https://python-all.ru/2.7/library/sys.html#sys.maxint) на [`sys.maxsize`](https://python-all.ru/2.7/library/sys.html#sys.maxsize).280281**`repr`**282283Заменяет repr с обратными кавычками на функцию [`repr()`](https://python-all.ru/2.7/library/functions.html#repr).284285**`set_literal`**286287Заменяет использование конструктора [`set`](https://python-all.ru/2.7/library/stdtypes.html#set) на литералы множества. Этот фиксер является необязательным.288289**`standarderror`**290291Переименовывает [`StandardError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.StandardError) в [`Exception`](https://python-all.ru/2.7/library/exceptions.html#exceptions.Exception).292293**`sys_exc`**294295Изменяет устаревшие [`sys.exc_value`](https://python-all.ru/2.7/library/sys.html#sys.exc_value), [`sys.exc_type`](https://python-all.ru/2.7/library/sys.html#sys.exc_type), [`sys.exc_traceback`](https://python-all.ru/2.7/library/sys.html#sys.exc_traceback) на использование [`sys.exc_info()`](https://python-all.ru/2.7/library/sys.html#sys.exc_info).296297**`throw`**298299Исправляет изменение API в методе `throw()` генератора.300301**`tuple_params`**302303Удаляет неявную распаковку параметров кортежа. Этот фиксер вставляет временные переменные.304305**`types`**306307Исправляет код, сломанный в результате удаления некоторых членов модуля [`types`](https://python-all.ru/2.7/library/types.html#module-types).308309**`unicode`**310311Переименовывает [`unicode`](https://python-all.ru/2.7/library/functions.html#unicode) в [`str`](https://python-all.ru/2.7/library/functions.html#str).312313**`urllib`**314315Обрабатывает переименование [`urllib`](https://python-all.ru/2.7/library/urllib.html#module-urllib) и [`urllib2`](https://python-all.ru/2.7/library/urllib2.html#module-urllib2) в пакет [`urllib`](https://python-all.ru/2.7/library/urllib.html#module-urllib).316317**`ws_comma`**318319Удаляет лишние пробелы из элементов, разделённых запятыми. Этот фиксер необязателен.320321**`xrange`**322323Переименовывает [`xrange()`](https://python-all.ru/2.7/library/functions.html#xrange) в [`range()`](https://python-all.ru/2.7/library/functions.html#range) и оборачивает существующие вызовы [`range()`](https://python-all.ru/2.7/library/functions.html#range) в `list`.324325**`xreadlines`**326327Заменяет `for x in file.xreadlines()` на `for x in file`.328329**`zip`**330331Оборачивает использование [`zip()`](https://python-all.ru/2.7/library/functions.html#zip) в вызов `list`. Отключается, когда появляется `from future_builtins import zip`.332333## 25.4.3. [`lib2to3`](https://python-all.ru/2.7/library/2to3.html#module-lib2to3) – библиотека 2to3334335> **Примечание**336>337> API [`lib2to3`](https://python-all.ru/2.7/library/2to3.html#module-lib2to3) следует считать нестабильным; в будущем оно может кардинально измениться.338