Je pensais ajouter un peu à la stratégie préconisée par la réponse de Wim - obtenir la version appropriée de Django fonctionnant à la fois sur 2.7 et 3.x - et décrire quelques tactiques qui ont fonctionné pour moi.
Python 2.7 est votre capsule d'échappement, jusqu'à ce que vous appuyiez sur la gâchette sur 3.x
- vos tests doivent s'exécuter sur les deux
- n'utilisez pas de fonctionnalités spécifiques à 3.x, comme les chaînes f
- d'abord Python 3.x, puis seulement plus tard Django 2.x qui ne fonctionne pas sur 2.7
- commencer tôt, ne pas trop analyser, mais éviter l'approche du big bang
- fichier par fichier au début.
- commencez par le code de niveau le plus bas, comme les bibliothèques d'utilitaires, pour lequel vous disposez de suites de tests.
- si possible, essayez de fusionner progressivement vos modifications dans les branches de production 2.7 et de garder votre code de portage 3.x à jour avec les changements de prod.
Avec quelle version mineure de Django commencer?
Mon critère ici est que les migrations Django peuvent être assez impliquées (et nécessitent en fait plus de réflexion que 2 => 3 travaux). Je passerais donc à la version 1.11 la plus récente et la plus efficace de cette façon, vous apportez déjà une certaine valeur à vos utilisateurs 2.7. Il y a probablement un bon nombre de cales de compatibilité pré-2.x sur 1.11 et vous obtiendrez ses avertissements de dépréciation 2.x.
Quelle version mineure de Python 3.x pour commencer?
Il est préférable de prendre en compte tous les angles, tels que la disponibilité de vos bibliothèques tierces, la prise en charge de votre suite CI / devops et la disponibilité sur vos images de système d'exploitation de serveur choisies. Vous pouvez toujours installer 3.8 et essayer une installation pip de votre requirements.txt par lui-même, par exemple.
Effet de levier git (ou tout ce que vous utilisez Scm) et virtualenv .
- des
requirement.txt
fichiers séparés , mais ...
- si vous avez un dépôt git basé sur un fichier, vous pouvez pointer chaque venv sur la même ligne de code avec un
pip install -e <your directory>
. cela signifie que, dans 2 terminaux différents, vous pouvez exécuter 2.7 et 3.x contre les mêmes unités.
- vous pouvez même exécuter les serveurs Django 2.7 et 3.x côte à côte sur différents ports et indiquer Firefox et Chrome.
- engagez-vous souvent (sur la branche de portage au moins) et découvrez git bisect .
utiliser 2to3
Oui, il cassera le code 2.7 et Django si vous le laissez. Donc...
exécutez-le en mode aperçu ou sur un seul fichier. voir ce qu'il casse mais aussi voir ce qu'il a bien fait.
limitez-le à certaines conversions qui ne cassent pas 2.7 ou Django. print x
=> print (x)
et except(Exception) as e
sont 2 évidents.
Voici à quoi ressemblait ma commande étranglée:
2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
- exécutez-le fichier par fichier jusqu'à ce que vous soyez vraiment confiant.
utilisez sed ou awk plutôt que votre éditeur pour les conversions en masse.
L'avantage est que, lorsque vous devenez plus conscient des préoccupations spécifiques de vos applications, vous pouvez créer une suite de modifications qui peuvent être exécutées sur 1 fichier ou plusieurs fichiers et faire la plupart du travail sans casser 2.7 ou Django. Appliquez ceci après votre passage 2to3 convenablement étranglé . Cela vous laisse des nettoyages résiduels dans votre éditeur et la réussite de vos tests.
(facultatif) commencez à courir en noir sur le code 2.7.
black qui est un formateur de code, utilise Python 3 ASTs pour exécuter son analyse. Il n'essaie pas d'exécuter le code, mais il signalera les erreurs de syntaxe qui l'empêcheront de passer à l'étape AST. Vous devrez travailler avec de la magie globale pour installer pip pour y arriver et vous devez acheter l'utilité des noirs.
D'autres l'ont fait - apprenez d'eux.
Écouter # 155 Les étapes pratiques pour passer à Python 3 devraient vous donner quelques idées sur le travail. Regardez les liens d'exposition pour cela. Ils aiment parler du mouvement Instagram (?) Qui impliquait un ajustement progressif de l'exécution du code 2.7 à la syntaxe 3.x sur une base de code commune et sur la même branche git, jusqu'au jour du déclenchement.
Voir aussi The Conservative Python 3 Porting Guide
et Instagram se déplacent en douceur vers Python 3 - La nouvelle pile
Conclusion
Votre temps pour Django 1.11 EOL (avril 2020) est assez court, donc si vous avez plus de 2 ressources de développement à y jeter, j'envisagerais de faire ce qui suit en parallèle:
DEV # 1: commencez par une bosse Django 1.11 (la théorie étant que Django 1.11 est probablement mieux positionné comme point de départ pour Django 2.x), en utilisant 2.7.
DEV # 2: lancez-vous sur Python 3.6 / 3.7 de votre code utilitaire non-Django. Étant donné que le code est compatible 2.7 à ce stade, fusionnez-le dans # 1 au fur et à mesure.
Découvrez comment les deux tâches se déroulent, évaluez le risque lié au projet lié à Django et à quoi ressemble la douleur Python 3. Vous manquez déjà le Python 2.7 EOL, mais un framework web obsolète est probablement plus dangereux que l'héritage Python 2.7, au moins pendant quelques mois. Je n'attendrais donc pas trop longtemps pour commencer à migrer depuis Django 1.9 et votre travail ne sera pas perdu. À mesure que vous voyez les progrès, vous commencerez à mieux voir les risques du projet.
Votre progression initiale en 2to3 sera lente, mais l'outillage et les conseils sont suffisamment bons pour que vous preniez rapidement de la vitesse, alors ne pensez pas trop avant de commencer à acquérir de l'expérience. Le côté Django dépend de votre exposition aux changements de rupture dans le framework, c'est pourquoi je pense qu'il est préférable de commencer tôt.
PS (opinion controversée / personnelle) Je n'ai pas beaucoup utilisé six bibliothèques de ponts 2 à 3 en conserve.
Ce n'est pas parce que je ne lui fais pas confiance - c'est génial pour les bibliothèques tierces - mais plutôt que je ne voulais pas ajouter une dépendance permanente complexe (et j'étais trop paresseux pour lire son doc). J'avais écrit du code 2.7 dans une syntaxe compatible 3.x pendant longtemps, donc je n'ai pas vraiment ressenti le besoin de les utiliser. Votre kilométrage peut varier et ne vous engagez pas sur cette voie si cela vous semble beaucoup de travail .
Au lieu de cela, j'ai créé un py223.py (57 LOC avec commentaires) avec ce type de contenu, dont la plupart concerne les solutions de contournement pour les obsolescences et les changements de nom dans la bibliothèque standard.
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)
Importez ensuite à partir de ce py223 pour contourner ces problèmes spécifiques. Plus tard, je vais juste fossé l'importation et déplacer les étranges isinstance(x, basestr_)
pour isinstance(x, str)
mais je sais à l' avance il y a peu à craindre.