26.7. 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.
26.7.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 3.2.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 3.2.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 3.2.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
26.7.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 exemploapply(function, *args, **kwargs)é convertido parafunction(*args, **kwargs).
-
asserts¶ Substitui o nome de método obsoleto
unittestpelo nome correto.De
Para
failUnlessEqual(a, b)assertEquals(a, b)failIfEqual(a, b)assertNotEquals(a, b)failUnless(a)assert_(a)failIf(a)failUnlessRaises(exc, cal)failUnlessAlmostEqual(a, b)assertAlmostEquals(a, b)failIfAlmostEqual(a, b)assertNotAlmostEquals(a, b)
-
buffer¶ Converte a classe
bufferparamemoryview. Este fixers é opcional porque a a API da classememoryviewé semelhante, mas não exatamente a mesma que a da classebuffer.
-
dict¶ Corrige os métodos de iteração de dicionário.
dict.iteritems()é convertido paradict.items(),dict.iterkeys()paradict.keys(), edict.itervalues()paradict.values(). Similarmente temos o método,dict.viewitems(),dict.viewkeys()edict.viewvalues()que são convertidos respectivamente paradict.items(),dict.keys()edict.values(). Também encapsula os usos existentes dedict.items(),dict.keys(), edict.values()em uma chamada paralist.
-
except¶ Converte
except X, Tparaexcept X as T.
-
execfile¶ Remove o uso da função
execfile(). O argumento paraexecfile()é encapsulado pelas funçõesopen(),compile(), eexec().
-
funcattrs¶ Corrige atributos de funções que foram renomeados. Por exemplo,
my_function.func_closureé convertido paramy_function.__closure__.
-
future¶ Remove a declaração
from __future__ import new_feature.
-
getcwdu¶ Renomeia a função
os.getcwdu()paraos.getcwd().
-
has_key¶ Modifica
dict.has_key(key)parakey 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 SomeClassetype(x) == SomeClasssão convertidas paraisinstance(x, SomeClass).while 1virawhile True. Este fixer também tenta usarsorted()nos lugares apropriados. Por exemplo, este blocoL = 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
importsapenas por causa de limitações técnicas.
-
input¶ Converte
input(prompt)paraeval(input(prompt)).
-
intern¶ Converte a função
intern()parasys.intern().
-
isinstance¶ Corrige tipos duplicados no segundo argumento de
isinstance(). Por exemplo,isinstance(x, (int, int))é convertido paraisinstance(x, int)eisinstance(x, (int, float, int))é convertido paraisinstance(x, (int, float)).
-
itertools_imports¶ Remove importações de
itertools.ifilter(),itertools.izip(), eitertools.imap(). Importações deitertools.ifilterfalse()também são alteradas paraitertools.filterfalse().
-
itertools¶ Altera o uso de
itertools.ifilter(),itertools.izip(), eitertools.imap()para os seus equivalentes incorporados.itertools.ifilterfalse()é alterado paraitertools.filterfalse().
-
map¶ Encapsula a função
map()numa chamada a classelist. Isso também alteramap(None, x)paralist(x). Usandofrom future_builtins import mapdesabilitará esse fixers.
-
metaclass¶ Converte a sintaxe da metaclasse antiga (
__metaclass__ = Metain 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 parameth.__func__.
-
ne¶ Converte a sintaxe antiga “diferente”,
<>, para!=.
-
next¶ Converte o uso de métodos de iterador
next()para a funçãonext(). Também renomeia métodosnext()para__next__().
-
nonzero¶ Renomeia o méotdo
__nonzero__()para__bool__().
-
numliterals¶ Converte os literais octal para a nova sintaxe.
-
operator¶ Converts calls to various functions in the
operatormodule to other, but equivalent, function calls. When needed, the appropriateimportstatements are added, e.g.import collections. The following mapping are made:De
Para
operator.isCallable(obj)hasattr(obj, '__call__')operator.sequenceIncludes(obj)operator.contains(obj)operator.isSequenceType(obj)isinstance(obj, collections.Sequence)operator.isMappingType(obj)isinstance(obj, collections.Mapping)operator.isNumberType(obj)isinstance(obj, numbers.Number)operator.repeat(obj, n)operator.mul(obj, n)operator.irepeat(obj, n)operator.imul(obj, n)
-
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)].
-
raise¶ Converte
raise E, Vpararaise E(V), eraise E, V, Tpararaise E(V).with_traceback(T). SeEfor uma tupla, a tradução ficará incorreta porque a substituição de tuplas por exceções foi removida no Python 3x.
-
reduce¶ Manipula o movimento de
reduce()parafunctools.reduce().
-
reload¶ Converte a função
reload()paraimp.reload().
-
renames¶ Altera o
sys.maxintparasys.maxsize.
-
sys_exc¶ Altera o obsoleto
sys.exc_value,sys.exc_type,sys.exc_tracebackpara utilizar agora a funçãosys.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.
-
ws_comma¶ Remove o espaço excessivo de itens separados por vírgulas. Este fixers é opcional.
-
xrange¶ Renomeia a função
xrange()pararange()e encapsula a chamada para função existenterange()comlist.
-
xreadlines¶ Altera de
for x in file.xreadlines()parafor x in file.
26.7.3. lib2to3 - biblioteca 2to3’s¶
Código Fonte: Lib/lib2to3/
Nota
A API do módulo lib2to3 deve ser considerado instável e pode mudar drasticamente no futuro.
