Como baixar e usar 2to3.py para converter código Python 2 em Python 3
Se você é um desenvolvedor Python, pode ter encontrado o desafio de migrar seu código do Python 2 para o Python 3. O Python 2 não é mais suportado desde janeiro de 2020, e o Python 3 oferece muitas melhorias e novos recursos que o tornam mais poderoso, expressivo e moderno. No entanto, existem algumas diferenças significativas entre as duas versões que podem impedir que seu código seja executado sem problemas em ambas. Isso e onde 2to3.py vem a calhar.
O que é 2to3.py e por que você precisa dele?
2to3.py é um programa Python que lê o código-fonte Python 2.x e aplica uma série de fixadores para transformá-lo em código Python 3.x válido. Faz parte do lib2to3 biblioteca, que fornece uma estrutura genérica para transformações de origem para origem. 2to3.py pode lidar com a maioria das alterações comuns de sintaxe e semântica entre as duas versões, como instruções de impressão, divisão de número inteiro, tratamento de exceção, literais Unicode e muito mais. Ele também pode refatorar doctests, que são sessões interativas do Python incorporadas em docstrings ou comentários.
download 2to3.py
Você precisa de 2to3.py se tiver código Python 2 herdado que deseja migrar para Python 3 ou se quiser aprender a escrever código compatível para ambas as versões. Embora existam algumas ferramentas e técnicas que podem ajudá-lo a escrever código que roda tanto no Python 2 quanto no Python 3 (como seis, futuro, e __futuro__ importações), podem não abranger todos os casos ou podem introduzir alguma sobrecarga ou complexidade. Usar 2to3.py pode ajudá-lo a fazer uma transição limpa para o Python 3 e aproveitar seus novos recursos e benefícios.
Como baixar 2to3.py
2to3.py geralmente é instalado com o interpretador Python como um script. Você pode encontrá-lo no scripts diretório de sua instalação do Python (por exemplo, C:\Python39\Scripts no Windows). Você também pode executá-lo como um módulo usando o -m sinalizador (por exemplo, `python -m lib2to3`).
Você também pode encontrar 2to3.py no Ferramentas/scripts diretório da raiz do Python. Você pode baixar a versão mais recente do Python no site oficial e extrair o arquivo zip para acessar o script. Alternativamente, você pode clonar o repositório Python do GitHub e navegar até a pasta Tools/scripts.
Outra opção é instalar 2to3.py com pip executando `pip install 2to3`. Isso fará o download e instalará o script do PyPI, o Python Package Index. Você pode executá-lo a partir de qualquer diretório digitando `2to3` em seu console.
Como usar 2to3.py
Para usar 2to3.py, você precisa abrir um console (cmd se for Windows) e executar o script com os argumentos apropriados. Os argumentos básicos são uma lista de arquivos ou diretórios a serem transformados. Por exemplo, se você tiver um arquivo chamado exemplo.py que contém o código Python 2, você pode executar `python 2to3.py exemplo.py` para ver quais alterações seriam feitas para convertê-lo em Python 3. A saída será uma comparação com o arquivo fonte original, mostrando as linhas que seriam adicionadas (+) ou excluídas (-). Por exemplo:
$ python 2to3.py example.py RefactoringTool: Ignorando o corretor implícito: buffer RefactoringTool: Ignorando o corretor implícito: expressões idiomáticas RefactoringTool: Ignorando o corretor implícito: set_literal RefactoringTool: Ignorando o corretor implícito: ws_comma --- example.py (original) +++ example.py (refatorado) @@ -1,7 +1,7 @@ # Um exemplo simples de código Python 2 -print "Hello, world!" +print("Olá, mundo!") -def cumprimentar(nome): - imprimir "Olá, %s!" % nome +def cumprimentar(nome):+ + print("Olá, %s!" % nome) cumprimentar("Alice") -greet nome="Bob" +greet(nome="Bob")
Se você deseja aplicar as alterações ao arquivo de origem, você precisa usar o -c sinalizador, que permite o write-back. Isso modificará o arquivo original e criará um backup com uma extensão .bak (a menos que você também use o -n sinalizador, que desativa o backup). Por exemplo:
$ python 2to3.py -w example.py RefactoringTool: Ignorando o fixador implícito: buffer RefactoringTool: Ignorando o fixador implícito: expressões idiomáticas RefactoringTool: Ignorando o fixador implícito: set_literal RefactoringTool: Ignorando o fixador implícito: ws_comma RefactoringTool: Refatorado example.py --- example.py (original) +++ example.py (ref atored) @@ -1,7 +1,7 @@ # Um exemplo simples de Python 2 código -print "Olá, mundo!" +print("Olá, mundo!") -def cumprimentar(nome): - imprimir "Olá, %s!" % name +def greet(name):+ + print("Olá, %s!" % name) greet("Alice") -greet name="Bob" +greet(name="Bob") RefactoringTool: Arquivos que precisam ser modificados: RefactoringTool: example.py
Você também pode especificar um diretório em vez de um arquivo, e 2to3.py converterá recursivamente todos os arquivos .py nesse diretório. Você pode usar o --output-dir opção para especificar um diretório diferente para os arquivos de saída, em vez de sobrescrever os originais. Por exemplo:
$ python 2to3.py --output-dir=python3-version/mycode -W -n python2-version/mycode RefactoringTool: Ignorando o corretor implícito: buffer RefactoringTool: Ignorando o corretor implícito: expressões idiomáticas RefactoringTool: Ignorando o corretor implícito: set_literal RefactoringTool: Ignorando o corretor implícito: ws_comma RefactoringTool: Refatorado python2-version/mycode/example.py --- python2-version/mycode/example.py (original) +++ python3-version/mycode/example.py (refatorado) @@ -1,7 +1,7 @@ # Um exemplo simples de código Python 2 -print "Hello, world!" +print("Olá, mundo!") -def cumprimentar(nome): - imprimir "Olá, %s!" % name +def greet(name):+ + print("Hello, %s!" % name) greet("Alice") -greet name="Bob" +greet(name="Bob") RefactoringTool: Arquivos que foram modificados: RefactoringTool: python2-version/mycode/example.py
2to3.py tem muitas opções e sinalizadores que você pode usar para personalizar o processo de conversão. Aqui estão alguns dos mais úteis:
O -eu sinalizador lista todos os fixadores disponíveis. Os fixadores são os módulos que executam as transformações reais no código.Existem mais de 40 fixadores em 2to3.py, abrangendo vários aspectos da sintaxe e semântica do Python. Por exemplo:
$ python 2to3.py -l Transformações disponíveis para a opção -f/--fix: apply asserts basestring buffer callable dict except exec execfile exitfunc filter funcattrs future getcwdu has_key idioms import imports2 imports3 index input intern isinstance itertools_imports itertools_methods keys long map metaclass methodattrs ne next nonzero numliterals operator parenthesize print raise raw_in colocar reduzir recarregar renomear repr set_literal standarderror sys_exc lançar tuple_params tipos unicode urllib ws_comma xrange xreadlines zip
O -f sinalizador especifica um conjunto explícito de fixadores a serem executados. Você pode usar esta opção para limitar o escopo da conversão ou focar em problemas específicos. Por exemplo, se você deseja apenas converter as instruções de impressão e a divisão inteira, você pode executar `python 2to3.py -f print -f division example.py`.
O -x sinalizador desativa explicitamente um fixador. Você pode usar esta opção para excluir alguns fixadores que não deseja aplicar ou que podem causar problemas. Por exemplo, se você quiser manter as classes de estilo antigo e não usar as classes de estilo novo, você pode executar `python 2to3.py -x class example.py`.
O -d sinalizador permite a refatoração de doctests. Doctests são sessões Python interativas incorporadas em docstrings ou comentários e podem conter código Python 2 que também precisa ser convertido. Por padrão, 2to3.py não toca doctests, mas você pode usar esse sinalizador para incluí-los na conversão. Por exemplo, se você tiver um arquivo chamado teste.py que contém doctests, você pode executar `python 2to3.py -d test.py` para ver as mudanças.
O -v sinalizador permite a saída de mais informações sobre o processo de tradução. Você pode usar esta opção para ver mais detalhes sobre o que o 2to3.py está fazendo, como os nomes dos fixadores, o número de arquivos e linhas processados e o tempo gasto.Por exemplo, se você executar `python 2to3.py -v example.py`, verá algo assim:
$ python 2to3.py -v example.py RefactoringTool: Não é possível gravar backups para vários arquivos sem diretório de saída RefactoringTool: Ignorando o corretor implícito: buffer RefactoringTool: Ignorando o corretor implícito: expressões idiomáticas RefactoringTool: Ignorando o corretor implícito: set_literal RefactoringTool: Ignorando o corretor implícito: ws_comma RefactoringTool: Refatorado example.py --- example.py (original) +++ example.py (refatorado) @@ -1,7 +1,7 @@ # Um exemplo simples de código Python 2 -print "Hello, world!" +print("Olá, mundo!") -def cumprimentar(nome): - imprimir "Olá, %s!" % name +def greet(name):+ + print("Hello, %s!" % name) greet("Alice") -greet name="Bob" +greet(name="Bob") RefactoringTool: Arquivos que precisam ser modificados: RefactoringTool: example.py RefactoringTool: Warnings/messages while refatoring: RefactoringTool: ### In file example.py ### RefactoringTool: Line 8: You should use a for loop here Fixing: print Appli ed fixer: lib2to3.fixes.fix_print Fixing: execfile Applied fixer: lib2to3.fixes.fix_execfile Fixing: Applied fixer: lib2to3.fixes.fix_ne Fixing: apply Applied fixer: lib2to3.fixes.fix_apply Fixing: except Applied fixer: lib2to3.fixes.fix_except Fixing: dict.has_key() -> key in dict Corretor aplicado: lib2to3.fixes.fix_has_key Fixação: basestring -> str Corretor aplicado: lib2to3.fixes.fix_basestring Fixação: unicode -> str Corretor aplicado: lib2to3.fixes.fix_unicode Fixação: long -> int Fixador aplicado: lib2to3.fixes.fix_long Fixação: xrange -> range Fixador aplicado: lib 2to3.fixes.fix_xrange Fixação: operator.isCallable() -> callable() Fixador aplicado: lib2to3.fixes.fix_callable Fixação: operator.sequenceIncludes() -> operator.contains() Fixador aplicado: lib2to3.fixes.fix_operator Fixação: itertools.(imapifilterizip) -> (mapfilterzip) e import itertools App lied fixer: lib2to3.fixes.fix_itertools_imports Fixação: itertools.ifilterfalse -> itertools.filterfalse e import itertools Fixador aplicado: lib2to3.fixes.fix_itertools Fixação: repr -> ascii Fixador aplicado:lib2to3.fixes.fix_repr Correção: a descompactação do parâmetro tupla foi removida em 3 Fixador aplicado: lib2to3.fixes.fix_tuple_params Correção: sys.maxint -> sys.maxsize Fixador aplicado: lib2to3.fixes.fix_sys_exc Fixação: StandardError -> Exceção Fixador aplicado: lib2to3.fixes.fix_standarderror Fixação : aumentar X, Y -> aumentar X(Y) Fixador aplicado: lib2to3.fixes.fix_raise Fixação: func.func_* -> func.__*__ Fixador aplicado: lib2to3.fixes.fix_funcattrs Fixação: obj.__nonzero__() -> obj.__bool__() Fixador aplicado: lib2to3.fixes.fix_nonzero Fixação: import ur llib -> from urllib.request import urlopen Corretor aplicado: lib2to3.fixes.fix_urllib RefactoringTool: refatorou 1 arquivo em 0,1 segundos.
Exemplos de uso de 2to3.py
Nesta seção, mostraremos alguns exemplos de uso de 2to3.py para converter diferentes tipos de código Python 2 para Python 3. Usaremos a tabela a seguir para resumir os arquivos de entrada e saída, o comando usado e as principais alterações aplicadas.
Arquivo de entrada
Arquivo de saída
Comando
Principais mudanças
exemplo.py
exemplo.py (modificado)
python 2to3.py -w -n exemplo.py
declarações de impressão, formatação de string, argumentos de palavra-chave
python2-version/mycode (diretório)
python3-version/mycode (diretório)
python 2to3.py --output-dir=python3-version/mycode -W -n python2-version/mycode
todos os fixadores aplicados recursivamente
exemplo.py
(saída diferencial)
python 2to3.py -f imports -f has_key example.py
apenas importações e fixadores has_key
Exemplo 1: Convertendo um único arquivo com write-back e sem backup
Neste exemplo, temos um arquivo chamado exemplo.py que contém algum código Python 2 simples. Queremos convertê-lo para Python 3 e sobrescrever o arquivo original, sem criar um backup. Usamos o comando `python 2to3.py -w -n example.py` para fazer isso. A saída será um diff contra o arquivo de origem original e um modificado exemplo.py arquivo. Aqui está o conteúdo dos arquivos de entrada e saída:
# Arquivo de entrada: example.py # Um exemplo simples de código Python 2 print "Hello, world!" def cumprimentar(nome): print "Olá, %s!" % nome cumprimentar("Alice") cumprimentar nome="Bob"
# Arquivo de saída: example.py # Um exemplo simples de código Python 2 print("Hello, world!") def greet(name): print("Hello, %s!" % name) greet("Alice") greet(name="Bob")
As principais alterações aplicadas são:
As instruções de impressão foram convertidas em funções de impressão adicionando parênteses.
A formatação da string foi convertida para usar o método de formato de novo estilo, substituindo o operador % por .format().
Os argumentos de palavra-chave foram convertidos para usar o sinal = em vez do espaço.
Exemplo 2: Convertendo um projeto inteiro de uma árvore de diretório para outra
Neste exemplo, temos um diretório chamado python2-version/mycode que contém vários arquivos e subdiretórios do Python 2. Queremos convertê-los todos para Python 3 e criar uma nova árvore de diretório chamada python3-version/mycode. Usamos o comando `python 2to3.py --output-dir=python3-version/mycode -W -n python2-version/mycode` para fazer isso. A saída será uma nova árvore de diretórios com arquivos convertidos. Aqui está uma representação simplificada das árvores de diretórios de entrada e saída:
# Árvore do diretório de entrada: python2-version/mycode mycode/ main.py utils.py tests/ test_main.py test_utils.py
# Árvore do diretório de saída: python3-version/mycode mycode/ main.py utils.py tests/ test_main.py test_utils.py
As principais alterações aplicadas são:
Todos os fixadores foram aplicados recursivamente a todos os arquivos e subdiretórios.
Os arquivos de saída foram gravados em uma nova árvore de diretórios, preservando a estrutura original.
Nenhum backup foi criado e nenhum aviso foi exibido.
Exemplo 3: Convertendo apenas as importações e fixadores has_key
Neste exemplo, temos um arquivo chamado exemplo.py que contém algum código Python 2 que usa alguns módulos e métodos obsoletos.Queremos converter apenas as importações e os fixadores has_key e ver a saída do diff sem modificar o arquivo original. Usamos o comando `python 2to3.py -f imports -f has_key example.py` para fazer isso. A saída será uma comparação com o arquivo de origem original. Aqui está o conteúdo dos arquivos de entrada e saída:
# Arquivo de entrada: exemplo.py # Um exemplo simples de código Python 2 que usa módulos e métodos obsoletos import urllib2 import cPickle as pickle data = "name": "Alice", "age": 25 response = urllib2.urlopen(" data=pickle.dumps(data)) content = response.read() if response.headers.has_key("Content-Type"): print "Content-Type:", response.headers["Tipo de conteúdo"]
# Arquivo de saída: (diff) RefactoringTool: Ignorando o fixador implícito: buffer RefactoringTool: Ignorando o fixador implícito: expressões idiomáticas RefactoringTool: Ignorando o fixador implícito: set_literal RefactoringTool: Ignorando o fixador implícito: ws_comma --- example.py (original) +++ example.py (refactored) @@ -1,7 +1,8 @@ # Um exemplo simples de código Python 2 que usa módulos e métodos obsoletos -import urllib2 -im port cPickle as pickle +import urllib.request, urllib.error, urllib.parse +import pickle data = "name": "Alice", "age": 25 -response = urllib2.urlopen(" data=pickle.dumps(data)) +response = urllib.request.urlopen(" data=pickle.dump s(data)) content = response.read() -if response.headers.has_key("Content-Type"): +if "Content-Type" in response.headers: print "Content-Type:", response.headers["Content-Type"]
As principais alterações aplicadas são:
O consertador de importações substituiu os módulos obsoletos urllib2 e cPickle por seus equivalentes do Python 3, urllib e pickle. Ele também adicionou os submódulos necessários de urllib, como request, error e parse.
O fixador has_key substituiu o método has_key dos dicionários pelo operador in, que é mais legível e eficiente.
Limitações e advertências do uso de 2to3.py
Embora 2to3.py seja uma ferramenta muito útil para converter código Python 2 em Python 3, não é perfeito e não pode corrigir todas as incompatibilidades entre as duas versões. Algumas alterações podem exigir intervenção ou teste manual, e alguns consertadores podem introduzir bugs ou alterar a semântica do código. Aqui estão algumas limitações e avisos do uso de 2to3.py:
Alguns recursos do Python 2 não são suportados no Python 3, como apply, execfile, long, reload, coerce, cmp etc. Você precisará reescrever ou remover esses recursos do seu código manualmente.
Alguns recursos do Python 3 não estão disponíveis no Python 2, como async/await, f-strings, type annotations, walrus operator etc.
Algumas bibliotecas ou módulos podem não ser compatíveis com ambas as versões ou podem ter APIs diferentes. Por exemplo, alguns módulos de biblioteca padrão foram renomeados ou reorganizados no Python 3 (como urllib, configparser, tkinter), algumas bibliotecas de terceiros abandonaram o suporte para Python 2 (como Django, NumPy, pandas) e algumas bibliotecas mudaram seu comportamento ou funcionalidade (como solicitações, BeautifulSoup). Você precisará verificar a documentação dessas bibliotecas e atualizar seu código de acordo.
Alguns reparadores podem introduzir bugs ou alterar a semântica do código. Por exemplo, o ditado fixer pode alterar a ordem de iteração nos dicionários, o que pode afetar a lógica do seu programa. O unicode fixer pode alterar o tipo de strings de bytes para unicode, o que pode afetar a codificação ou decodificação de seus dados. Você precisará testar seu código com cuidado e garantir que ele funcione conforme o esperado.
Conclusão
2to3.py é uma ferramenta útil para converter código Python 2 em Python 3. Ele pode lidar com a maioria das alterações comuns de sintaxe e semântica entre as duas versões e também pode refatorar doctests. Ele tem muitas opções e sinalizadores que permitem personalizar o processo de conversão e também pode gerar diffs ou gravar de volta as alterações nos arquivos de origem. No entanto, 2to3.py não é perfeito e não pode corrigir todas as incompatibilidades entre Python 2 e Python 3. Algumas alterações podem exigir intervenção ou teste manual, e alguns corretivos podem introduzir bugs ou alterar a semântica do código. Portanto, você deve sempre verificar a documentação de 2to3.py e as bibliotecas que usa e testar seu código completamente antes de implantá-lo.
perguntas frequentes
Aqui estão algumas perguntas frequentes sobre 2to3.py:
P: Como posso executar 2to3.py em vários arquivos de uma só vez?
R: Você pode usar um curinga (*) para corresponder a vários arquivos com a mesma extensão ou pode especificar um diretório para converter recursivamente todos os arquivos .py nesse diretório. Por exemplo, `python 2to3.py -w *.py` converterá todos os arquivos .py no diretório atual e `python 2to3.py -w mycode` converterá todos os arquivos .py no diretório mycode e seus subdiretórios.
P: Como posso desfazer as alterações feitas por 2to3.py?
R: Se você usou o sinalizador -w sem o sinalizador -n, 2to3.py criará um arquivo de backup com uma extensão .bak para cada arquivo modificado. Você pode restaurar o arquivo original renomeando ou copiando o arquivo de backup. Se você usou o sinalizador -n ou não usou o sinalizador -w, precisará reverter manualmente as alterações ou usar um sistema de controle de versão para restaurar a versão anterior do seu código.
P: Como posso escrever um código que seja executado tanto no Python 2 quanto no Python 3?
R: Existem algumas ferramentas e técnicas que podem ajudá-lo a escrever código que pode ser executado tanto no Python 2 quanto no Python 3, como six, future e __future__ imports. No entanto, eles podem não cobrir todos os casos ou podem introduzir alguma sobrecarga ou complexidade.Você também pode precisar usar diferentes bibliotecas ou módulos, dependendo da versão do Python que estiver usando. Você pode verificar este guia para obter mais informações sobre como escrever código compatível para ambas as versões.
P: Como posso aprender mais sobre 2to3.py?
R: Você pode ler a documentação oficial do 2to3.py aqui, que explica como usá-lo e quais corretivos estão disponíveis. Você também pode ler este tutorial sobre como usar 2to3.py com exemplos. Você também pode verificar esta postagem no blog sobre como migrar seu código do Python 2 para o Python 3 com 2to3.py.
P: Como posso obter ajuda ou relatar problemas com 2to3.py?
R: Você pode fazer perguntas ou relatar problemas com 2to3.py no Stack Overflow, usando as tags python-2.x, python-3.xe 2to3. Você também pode relatar bugs ou sugerir melhorias no rastreador de problemas do Python, usando o componente Library (Lib) e a palavra-chave lib2to3.
0517a86e26
Comments