Para a conversão de código Python2 para Python3, qual versão do Python e Django é mais adequada?

11

Atualmente, estou trabalhando em uma grande empresa, na qual precisamos converter o grande projeto antigo do Django do python2 para a versão python3, por isso fiz muitas pesquisas relacionadas, mas ainda não consegui encontrar nenhuma resposta perfeita relacionada à versão do Python e Django mais adequada para a conversão.

Atualmente, estou usando Python: 2.7.16 e Django: 1.9.13 na minha versão antiga.

Qualquer pessoa pode me sugerir a versão mais adequada do Python e Django para a versão anterior para conversão python2 em python3.

Lua
fonte
A versão atual do python3 é o Python 3.8, e a versão mais recente do Django é o Django 3.0. O site do Django recomenda a versão mais recente do python 3 , que é 3.8. Existe uma razão específica para você não querer acelerar o python e o django para as versões mais recentes?
Green Cloak Guy
2
Curiosamente, eu percebi apenas alguns dias atrás que o site baseado no Django que eu tenho mantido por alguns anos agora é executado no servidor em que ele está hospedado usando python2.7, enquanto eu o localmente usando python3. 7) A única diferença que encontrei foi quando tentei usar f-strings em algum lugar pela primeira vez e a versão do servidor da web travou; caso contrário, ele estará sendo executado exatamente como o esperado (exatamente o mesmo) local e remotamente, para fins de teste e adição de recursos. Minha conclusão inteiramente anedótica é que o Django é geralmente compatível com a maioria das coisas.
Green Cloak Guy
11
para a versão mais recente, descobri que algumas pessoas não recomendam, porque na versão mais recente se houver algum problema relacionado a novas atualizações, será difícil encontrar soluções às vezes, portanto, no projeto atual, não quero correr esse tipo de risco e também para Para testar o teste, comecei a converter meu projeto para a versão mais recente do python 3.7.3 com o django mais recente e já encontrei 30 tipos de problemas.
Lua
Deve-se notar - essa pergunta surgiu em uma auditoria de revisão para mim. "Existe algum documento ou referência" é claramente fora do tópico (solicitando um recurso externo). No entanto, acredito que a pergunta poderia ser editada de modo a levar melhor à resposta aceita abaixo.
theMayer

Respostas:

3

Eu pensei em acrescentar um pouco à estratégia defendida pela resposta de Wim - obter a versão apropriada do Django trabalhando primeiro nos 2.7 e 3.x - e descrever algumas táticas que funcionaram para mim.

Python 2.7 é o seu pod de escape, até você pressionar o gatilho no 3.x

  • seus testes devem ser executados em ambos
  • não use nenhum recurso específico do 3.x, como strings-f
  • primeiro Python 3.x, depois apenas o Django 2.x que não roda no 2.7
  • comece cedo, não analise demais, mas evite a abordagem do big bang
    • arquivo por arquivo em primeiro lugar.
    • comece com o código de nível mais baixo, como bibliotecas de utilitários, para o qual você tem suítes de teste.
    • se possível, tente mesclar gradualmente suas alterações nas ramificações de produção 2.7 e mantenha seu código de portagem 3.x atualizado com as alterações de prod.

Qual versão menor do Django para começar?

Meu critério aqui é que as migrações do Django podem ser bastante envolvidas (e realmente requerem mais reflexão do que 2 => 3 trabalhos). Gostaria de passar para o 1.11 mais recente e melhor, dessa forma, você já está fornecendo algum valor aos seus usuários 2.7. Provavelmente, existe um bom número de calços de compatibilidade pré-2.x no 1.11 e você receberá seus avisos de descontinuação do 2.x.

Qual versão secundária do Python 3.x para começar?

É melhor considerar todos os ângulos, como a disponibilidade de suas bibliotecas de terceiros, o suporte do seu pacote CI / devops e a disponibilidade nas imagens do sistema operacional do servidor escolhido. Você sempre pode instalar o 3.8 e tentar instalar um pip dos seus requisitos.txt por si só, por exemplo.

Aproveite o git (ou qualquer outro scm que você use) e o virtualenv .

  • requirement.txtarquivos separados , mas ...
  • se você tiver um repositório git baseado em arquivo, poderá apontar cada venv para a mesma linha de código com a pip install -e <your directory>. isso significa que, em 2 terminais diferentes, você pode executar 2.7 e 3.x contra o (s) mesmo (s) mais (s).
  • você pode até rodar servidores Django 2.7 e 3.x lado a lado em portas diferentes e apontar, digamos, Firefox e Chrome para eles.
  • cometa frequentemente (pelo menos no ramo de portabilidade) e aprenda sobre o git bisect .

faça uso de 2to3

Sim, ele quebrará o código 2.7 e o Django, se você permitir. Assim...

  • execute-o no modo de visualização ou em um único arquivo. veja o que quebra, mas também veja o que fez certo.

  • acelere para apenas certas conversões que não quebram o 2.7 ou o Django. print x=> print (x)e except(Exception) as esão 2 não-intelectuais.

É assim que meu comando regulado era:

2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
  • execute-o arquivo por arquivo até que você esteja realmente confiante.

use sed ou awk em vez de seu editor para conversões em massa.

A vantagem é que, à medida que você se torna mais ciente das preocupações específicas de seus aplicativos, pode criar um conjunto de alterações que podem ser executadas em 1 arquivo ou em muitos arquivos e executar a maior parte do trabalho sem quebrar o 2.7 ou o Django. Aplique isso após o seu passe 2to3 adequadamente otimizado . Isso deixa você com limpezas residuais no seu editor e com a aprovação nos testes.

(opcional) comece a ficar preto no código 2.7.

black, que é um formatador de código, usa ASTs do Python 3 para executar sua análise. Ele não tenta executar o código, mas sinaliza erros de sintaxe que impedem que ele chegue ao estágio AST. Você terá que trabalhar com alguma mágica global de instalação de pip para chegar lá e precisará comprar a utilidade do preto.

Outras pessoas fizeram isso - aprenda com elas.

Ouvindo o número 155 As etapas práticas para mudar para o Python 3 devem lhe dar algumas idéias do trabalho. Veja os links do programa. Eles adoram falar sobre o movimento do Instagram (?) Que envolveu um ajuste gradual da execução do código 2.7 para a sintaxe 3.x em uma base de código comum e no mesmo ramo git, até o dia do acionamento.

Consulte também o Guia de portabilidade do Conservative Python 3

e Instagram fazem uma transição suave para Python 3 - The New Stack

Conclusão

Seu tempo para o Django 1.11 EOL (abril de 2020) é bastante curto, portanto, se você tiver mais de 2 recursos de desenvolvimento, considere fazer o seguinte em paralelo:

  • DEV # 1: inicie com um salto do Django 1.11 (a teoria é que o Django 1.11 provavelmente está melhor posicionado como um ponto de partida para o Django 2.x), usando 2.7.

  • DEV # 2: inicie no Python 3.6 / 3.7 do seu código utilitário não Django. Como o código é compatível com 2.7 neste ponto, mescle-o ao número 1 à medida que avança.

Veja como as duas tarefas prosseguem, avalie qual é o risco do projeto relacionado ao Django e qual é a aparência do Python 3. Você já está sentindo falta da EOL do Python 2.7, mas uma estrutura da Web obsoleta é provavelmente mais perigosa que o Python 2.7 herdado, pelo menos por alguns meses. Portanto, não esperaria muito tempo para começar a migrar para o Django 1.9 e seu trabalho não será desperdiçado. Conforme você vê o progresso, começará a ver melhor os riscos do projeto.

Seu progresso inicial de 2 a 3 será lento, mas as ferramentas e as orientações são boas o suficiente para você acelerar rapidamente, portanto, não pense demais antes de começar a reunir experiência. O lado do Django depende da sua exposição a mudanças no quadro, e é por isso que acho melhor começar cedo.

PS (opinião controversa / pessoal): Não usei muito seis ou outras bibliotecas de pontes 2 a 3 enlatadas.

É não porque eu não confiar nele - é brilhante para libs 3rd party - mas sim que eu não queria adicionar uma dependência permanente complexo (e eu estava com preguiça de ler seu doc). Eu estava escrevendo código 2.7 na sintaxe compatível com 3.x por um longo tempo, então não senti a necessidade de usá-los. Sua milhagem pode variar e não seguir esse caminho se parecer muito trabalhoso .

Em vez disso, criei um py223.py (57 LOC, incluindo comentários) com esse tipo de conteúdo, a maioria relacionada a soluções alternativas para reprovações e alterações de nome na biblioteca padrão.

try:
    basestring_ = basestring
except (NameError,) as e:
    basestring_ = str

try:
    cmp_ = cmp
except (NameError,) as e:
    # from http://portingguide.readthedocs.io/en/latest/comparisons.html
    def cmp_(x, y):
        """
        Replacement for built-in function cmp that was removed in Python 3
        """
        return (x > y) - (x < y)

Em seguida, importe desse py223 para solucionar essas preocupações específicas. Mais tarde, eu só vai abandonar a importação e mover aqueles estranho isinstance(x, basestr_)para isinstance(x, str)mas sei de antemão que há pouco para se preocupar.

JL Peyret
fonte
Bom conselho. Apenas uma observação, o próprio Django já usa sixpara a camada de compatibilidade; portanto, se você quiser usá-lo em um projeto Django durante a transição, isso não significa "adicionar uma dependência permanente complexa".
wim
@wim. Eu concordo com você re. seis, mas depende do ponto de vista. Eu já notei que ele vem com bibliotecas de terceiros, portanto, não "custa" em termos de requisitos e dependências gerais. no entanto, eu - talvez errado - considerei uma grande caixa preta / verruga no meio do meu código. se tudo o que você está fazendo é coisas como testar a string da instância / unicode / basestring e se você sabe fazer isso sozinho, sabe exatamente como recuperar seus shims quando eles não são mais necessários. Vou levar isso até o fim, no entanto.
JL Peyret
É pip install -e ...(com letras minúsculas -e), certo?
thebjorn
provavelmente é. irá corrigir
JL Peyret
3

Minha sugestão é atualizar primeiro para Django==1.11.26, que é a versão mais recente do Django que suporta o Python 2 e o Python 3. Continue na sua versão atual do Python 2.7 por enquanto.

Leia atentamente as notas de versão de 1.10.xe 1.11.x, verificando preterimentos e corrigindo qualquer coisa que tenha parado de funcionar no seu código 1.9.x. As coisas vão quebrar. O Django se move rápido. Para um projeto grande do Django, pode haver muitas alterações de código necessárias, e se você estiver usando muitos plugins ou bibliotecas de terceiros, poderá ser necessário manipular suas versões. Algumas de suas dependências de terceiros provavelmente foram totalmente abandonadas, portanto, é necessário encontrar substituições ou remover os recursos.

Para encontrar as notas de versão para cada atualização de versão, apenas pesquise no Google "O que há de novo no Django". Os hits documentam meticulosamente todas as deprecações e alterações:

Uma vez que o webapp parece estar funcionando bem no Django 1.11, com todos os testes de passagem (você fazer tem um conjunto de testes, certo?), Então você pode fazer a conversão Python 3, mantendo a versão Django o mesmo. O Django 1.11 suporta até Python 3.7, portanto essa seria uma boa versão para o seu destino. Espere unicode em todo o lugar, já que as conversões implícitas entre bytes e texto desapareceram agora e muitos webapps do Python 2 dependiam disso.

Quando o projeto parece estar funcionando bem no Django 1.11 e no Python 3.7, você pode pensar em atualizar para o Django 3.0, seguindo o mesmo processo de antes - lendo as notas de versão, fazendo as alterações necessárias, executando o conjunto de testes e fazendo check-out o webapp em um servidor dev manualmente.

wim
fonte
11
Definitivamente o caminho a percorrer. Faça com que seu código de teste seja executado tanto no 2.7 quanto no 3.x. Você pode ter 2 virtualenvs diferentes apontando para o mesmo repositório git pip install -E. Depois que os testes de unidade estiverem em execução, inicie o uso do Django-on-3x e mantenha o código funcionando em 2 e 3. Com algumas codificações cuidadosas e com cuidado para não queimar suas pontes de 2,7 - sem strings por exemplo - a alternância será muito anticlimático. Quando o 3.x estiver totalmente estável, comece a usar o código 3.x only. A vantagem é que a produção 2.7 está sempre na etapa até a troca.
JL Peyret
2

Eu atualizaria para py3 primeiro. Você precisará olhar no setup.pyrepositório do Django no branch stable / 1.9.x ( https://github.com/django/django/blob/stable/1.9.x/setup.py ) para descobrir que o py3 as versões suportadas são 3.4 (inativas) e 3.5.

Uma vez no py3.5 e no Django 1.9, você pode atualizar um de cada vez até chegar à versão em que deseja terminar. Por exemplo, o Django 1.11 suporta py3.5 e py3.7, então

py27/dj19 -> py35/dj19 -> py35/dj1.11 -> py37/dj1.11 ... -> py37/dj2.2

O dj2.2 é a primeira versão que suporta o py3.8, mas eu provavelmente pararia no py37 / dj2.2 se você estiver trabalhando em um ambiente normalmente conservador.

Se você tiver outros pacotes, precisará encontrar combinações de versões que funcionem juntas em cada etapa. Ter um plano é fundamental, e atualizar apenas um componente por vez geralmente acaba economizando seu tempo.

A futura biblioteca ( https://python-future.org/ ) o ajudará em muitas situações nojentas, enquanto você precisa de código para executar nos py27 e 3.x. seis também é ótimo. Eu evitaria rolar sua própria camada de compatibilidade (por que reinventar a roda?)

Se possível, tente obter uma cobertura de teste de unidade de 75 a 85% antes de iniciar e, definitivamente, configure o teste automático nas versões "de" e "para" para cada etapa da atualização. Certifique-se de ler e corrigir todos os avisos do Django antes de atualizar para a próxima versão - o Django se preocupa muito pouco com a compatibilidade com versões anteriores, então eu normalmente sugiro que você atinja todas as versões secundárias no caminho da atualização (ou pelo menos certifique-se de ler as "versões anteriores incompatibilidades "e listas de reprovação para cada versão secundária).

Boa sorte (estamos atualizando uma base de código 300 + Kloc de py27 / dj1.7 agora, então sinto sua dor ;-)

thebjorn
fonte
11
+1 na cobertura do teste. Essa é uma métrica chave aqui, qualquer que seja a abordagem que alguém acabe adotando. Realmente ajuda ao experimentar alterações difusas de código e estou dizendo isso como alguém que não é um aficionado pelo teste de TDD Vermelho / Verde. Descobrir uma maneira de basear seus resultados 2.7 e atualizar se torna muito mais fácil.
JL Peyret
2

Eu tenho o mesmo tipo de problema com o meu projeto e tentei o python 3.7.5 com o Django versão 2.2.7.

Você não deve usar a versão mais recente do python 3.8 ou a versão mais recente do Django 3.0, pois pode haver chances de que, para qualquer tipo de bug, você não consiga obter a solução adequada para as versões mais recentes.

Alpesh
fonte
Isso deve ser um comentário
Bruno em
-2

Você deve tentar filmar as versões atuais. Python 3.8 e Django 3.0. A biblioteca Six ajudará com algumas mudanças nas convenções. De qualquer maneira, você precisará refatorar para torná-lo atual.

Dave
fonte
3
Você já fez uma atualização do Django? Isso é apenas uma ilusão. Ir diretamente para Python 3.8 e Django 3.0 a partir de 2.7 / 1.9 será praticamente impossível. Mesmo atualizar versões menores como o Django 1.9 para 1.10 pode ser um processo difícil, com muitas alterações de código necessárias.
Wim
Sim, concordo que tive a aprovação de tempo e luxo para fazer um refator completo e atualizar o aplicativo. Mais uma vez o tamanho do aplicativo, lógica e limitações de tempo são um enorme problema para a maioria dos caras, mas eles nunca mencionou o tamanho do aplicativo ou restrição de tempo, então eu recomendei minha opinião de "melhor solução" ou "wishful thinking";)
Dave
Além disso, se você precisar se preocupar com as coisas do Ansible e rodando em um Ubuntu LTS, também encontrará o suporte para 3.7 na falta do Ubuntu 18.04. Os podcasts de segurança que eu ouço aconselham que o 3.8 se acalme um pouco até o lançamento do ponto ou 2. -1 para riscos desnecessários.
JL Peyret
Alguma boa recomendação de podcast de segurança?
Dave
Para Python sec, listennotes.com/podcasts/talk-python-to-me/… Mas acho que o cuidado com o 3.8 de um por um é mais recente. O Risky Business é um podcast de segurança bom e divertido, especialmente se você seguir as relações internacionais. Desculpas pelo voto negativo, mas sim, o que funcionou no seu caso pode encerrar alguém em um contexto diferente. Para conversão de 2 para 3, consulte listennotes.com/podcasts/talk-python-to-me/…
JL Peyret