> **Источник:** https://python-all.ru/3.1/library/2to3.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 25.4. 2to3 – автоматическое преобразование кода Python 2 в 3

2to3 – это программа на Python, которая читает исходный код Python 2.x и применяет ряд *преобразователей* для преобразования его в корректный код Python 3.x. Стандартная библиотека содержит обширный набор преобразователей, которые справляются почти с любым кодом. Однако библиотека поддержки 2to3 `lib2to3` – это гибкая и универсальная библиотека, поэтому можно писать собственные преобразователи для 2to3. `lib2to3` также можно адаптировать для заказных приложений, в которых требуется автоматически редактировать код Python.

## 25.4.1. Использование 2to3

2to3 обычно устанавливается вместе с интерпретатором Python как скрипт. Он также находится в каталоге `Tools/scripts` корневого каталога Python.

Основные аргументы 2to3 – это список файлов или каталогов для преобразования. Каталоги обходятся рекурсивно в поисках исходников Python.

Вот пример исходного файла Python 2.x, `example.py`:

```python
def greet(name):
    print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)
```

Его можно преобразовать в код Python 3.x с помощью 2to3 в командной строке:

```python
$ 2to3 example.py
```

Выводится diff относительно исходного файла. 2to3 также может сразу записать необходимые изменения в исходный файл. (Резервная копия исходного файла создаётся, если не указан флаг *-n*.) Запись изменений включается флагом *-w*:

```python
$ 2to3 -w example.py
```

После преобразования `example.py` выглядит так:

```python
def greet(name):
    print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)
```

Комментарии и точные отступы сохраняются на протяжении всего процесса преобразования.

По умолчанию 2to3 запускает набор [*заранее определённых преобразователей*](https://python-all.ru/3.1/library/2to3.html#to3-fixers). Флаг *-l* выводит список всех доступных преобразователей. Явный набор преобразователей для запуска можно задать с помощью *-f*. Аналогично, *-x* явно отключает преобразователь. Следующий пример запускает только преобразователи `imports` и `has_key`:

```python
$ 2to3 -f imports -f has_key example.py
```

Эта команда запускает все фиксеры, кроме фиксера `apply`:

```python
$ 2to3 -x apply example.py
```

Некоторые фиксеры являются *явными*, то есть они не запускаются по умолчанию, и их необходимо указать в командной строке для запуска. Здесь, помимо фиксеров по умолчанию, запускается фиксер `idioms`:

```python
$ 2to3 -f all -f idioms example.py
```

Обратите внимание, что передача `all` включает все фиксеры по умолчанию.

Иногда 2to3 находит в исходном коде место, которое нужно изменить, но не может исправить автоматически. В этом случае 2to3 выводит предупреждение под diff для файла. Следует обработать это предупреждение, чтобы получить корректный код 3.x.

2to3 также может рефакторить доктесты. Чтобы включить этот режим, используйте флаг *-d*. Обратите внимание, что *только* доктесты будут подвергнуты рефакторингу. При этом не требуется, чтобы модуль был корректным Python. Например, примеры в стиле доктестов в документе reST также можно рефакторить с помощью этой опции.

Опция *-v* включает вывод дополнительной информации о процессе преобразования.

Поскольку некоторые операторы print можно разобрать как вызовы функций или как инструкции, 2to3 не всегда может читать файлы, содержащие функцию print. Когда 2to3 обнаруживает указание компилятора `from __future__ import print_function`, он изменяет свою внутреннюю грамматику, чтобы интерпретировать [`print()`](https://python-all.ru/3.1/library/functions.html#print) как функцию. Это изменение также можно включить вручную с помощью флага *-p*. Используйте *-p* для запуска фиксеров на коде, в котором операторы print уже преобразованы.

## 25.4.2. Фиксеры

Каждый шаг преобразования кода инкапсулирован в фиксере. Команда `2to3 -l` выводит их список. Как уже [*описано выше*](https://python-all.ru/3.1/library/2to3.html#to3-using), каждый можно включить или отключить по отдельности. Ниже они описаны подробнее.

**`apply`**

Удаляет использование

`apply()`

. Например,

`apply(function, *args, **kwargs)`

преобразуется в

`function(*args, **kwargs)`

.

**`basestring`**

Преобразует

`basestring`

в

[`str`](https://python-all.ru/3.1/library/functions.html#str)

.

**`buffer`**

Преобразует

`buffer`

в

[`memoryview`](https://python-all.ru/3.1/library/stdtypes.html#memoryview)

. Этот фиксер необязателен, поскольку API

[`memoryview`](https://python-all.ru/3.1/library/stdtypes.html#memoryview)

похож, но не полностью совпадает с API

`buffer`

.

**`callable`**

Преобразует

`callable(x)`

в

`isinstance(x, collections.Callable)`

, добавляя импорт

[`collections`](https://python-all.ru/3.1/library/collections.html#module-collections)

при необходимости.

**`dict`**

Исправляет методы итерации словарей.

`dict.iteritems()`

преобразуется в

[`dict.items()`](https://python-all.ru/3.1/library/stdtypes.html#dict.items)

,

`dict.iterkeys()`

в

[`dict.keys()`](https://python-all.ru/3.1/library/stdtypes.html#dict.keys)

, а

`dict.itervalues()`

в

[`dict.values()`](https://python-all.ru/3.1/library/stdtypes.html#dict.values)

. Аналогично,

`dict.viewitems()`

,

`dict.viewkeys()`

и

`dict.viewvalues()`

преобразуются соответственно в

[`dict.items()`](https://python-all.ru/3.1/library/stdtypes.html#dict.items)

,

[`dict.keys()`](https://python-all.ru/3.1/library/stdtypes.html#dict.keys)

и

[`dict.values()`](https://python-all.ru/3.1/library/stdtypes.html#dict.values)

. Кроме того, он оборачивает существующие использования

[`dict.items()`](https://python-all.ru/3.1/library/stdtypes.html#dict.items)

,

[`dict.keys()`](https://python-all.ru/3.1/library/stdtypes.html#dict.keys)

и

[`dict.values()`](https://python-all.ru/3.1/library/stdtypes.html#dict.values)

в вызов

[`list`](https://python-all.ru/3.1/library/functions.html#list)

.

**`except`**

Преобразует

`except X, T`

в

`except X as T`

.

**`exec`**

Преобразует инструкцию

`exec`

в функцию

[`exec()`](https://python-all.ru/3.1/library/functions.html#exec)

.

**`execfile`**

Удаляет использование

`execfile()`

. Аргумент

`execfile()`

оборачивается вызовами

[`open()`](https://python-all.ru/3.1/library/functions.html#open)

,

[`compile()`](https://python-all.ru/3.1/library/functions.html#compile)

и

[`exec()`](https://python-all.ru/3.1/library/functions.html#exec)

.

**`exitfunc`**

Заменяет присваивание

`sys.exitfunc`

на использование модуля

[`atexit`](https://python-all.ru/3.1/library/atexit.html#module-atexit)

.

**`filter`**

Оборачивает использование

[`filter()`](https://python-all.ru/3.1/library/functions.html#filter)

в вызов

[`list`](https://python-all.ru/3.1/library/functions.html#list)

.

**`funcattrs`**

Исправляет атрибуты функций, которые были переименованы. Например,

`my_function.func_closure`

преобразуется в

`my_function.__closure__`

.

**`future`**

Удаляет операторы

`from __future__ import new_feature`

.

**`getcwdu`**

Переименовывает

`os.getcwdu()`

в

[`os.getcwd()`](https://python-all.ru/3.1/library/os.html#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()`](https://python-all.ru/3.1/library/functions.html#sorted) в подходящих местах. Например, этот блок

```python
L = list(some_iterable)
L.sort()
```

изменяется на

```python
L = sorted(some_iterable)
```

**`import`**

Обнаруживает импорты соседних модулей и преобразует их в относительные импорты.

**`imports`**

Обрабатывает переименования модулей в стандартной библиотеке.

**`imports2`**

Обрабатывает переименования других модулей в стандартной библиотеке. Он отделён от фиксера

[`imports`](https://python-all.ru/3.1/library/2to3.html#2to3fixer-imports)

только из-за технических ограничений.

**`input`**

Преобразует

`input(prompt)`

в

`eval(input(prompt))`

**`intern`**

Преобразует

`intern()`

в

[`sys.intern()`](https://python-all.ru/3.1/library/sys.html#sys.intern)

.

**`isinstance`**

Исправляет дублирующиеся типы во втором аргументе

[`isinstance()`](https://python-all.ru/3.1/library/functions.html#isinstance)

. Например,

`isinstance(x, (int, int))`

преобразуется в

`isinstance(x, (int))`

.

**`itertools_imports`**

Удаляет импорты

`itertools.ifilter()`

,

`itertools.izip()`

и

`itertools.imap()`

. Импорты

`itertools.ifilterfalse()`

также заменяются на

[`itertools.filterfalse()`](https://python-all.ru/3.1/library/itertools.html#itertools.filterfalse)

.

**`itertools`**

Заменяет использование

`itertools.ifilter()`

,

`itertools.izip()`

и

`itertools.imap()`

на их встроенные эквиваленты.

`itertools.ifilterfalse()`

заменяется на

[`itertools.filterfalse()`](https://python-all.ru/3.1/library/itertools.html#itertools.filterfalse)

.

**`long`**

Убирает префикс

`L`

у литералов длинных целых и переименовывает

`long`

в

[`int`](https://python-all.ru/3.1/library/functions.html#int)

.

**`map`**

Оборачивает

[`map()`](https://python-all.ru/3.1/library/functions.html#map)

в вызов

[`list`](https://python-all.ru/3.1/library/functions.html#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()`](https://python-all.ru/3.1/library/functions.html#next)

. Также переименовывает методы

[`next()`](https://python-all.ru/3.1/library/functions.html#next)

в

`__next__()`

.

**`nonzero`**

Переименовывает

`__nonzero__()`

в

[`__bool__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__bool__)

.

**`numliterals`**

Преобразует восьмеричные литералы в новый синтаксис.

**`paren`**

Добавляет дополнительные круглые скобки там, где они требуются в списковых включениях. Например,

`[x for x in 1, 2]`

становится

`[x for x in (1, 2)]`

.

**`print`**

Преобразует инструкцию

`print`

в функцию

[`print()`](https://python-all.ru/3.1/library/functions.html#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()`](https://python-all.ru/3.1/library/functions.html#input)

.

**`reduce`**

Обрабатывает перенос

`reduce()`

в

[`functools.reduce()`](https://python-all.ru/3.1/library/functools.html#functools.reduce)

.

**`renames`**

Изменяет

`sys.maxint`

на

[`sys.maxsize`](https://python-all.ru/3.1/library/sys.html#sys.maxsize)

.

**`repr`**

Заменяет обратные кавычки на функцию

[`repr()`](https://python-all.ru/3.1/library/functions.html#repr)

.

**`set_literal`**

Заменяет использование конструктора

[`set`](https://python-all.ru/3.1/library/stdtypes.html#set)

на литералы множеств. Этот фиксер является необязательным.

**`standard_error`**

Переименовывает

`StandardError`

в

[`Exception`](https://python-all.ru/3.1/library/exceptions.html#Exception)

.

**`sys_exc`**

Изменяет устаревшие

`sys.exc_value`

,

`sys.exc_type`

,

`sys.exc_traceback`

на использование

[`sys.exc_info()`](https://python-all.ru/3.1/library/sys.html#sys.exc_info)

.

**`throw`**

Исправляет изменение API в методе

`throw()`

генератора.

**`tuple_params`**

Удаляет неявную распаковку параметров кортежа. Этот фиксер вставляет временные переменные.

**`types`**

Исправляет код, сломанный удалением некоторых членов модуля

[`types`](https://python-all.ru/3.1/library/types.html#module-types)

.

**`unicode`**

Переименовывает

`unicode`

в

[`str`](https://python-all.ru/3.1/library/functions.html#str)

.

**`urllib`**

Обрабатывает переименование

`urllib`

и

`urllib2`

в

`urllib`

пакет.

**`ws_comma`**

Удаляет лишние пробелы из элементов, разделённых запятыми. Этот фиксер необязателен.

**`xrange`**

Переименовывает

`xrange()`

в

[`range()`](https://python-all.ru/3.1/library/functions.html#range)

и оборачивает существующие вызовы

[`range()`](https://python-all.ru/3.1/library/functions.html#range)

в

[`list`](https://python-all.ru/3.1/library/functions.html#list)

.

**`xreadlines`**

Изменяет

`for x in file.xreadlines()`

на

`for x in file`

.

**`zip`**

Оборачивает использование

[`zip()`](https://python-all.ru/3.1/library/functions.html#zip)

в вызов

[`list`](https://python-all.ru/3.1/library/functions.html#list)

. Это отключается, когда встречается

`from future_builtins import zip`

.

## 25.4.3. `lib2to3` – библиотека 2to3

> **Примечание**
>
> API `lib2to3` следует считать нестабильным и в будущем оно может кардинально измениться.
