This document is for an old version of Python that is no longer supported. You should upgrade and read the documentação do Python para versão estável atual.

# 25.4. 2to3 - Tradução Automatizada de Código Python 2 para 3

2to3 é um programa Python que lê código-fonte Python 2.x e aplica uma série de fixers para transformá-lo em código válido para a versão do Python 3.x. A biblioteca padrão contém um conjunto rico de fixers que lidarão com quase todos os códigos. A biblioteca de suporte `lib2to3` é, no entanto, uma biblioteca genérica e flexível, por isso é possível escrever seus próprios fixers para o 2to3. O módulo `lib2to3` também pode er adaptado a aplicativos personalizados em que o código Python precisa ser editado automaticamente.

## 25.4.1. Usando o 2to3

O 2to3 geralmente será instalado junto com o interpretador Python como se fosse um script. Ele também está localizado no diretório `Tools/scripts` na raiz da instalação do Python.

Os argumentos básicos de 2to3 são uma lista de arquivos ou diretórios a serem transformados. Os diretórios são recursivamente percorridos pelos fontes Python.

Aqui temos um exemplo de arquivo fonte Python 2.x, `example.py`:

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

O mesmo pode ser convertido para código Python 3.x através de 2to3 através da linha de comando:

    $ 2to3 example.py

É impresso um diff contra o arquivo original. O 2to3 também pode escrever as modificações necessárias de volta ao arquivo de origem. (Um backup do arquivo original sempre será feito, salvo se a opção: `-n` for utilizada.) Escrever as alterações de volta está disponível com o uso do flag `-w` flag:

    $ 2to3 -w example.py

Após a transformação, o arquivo `example.py` se parecerá com isso:

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

Os comentários e a indentação são preservados ao longo do processo de tradução.

Por padrão, 2to3 executa um conjunto de predefined fixers. A opção de flag `-l` lista todos os fixers disponíveis. Um conjunto explícito de fixers para executação pode ser fornecido com a opção: `-f`. Da mesma forma, a opção `-x` desabilita explicitamente um fixers. O exemplo a seguir executa apenas os fixadores `imports` e `has_key`:

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

Este comando executa todos os fixers, exceto o fixers `apply`:

    $ 2to3 -x apply example.py

Alguns fixers são explícitos, o que significa que eles não são executados por padrão e devem estar listados na linha de comando a para serem executados. Aqui, além dos fixers padrão, o fixers `idioms` também será executado:

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

Observe como a passagem de `all` permite todos os fixers padrão.

Às vezes, 2to3 encontrará um lugar em seu código-fonte que precisa ser alterado, mas o 2to3 não pode corrigir automaticamente. Nesse caso, o 2to3 imprimirá um aviso abaixo do diff para um arquivo. Você deve endereçar o aviso para ter o código 3.x compatível.

O 2to3 também pode refatorar o doctests. Para ativar este modo, use o flag `-d`. Observe que os doctests somente serão refatorados. Isso também não exige que o módulo Python seja válido. Por exemplo, os exemplos doctest como em um documento reST também podem ser refatorados com esta opção.

A opção `-v` permite a saída de mais informações sobre o processo de tradução.

Uma vez que algumas declarações de impressão podem ser analisadas como chamadas de função ou declarações, 2to3 nem sempre pode ler arquivos que contêm a função de impressão. Quando 2to3 detecta a presença da diretiva de compilação `from __future__ import print_function`, ele modifica sua gramática interna para interpretar funções `print()` como uma função. Esta alteração também pode ser ativada manualmente com o flag `-p`. Use o flag `-p` para executar fixadores no código que já tiveram suas declarações impressas convertidas.

A opção `-o` ou `--output-dir` permite especificar um diretório alternativo para a escrita dos arquivos de saída processados. A flag `-n` é necessária ao usá-lo como arquivos de backup, não faz sentido quando não está sobrescrevendo os arquivos de entrada.

Novo na versão 2.7.3: A opção `-o` foi adicionada.

A flag `-W` ou `--write-unchanged-files`diz ao 2to3 para sempre salvar arquivos de saída, mesmo que nenhuma alteração tenha sido necessária no arquivo. Isso é mais útil com: :option:`!-o`, de modo que uma árvore de código Python inteiro é copiada com a tradução de um diretório para outro. Esta opção implica o uso da flag `-w`, pois não faria sentido de outro modo.

Novo na versão 2.7.3: A opção cujo flag é `-W` foi adicionada.

A opção `--add-suffix` determina a string que será adicionada a todos os nomes de arquivos. O flag da opção `-n` é necessário quando especificamos isso, pois os backups não são necessários quando escrevemos em nomes de arquivos diferentes. Por exemplo:

    $ 2to3 -n -W --add-suffix=3 example.py

Resultará num arquivo convertido de nome `example.py3` a ser escrito.

Novo na versão 2.7.3: A opção `--add-suffix` foi adicionada.

Para traduzir um projeto inteiro de uma árvore de diretório para outra, use:

    $ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode

## 25.4.2. Fixers

Cada passo de transformação do código é encapsulado em um fixer. O comando `2to3 -l` lista todos. Assim como documented above, cada um pode ser ativado ou desativado individualmente. Eles são descritos aqui com mais detalhes.

`apply`

  Remove o uso de `apply()`. Por exemplo `apply(function, *args, **kwargs)` é convertido para `function(*args, **kwargs)`.

`asserts`

  Substitui o nome de método descontinuado `unittest` pelo nome correto.

  De | Para
  --- | ---
  `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`

  Converte a classe `basestring` para a classe `str`.

`buffer`

  Converte a classe `buffer` para `memoryview`. Este fixers é opcional porque a a API da classe `memoryview` é semelhante, mas não exatamente a mesma que a da classe `buffer`.

`dict`

  Corrige os métodos de iteração de dicionário. `dict.iteritems()` é convertido para `dict.items()`, `dict.iterkeys()` para `dict.keys()`, e `dict.itervalues()` para `dict.values()`. Similarmente temos o método, `dict.viewitems()`, `dict.viewkeys()` e `dict.viewvalues()` que são convertidos respectivamente para `dict.items()`, `dict.keys()` e `dict.values()`. Também encapsula os usos existentes de `dict.items()`, `dict.keys()`, e `dict.values()` em uma chamada para `list`.

`except`

  Converte `except X, T` para `except X as T`.

`exec`

  Converts the `exec` statement to the `exec()` function.

`execfile`

  Remove o uso da função `execfile()`. O argumento para `execfile()` é encapsulado pelas funções `open()`, `compile()`, e `exec()`.

`exitfunc`

  Mudança de declaração de `sys.exitfunc` para usar o módulo `atexit`.

`filter`

  Encapsula a função `filter()` usando uma chamada para a classe `list`.

`funcattrs`

  Corrige atributos de funções que foram renomeados. Por exemplo, `my_function.func_closure` é convertido para `my_function.__closure__`.

`future`

  Remove a declaração `from __future__ import new_feature`.

`getcwdu`

  Renomeia a função `os.getcwdu()` para `os.getcwd()`.

`has_key`

  Modifica `dict.has_key(key)` para `key in dict`.

`idioms`

  Este fixer opcional executa várias transformações que tornam o código Python mais idiomático. Comparações de tipo como `type(x) is SomeClass` e `type(x) == SomeClass` são convertidas para `isinstance(x, SomeClass)`. `while 1` vira `while True`. Este fixer também tenta usar `sorted()` nos lugares apropriados. Por exemplo, este bloco

      L = list(some_iterable)
      L.sort()

  é alterado para:

      L = sorted(some_iterable)

`import`

  Detecta importações de irmãos e as converte em importações relativas.

`imports`

  Muda o nome do módulo na biblioteca padrão.

`imports2`

  Lida com outras renomeações de módulos na biblioteca padrão. É separado do fixer `imports` apenas por causa de limitações técnicas.

`input`

  Converte `input(prompt)` para `eval(input(prompt))`.

`intern`

  Converte a função `intern()` para `sys.intern()`.

`isinstance`

  Fixes duplicate types in the second argument of `isinstance()`. For example, `isinstance(x, (int, int))` is converted to `isinstance(x, (int))`.

`itertools_imports`

  Remove importações de `itertools.ifilter()`, `itertools.izip()`, e `itertools.imap()`. Importações de `itertools.ifilterfalse()` também são alteradas para `itertools.filterfalse()`.

`itertools`

  Altera o uso de `itertools.ifilter()`, `itertools.izip()`, e `itertools.imap()` para os seus equivalentes embutidos. `itertools.ifilterfalse()` é alterado para `itertools.filterfalse()`.

`long`

  Renomeia a classe `long` para `int`.

`map`

  Encapsula a função `map()` numa chamada a classe `list`. Isso também altera `map(None, x)` para `list(x)`. Usando `from future_builtins import map` desabilitará esse fixers.

`metaclass`

  Converte a sintaxe da metaclasse antiga (`__metaclass__ = Meta` in the class body) para o novo formato (`class X(metaclass=Meta)`).

`methodattrs`

  Corrige nomes de atributos de métodos antigos. Por exemplo `meth.im_func` é convertido para `meth.__func__`.

`ne`

  Converte a sintaxe antiga “diferente”, `<>`, para `!=`.

`next`

  Converts the use of iterator’s `next()` methods to the `next()` function. It also renames `next()` methods to `__next__()`.

`nonzero`

  Renomeia o méotdo `__nonzero__()` para `__bool__()`.

`numliterals`

  Converte os literais octal para a nova sintaxe.

`paren`

  Adiciona parênteses onde os mesmos não eram necessários em lista comprehensions. Por exemplo, `[x for x in 1, 2]` becomes `[x for x in (1, 2)]`.

`print`

  Converts the `print` statement to the `print()` function.

`raise`

  Converts `raise E, V` to `raise E(V)`, and `raise E, V, T` to `raise E(V).with_traceback(T)`. If `E` is a tuple, the translation will be incorrect because substituting tuples for exceptions has been removed in Python 3.

`raw_input`

  Converte a função `raw_input()` para `input()`.

`reduce`

  Manipula o movimento de `reduce()` para `functools.reduce()`.

`renames`

  Altera o `sys.maxint` para `sys.maxsize`.

`repr`

  Substitui o backtick repr pela função `repr()`.

`set_literal`

  Substitui o uso da classe `set` construtor pelo seu literal. Este fixers é opcional.

`standarderror`

  Renomeia `StandardError` para `Exception`.

`sys_exc`

  Altera os descontinuados `sys.exc_value`, `sys.exc_type`, `sys.exc_traceback` para utilizar agora a função `sys.exc_info()`.

`throw`

  Corrige a mudança de API no método gerador `throw()`.

`tuple_params`

  Remove o desempacotamento implícito do parâmetro da tupla. Este fixers insere variáveis temporárias.

`types`

  Corrige o código quebrado pela remoção de alguns membros no módulo `types`.

`unicode`

  Renomeia a classe `unicode` para `str`.

`urllib`

  Manipula a renomeação dos módulos `urllib` e `urllib2` para o pacote `urllib`.

`ws_comma`

  Remove o espaço excessivo de itens separados por vírgulas. Este fixers é opcional.

`xrange`

  Renomeia a função `xrange()` para `range()` e encapsula a chamada para função existente `range()` com `list`.

`xreadlines`

  Altera de `for x in file.xreadlines()` para `for x in file`.

`zip`

  Encapsula o uso da função `zip()` na chamada a classe `list`. Isso está desativado quando `from future_builtins import zip` aparecer.

## 25.4.3. `lib2to3` - biblioteca 2to3’s

Nota

A API do módulo `lib2to3` deve ser considerado instável e pode mudar drasticamente no futuro.