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 :ref:`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 obsoleto 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 incorporados. 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 o obsoleto 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.