> **Источник:** https://python-all.ru/2.6/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/2.6/library/2to3.html#to3-fixers). Флаг *-l* выводит список всех доступных преобразователей. Явный набор запускаемых преобразователей можно задать с помощью *-f*. Аналогично [*-x*](https://python-all.ru/2.6/using/cmdline.html#cmdoption-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 также может рефакторить doctest'ы. Для включения этого режима используйте флаг [*-d*](https://python-all.ru/2.6/using/cmdline.html#cmdoption-d). Обратите внимание, что *только* doctest'ы будут подвергнуты рефакторингу. При этом модуль не обязан быть корректным Python. Например, примеры в стиле doctest в reST-документе также можно рефакторить с помощью этой опции.

Опция [*-v*](https://python-all.ru/2.6/using/cmdline.html#cmdoption-v) включает вывод дополнительной информации о процессе перевода.

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

## 25.4.2. Фиксеры

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

**`apply`**

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

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

. Например,

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

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

`function(*args, **kwargs)`

.

**`basestring`**

Преобразует

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

в

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

.

**`buffer`**

Преобразует

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

в

`memoryview`

. Этот исправитель необязателен, потому что API

`memoryview`

похож, но не полностью идентичен API

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

.

**`callable`**

Преобразует

`callable(x)`

в

`isinstance(x, collections.Callable)`

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

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

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

**`dict`**

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

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

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

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

,

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

– в

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

, а

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

– в

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

. Аналогично

`dict.viewitems()`

,

`dict.viewkeys()`

и

`dict.viewvalues()`

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

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

,

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

и

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

. Также существующие использования

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

,

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

и

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

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

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

.

**`except`**

Преобразует

`except X, T`

в

`except X as T`

.

**`exec`**

Преобразует оператор

[`exec`](https://python-all.ru/2.6/reference/simple_stmts.html#exec)

в функцию

`exec()`

.

**`execfile`**

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

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

. Аргумент

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

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

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

,

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

и

`exec()`

.

**`exitfunc`**

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

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

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

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

.

**`filter`**

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

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

в вызов

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

.

**`funcattrs`**

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

`my_function.func_closure`

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

`my_function.__closure__`

.

**`future`**

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

`from __future__ import new_feature`

.

**`getcwdu`**

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

[`os.getcwdu()`](https://python-all.ru/2.6/library/os.html#os.getcwdu)

в

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

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

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

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

**`import`**

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

**`imports`**

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

**`imports2`**

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

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

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

**`input`**

Преобразует

`input(prompt)`

в

`eval(input(prompt))`

**`intern`**

Преобразует

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

в

`sys.intern()`

.

**`isinstance`**

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

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

. Например,

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

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

`isinstance(x, (int))`

.

**`itertools_imports`**

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

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

,

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

и

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

. Импорты

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

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

`itertools.filterfalse()`

.

**`itertools`**

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

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

,

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

и

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

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

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

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

`itertools.filterfalse()`

.

**`long`**

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

`L`

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

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

в

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

.

**`map`**

Оборачивает

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

в вызов

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

итератора в функцию

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

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

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

в

`__next__()`

.

**`nonzero`**

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

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

в

`__bool__()`

.

**`numliterals`**

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

**`paren`**

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

`[x for x in 1, 2]`

становится

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

.

**`print`**

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

[`print`](https://python-all.ru/2.6/reference/simple_stmts.html#print)

в функцию

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

в

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

.

**`reduce`**

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

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

в

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

.

**`renames`**

Изменяет

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

на

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

.

**`repr`**

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

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

.

**`set_literal`**

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

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

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

**`standard_error`**

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

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

в

[`исключение`](https://python-all.ru/2.6/library/exceptions.html#exceptions.Exception)

.

**`sys_exc`**

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

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

,

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

,

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

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

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

.

**`throw`**

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

`throw()`

генератора.

**`tuple_params`**

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

**`types`**

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

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

.

**`unicode`**

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

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

в

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

.

**`urllib`**

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

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

и

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

в

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

пакет.

**`ws_comma`**

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

**`xrange`**

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

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

в

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

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

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

вызовы в

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

.

**`xreadlines`**

Изменяет

`for x in file.xreadlines()`

на

`for x in file`

.

**`zip`**

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

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

в вызов

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

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

`from future_builtins import zip`

.

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

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