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 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

   Converte a "exec" declaração para a função "exec()".

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

   Corrige tipos duplicados no segundo argumento de "isinstance()".
   Por exemplo, "isinstance(x, (int, int))" é convertido para
   "isinstance(x, int)" e "isinstance(x, (int, float, int))" é
   convertido para "isinstance(x, (int, float))".

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

   Converte o uso de métodos de iterador "next()" para a função
   "next()". Também renomeia métodos "next()" 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 "operator" module to
   other, but equivalent, function calls.  When needed, the
   appropriate "import" statements 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)]".

print

   Converte a declaração "print" para a função "print()".

raise

   Converte "raise E, V" para "raise E(V)", e "raise E, V, T" para
   "raise E(V).with_traceback(T)".  Se "E" for uma tupla, a tradução
   ficará incorreta porque a substituição de tuplas por exceções foi
   removida no Python 3x.

raw_input

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

reduce

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

reload

   Converte a função "reload()" para "imp.reload()".

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.


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.
