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.txt
arquivos 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 e
sã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.