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 exemploapply(function, *args, **kwargs)
é convertido parafunction(*args, **kwargs)
.
-
asserts
¶ Substitui o nome de método obsoleto
unittest
pelo 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)
-
basestring
¶ Converte a classe
basestring
para a classestr
.
-
buffer
¶ Converte a classe
buffer
paramemoryview
. 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, T
paraexcept X as T
.
-
execfile
¶ Remove o uso da função
execfile()
. O argumento paraexecfile()
é encapsulado pelas funçõesopen()
,compile()
, eexec()
.
-
exitfunc
¶ Mudança de declaração de
sys.exitfunc
para usar o móduloatexit
.
-
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 SomeClass
etype(x) == SomeClass
são convertidas paraisinstance(x, SomeClass)
.while 1
virawhile 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
imports
apenas por causa de limitações técnicas.
-
input
¶ Converte
input(prompt)
paraeval(input(prompt))
.
-
isinstance
¶ Fixes duplicate types in the second argument of
isinstance()
. For example,isinstance(x, (int, int))
is converted toisinstance(x, (int))
.
-
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 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 parameth.__func__
.
-
ne
¶ Converte a sintaxe antiga “diferente”,
<>
, para!=
.
-
next
¶ Converts the use of iterator’s
next()
methods to thenext()
function. It also renamesnext()
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)]
.
-
raise
¶ Converts
raise E, V
toraise E(V)
, andraise E, V, T
toraise E(V).with_traceback(T)
. IfE
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()
parainput()
.
-
reduce
¶ Manipula o movimento de
reduce()
parafunctools.reduce()
.
-
renames
¶ Altera o
sys.maxint
parasys.maxsize
.
-
standarderror
¶ Renomeia
StandardError
paraException
.
-
sys_exc
¶ Altera o obsoleto
sys.exc_value
,sys.exc_type
,sys.exc_traceback
para 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
.