2to3.md
1> **Источник:** https://python-all.ru/3.6/library/2to3.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 26.7. 2to3 – автоматическое преобразование кода Python 2 в 3892to3 – это программа на Python, которая читает исходный код Python 2.x и применяет серию *преобразователей* для преобразования его в корректный код Python 3.x. Стандартная библиотека содержит богатый набор преобразователей, которые справятся почти с любым кодом. 2to3 – поддерживающая библиотека [`lib2to3`](https://python-all.ru/3.6/library/2to3.html#module-lib2to3), однако, представляет собой гибкую и обобщённую библиотеку, поэтому можно написать собственные преобразователи для 2to3. [`lib2to3`](https://python-all.ru/3.6/library/2to3.html#module-lib2to3) также можно адаптировать для пользовательских приложений, в которых требуется редактировать код Python автоматически.1011## 26.7.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/3.6/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/3.6/library/functions.html#print) как функцию. Это изменение также можно включить вручную с помощью флага `-p`. Используйте `-p` для запуска преобразователей на коде, в котором операторы print уже преобразованы.7879Опция `-o` или `--output-dir` позволяет указать альтернативный каталог для записи выходных файлов. Флаг `-n` обязателен при использовании этого, поскольку резервные копии не имеют смысла, когда исходные файлы не перезаписываются.8081Новое в версии 3.2.3: Была добавлена опция `-o`.8283Флаг `-W` или `--write-unchanged-files` предписывает 2to3 всегда записывать выходные файлы, даже если файл не требовал изменений. Это наиболее полезно с `-o`, чтобы всё дерево исходников Python было скопировано с преобразованием из одного каталога в другой. Эта опция подразумевает флаг `-w`, иначе она не имела бы смысла.8485Новое в версии 3.2.3: Был добавлен флаг `-W`.8687Опция `--add-suffix` задаёт строку, которая будет добавлена ко всем именам выходных файлов. Флаг `-n` обязателен при указании этой опции, так как резервные копии не нужны при записи в файлы с другими именами. Пример:8889```console90$ 2to3 -n -W --add-suffix=3 example.py91```9293Приведёт к записи преобразованного файла с именем `example.py3`.9495Новое в версии 3.2.3: Была добавлена опция `--add-suffix`.9697Чтобы преобразовать весь проект из одного дерева каталогов в другое, используйте:9899```console100$ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode101```102103## 26.7.2. Fixers104105Каждый шаг преобразования кода инкапсулирован в преобразователе. Команда `2to3 -l` выводит их список. Как [описано выше](https://python-all.ru/3.6/library/2to3.html#to3-using), каждый можно включать и отключать по отдельности. Здесь они описаны более подробно.106107**`apply`**108109Удаляет использование `apply()`. Например, `apply(function, *args, **kwargs)` преобразуется в `function(*args, **kwargs)`.110111**`asserts`**112113Заменяет устаревшие имена методов [`unittest`](https://python-all.ru/3.6/library/unittest.html#module-unittest) на корректные.114115| Из | В |116| --- | --- |117| `failUnlessEqual(a, b)` | [`assertEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertEqual) |118| `assertEquals(a, b)` | [`assertEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertEqual) |119| `failIfEqual(a, b)` | [`assertNotEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertNotEqual) |120| `assertNotEquals(a, b)` | [`assertNotEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertNotEqual) |121| `failUnless(a)` | [`assertTrue(a)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertTrue) |122| `assert_(a)` | [`assertTrue(a)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertTrue) |123| `failIf(a)` | [`assertFalse(a)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertFalse) |124| `failUnlessRaises(exc, cal)` | [`assertRaises(exc, cal)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertRaises) |125| `failUnlessAlmostEqual(a, b)` | [`assertAlmostEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertAlmostEqual) |126| `assertAlmostEquals(a, b)` | [`assertAlmostEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertAlmostEqual) |127| `failIfAlmostEqual(a, b)` | [`assertNotAlmostEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) |128| `assertNotAlmostEquals(a, b)` | [`assertNotAlmostEqual(a, b)`](https://python-all.ru/3.6/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) |129130**`basestring`**131132Преобразует `basestring` в [`str`](https://python-all.ru/3.6/library/stdtypes.html#str).133134**`buffer`**135136Преобразует `buffer` в [`memoryview`](https://python-all.ru/3.6/library/stdtypes.html#memoryview). Этот фиксер необязателен, поскольку API [`memoryview`](https://python-all.ru/3.6/library/stdtypes.html#memoryview) похож, но не полностью совпадает с API `buffer`.137138**`dict`**139140Исправляет методы итерации словарей. `dict.iteritems()` преобразуется в [`dict.items()`](https://python-all.ru/3.6/library/stdtypes.html#dict.items), `dict.iterkeys()` – в [`dict.keys()`](https://python-all.ru/3.6/library/stdtypes.html#dict.keys), а `dict.itervalues()` – в [`dict.values()`](https://python-all.ru/3.6/library/stdtypes.html#dict.values). Аналогично, `dict.viewitems()`, `dict.viewkeys()` и `dict.viewvalues()` преобразуются соответственно в [`dict.items()`](https://python-all.ru/3.6/library/stdtypes.html#dict.items), [`dict.keys()`](https://python-all.ru/3.6/library/stdtypes.html#dict.keys) и [`dict.values()`](https://python-all.ru/3.6/library/stdtypes.html#dict.values). Также он оборачивает существующие использования [`dict.items()`](https://python-all.ru/3.6/library/stdtypes.html#dict.items), [`dict.keys()`](https://python-all.ru/3.6/library/stdtypes.html#dict.keys) и [`dict.values()`](https://python-all.ru/3.6/library/stdtypes.html#dict.values) в вызов [`list`](https://python-all.ru/3.6/library/stdtypes.html#list).141142**`except`**143144Преобразует `except X, T` в `except X as T`.145146**`exec`**147148Преобразует инструкцию `exec` в функцию [`exec()`](https://python-all.ru/3.6/library/functions.html#exec).149150**`execfile`**151152Удаляет использование `execfile()`. Аргумент `execfile()` оборачивается в вызовы [`open()`](https://python-all.ru/3.6/library/functions.html#open), [`compile()`](https://python-all.ru/3.6/library/functions.html#compile) и [`exec()`](https://python-all.ru/3.6/library/functions.html#exec).153154**`exitfunc`**155156Изменяет присваивание `sys.exitfunc` на использование модуля [`atexit`](https://python-all.ru/3.6/library/atexit.html#module-atexit).157158**`filter`**159160Оборачивает использование [`filter()`](https://python-all.ru/3.6/library/functions.html#filter) в вызов [`list`](https://python-all.ru/3.6/library/stdtypes.html#list).161162**`funcattrs`**163164Исправляет переименованные атрибуты функций. Например, `my_function.func_closure` преобразуется в `my_function.__closure__`.165166**`future`**167168Удаляет операторы `from __future__ import new_feature`.169170**`getcwdu`**171172Переименовывает `os.getcwdu()` в [`os.getcwd()`](https://python-all.ru/3.6/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/3.6/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/3.6/library/2to3.html#2to3fixer-imports) только из-за технических ограничений.204205**`input`**206207Преобразует `input(prompt)` в `eval(input(prompt))`.208209**`intern`**210211Преобразует `intern()` в [`sys.intern()`](https://python-all.ru/3.6/library/sys.html#sys.intern).212213**`isinstance`**214215Исправляет дублирование типов во втором аргументе [`isinstance()`](https://python-all.ru/3.6/library/functions.html#isinstance). Например, `isinstance(x, (int, int))` преобразуется в `isinstance(x, int)`, а `isinstance(x, (int, float, int))` преобразуется в `isinstance(x, (int, float))`.216217**`itertools_imports`**218219Удаляет импорты `itertools.ifilter()`, `itertools.izip()` и `itertools.imap()`. Импорты `itertools.ifilterfalse()` также заменяются на [`itertools.filterfalse()`](https://python-all.ru/3.6/library/itertools.html#itertools.filterfalse).220221**`itertools`**222223Изменяет использование `itertools.ifilter()`, `itertools.izip()` и `itertools.imap()` на их встроенные аналоги. `itertools.ifilterfalse()` заменяется на [`itertools.filterfalse()`](https://python-all.ru/3.6/library/itertools.html#itertools.filterfalse).224225**`long`**226227Переименовывает `long` в [`int`](https://python-all.ru/3.6/library/functions.html#int).228229**`map`**230231Оборачивает [`map()`](https://python-all.ru/3.6/library/functions.html#map) в вызов [`list`](https://python-all.ru/3.6/library/stdtypes.html#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()` итератора в функцию [`next()`](https://python-all.ru/3.6/library/functions.html#next). Также переименовывает методы [`next()`](https://python-all.ru/3.6/library/functions.html#next) в [`__next__()`](https://python-all.ru/3.6/library/stdtypes.html#iterator.__next__).248249**`nonzero`**250251Переименовывает `__nonzero__()` в [`__bool__()`](https://python-all.ru/3.6/reference/datamodel.html#object.__bool__).252253**`numliterals`**254255Преобразует восьмеричные литералы в новый синтаксис.256257**`operator`**258259Преобразует вызовы различных функций из модуля [`operator`](https://python-all.ru/3.6/library/operator.html#module-operator) в другие, но эквивалентные вызовы. При необходимости добавляются соответствующие операторы `import`, например `import collections`. Выполняется следующее отображение:260261| Из | В |262| --- | --- |263| `operator.isCallable(obj)` | `hasattr(obj, '__call__')` |264| `operator.sequenceIncludes(obj)` | `operator.contains(obj)` |265| `operator.isSequenceType(obj)` | `isinstance(obj, collections.Sequence)` |266| `operator.isMappingType(obj)` | `isinstance(obj, collections.Mapping)` |267| `operator.isNumberType(obj)` | `isinstance(obj, numbers.Number)` |268| `operator.repeat(obj, n)` | `operator.mul(obj, n)` |269| `operator.irepeat(obj, n)` | `operator.imul(obj, n)` |270271**`paren`**272273Добавляет дополнительные круглые скобки там, где они необходимы в списковых включениях. Например, `[x for x in 1, 2]` становится `[x for x in (1, 2)]`.274275**`print`**276277Преобразует инструкцию `print` в функцию [`print()`](https://python-all.ru/3.6/library/functions.html#print).278279**`raise`**280281Преобразует `raise E, V` в `raise E(V)` и `raise E, V, T` в `raise E(V).with_traceback(T)`. Если `E` является кортежем, перевод будет некорректным, поскольку замена кортежами исключений была удалена в версии 3.0.282283**`raw_input`**284285Преобразует `raw_input()` в [`input()`](https://python-all.ru/3.6/library/functions.html#input).286287**`reduce`**288289Обрабатывает перемещение `reduce()` в [`functools.reduce()`](https://python-all.ru/3.6/library/functools.html#functools.reduce).290291**`reload`**292293Преобразует `reload()` в [`imp.reload()`](https://python-all.ru/3.6/library/imp.html#imp.reload).294295**`renames`**296297Заменяет `sys.maxint` на [`sys.maxsize`](https://python-all.ru/3.6/library/sys.html#sys.maxsize).298299**`repr`**300301Заменяет repr с обратными кавычками на функцию [`repr()`](https://python-all.ru/3.6/library/functions.html#repr).302303**`set_literal`**304305Заменяет использование конструктора [`set`](https://python-all.ru/3.6/library/stdtypes.html#set) на литералы множества. Этот фиксер является необязательным.306307**`standarderror`**308309Переименовывает `StandardError` в [`Exception`](https://python-all.ru/3.6/library/exceptions.html#Exception).310311**`sys_exc`**312313Изменяет устаревшие `sys.exc_value`, `sys.exc_type`, `sys.exc_traceback` на использование [`sys.exc_info()`](https://python-all.ru/3.6/library/sys.html#sys.exc_info).314315**`throw`**316317Исправляет изменение API в методе `throw()` генератора.318319**`tuple_params`**320321Удаляет неявную распаковку параметров кортежа. Этот фиксер вставляет временные переменные.322323**`types`**324325Исправляет код, сломанный в результате удаления некоторых членов модуля [`types`](https://python-all.ru/3.6/library/types.html#module-types).326327**`unicode`**328329Переименовывает `unicode` в [`str`](https://python-all.ru/3.6/library/stdtypes.html#str).330331**`urllib`**332333Обрабатывает переименование [`urllib`](https://python-all.ru/3.6/library/urllib.html#module-urllib) и `urllib2` в пакет [`urllib`](https://python-all.ru/3.6/library/urllib.html#module-urllib).334335**`ws_comma`**336337Удаляет лишние пробелы из элементов, разделённых запятыми. Этот фиксер необязателен.338339**`xrange`**340341Переименовывает `xrange()` в [`range()`](https://python-all.ru/3.6/library/stdtypes.html#range) и оборачивает существующие вызовы [`range()`](https://python-all.ru/3.6/library/stdtypes.html#range) в [`list`](https://python-all.ru/3.6/library/stdtypes.html#list).342343**`xreadlines`**344345Заменяет `for x in file.xreadlines()` на `for x in file`.346347**`zip`**348349Оборачивает использование [`zip()`](https://python-all.ru/3.6/library/functions.html#zip) в вызов [`list`](https://python-all.ru/3.6/library/stdtypes.html#list). Отключается, когда появляется `from future_builtins import zip`.350351## 26.7.3. [`lib2to3`](https://python-all.ru/3.6/library/2to3.html#module-lib2to3) – библиотека 2to3352353**Исходный код:** [Lib/lib2to3/](https://python-all.ru/src/3.6/Lib/lib2to3)354355---356357> **Примечание**358>359> API [`lib2to3`](https://python-all.ru/3.6/library/2to3.html#module-lib2to3) следует считать нестабильным; в будущем оно может кардинально измениться.360