Ich dachte, ich würde ein wenig zu der Strategie beitragen, die von Wims Antwort befürwortet wird - zuerst die entsprechende Version von Django für 2.7 und 3.x verwenden - und einige Taktiken skizzieren , die für mich funktionieren.
Python 2.7 ist Ihr Escape Pod, bis Sie den Abzug auf 3.x betätigen
- Ihre Tests sollten auf beiden ausgeführt werden
- Verwenden Sie keine 3.x-spezifischen Funktionen wie F-Strings
- zuerst Python 3.x, dann erst später Django 2.x, das nicht auf 2.7 läuft
- Fangen Sie früh an, analysieren Sie nicht zu viel, sondern vermeiden Sie den Urknall-Ansatz
- Datei für Datei zuerst.
- Beginnen Sie mit dem Code der niedrigsten Ebene, z. B. Dienstprogrammbibliotheken, für die Sie Testsuiten haben.
- Versuchen Sie nach Möglichkeit, Ihre Änderungen schrittweise in den 2.7-Produktionszweigen zusammenzuführen und Ihren 3.x-Portierungscode mit Produktänderungen auf dem neuesten Stand zu halten.
Mit welcher Nebenversion von Django soll ich anfangen?
Mein Kriterium hier ist, dass Django-Migrationen ziemlich involviert sein können (und tatsächlich mehr Nachdenken erfordern als 2 => 3 Arbeit). Ich würde also auf die neueste und beste Version 1.11 umsteigen, damit Sie Ihren 2.7-Benutzern bereits einen Mehrwert bieten. Es gibt wahrscheinlich eine gute Anzahl von Pre-2.x-Kompatibilitäts-Shims für 1.11 und Sie erhalten die 2.x-Verfallswarnungen.
Mit welcher Nebenversion von Python 3.x soll man anfangen?
Berücksichtigen Sie am besten alle Aspekte, z. B. die Verfügbarkeit Ihrer Bibliotheken von Drittanbietern, die Unterstützung durch Ihre CI / devops-Suite und die Verfügbarkeit auf den von Ihnen ausgewählten Server-Betriebssystem-Images. Sie können beispielsweise jederzeit 3.8 installieren und versuchen, eine pip-Installation Ihrer Anforderung.txt selbst durchzuführen.
Leverage git (oder was auch immer scm Sie verwenden) und virtualenv .
- separate
requirement.txt
Dateien, aber ...
- Wenn Sie ein dateibasiertes Git-Repo haben, können Sie jedes Venv mit einem auf dieselbe Codeline richten
pip install -e <your directory>
. Das bedeutet, dass Sie in 2 verschiedenen Terminals 2.7 und 3.x gegen dieselben Unittest (s) ausführen können.
- Sie können sogar 2.7- und 3.x-Django-Server nebeneinander an verschiedenen Ports ausführen und beispielsweise Firefox und Chrome darauf hinweisen.
- Commit oft (zumindest auf dem Portierungszweig) und lerne etwas über Git Bisect .
benutze 2to3
Ja, es wird 2.7 Code und Django brechen, wenn Sie es zulassen. Damit...
Führen Sie es im Vorschaumodus oder für eine einzelne Datei aus. sehen, was es bricht, aber auch sehen, was es richtig gemacht hat.
Drosseln Sie es nur auf bestimmte Conversions, die 2.7 oder Django nicht brechen. print x
=> print (x)
und except(Exception) as e
sind 2 No-Brainers.
So sah mein gedrosselter Befehl aus:
2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
- Führen Sie es Datei für Datei aus, bis Sie wirklich sicher sind.
Verwenden Sie sed oder awk anstelle Ihres Editors für Massenkonvertierungen.
Der Vorteil besteht darin, dass Sie, wenn Sie sich der spezifischen Probleme Ihrer Apps bewusster werden, eine Reihe von Änderungen erstellen können, die entweder für eine oder mehrere Dateien ausgeführt werden können und den größten Teil der Arbeit erledigen können, ohne 2.7 oder Django zu beschädigen. Wenden Sie dies nach Ihrem entsprechend gedrosselten 2to3- Durchgang an. So bleiben Ihnen Restbereinigungen in Ihrem Editor und Ihre Tests müssen bestanden werden.
(optional) Starten Sie Schwarz mit 2.7-Code.
black, ein Code-Formatierer, verwendet Python 3-ASTs, um seine Analyse auszuführen. Es wird nicht versucht, den Code auszuführen, es werden jedoch Syntaxfehler angezeigt, die verhindern, dass er die AST-Stufe erreicht. Sie müssen jedoch einige Pip-Install-Global-Magic-Übungen durchführen, um dorthin zu gelangen, und Sie müssen sich auf die Nützlichkeit von Schwarz einlassen.
Andere Leute haben es geschafft - lernen Sie von ihnen.
Anhören von # 155 Praktische Schritte für den Wechsel zu Python 3 sollten Ihnen einige Ideen für die Arbeit geben. Schauen Sie sich die Show-Links dafür an. Sie lieben es, über den Instagram (?) - Schritt zu sprechen, bei dem die Ausführung von 2.7-Code auf 3.x-Syntax auf einer gemeinsamen Codebasis und auf demselben Git-Zweig schrittweise angepasst wurde, bis der Tag ausgelöst wird.
Siehe auch The Conservative Python 3 Porting Guide
und Instagram macht einen reibungslosen Übergang zu Python 3 - The New Stack
Fazit
Ihre Zeit für Django 1.11 EOL (April 2020) ist ziemlich kurz. Wenn Sie also mehr als 2 Entwicklungsressourcen haben, würde ich in Betracht ziehen, Folgendes parallel zu tun:
DEV # 1: Beginnen Sie mit einer Django 1.11-Beule (die Theorie besagt, dass Django 1.11 wahrscheinlich am besten als Startpunkt für Django 2.x positioniert ist), indem Sie 2.7 verwenden.
DEV # 2: Beginnen Sie mit Python 3.6 / 3.7 Ihres Nicht-Django-Dienstprogrammcodes. Da der Code zu diesem Zeitpunkt mit 2.7 kompatibel ist, führen Sie ihn bei Bedarf zu Nummer 1 zusammen.
Sehen Sie, wie beide Aufgaben ablaufen, wie das Django-bezogene Projektrisiko ist und wie der Python 3-Schmerz aussieht. Sie vermissen bereits Python 2.7 EOL, aber ein veraltetes Webframework ist wahrscheinlich zumindest für einige Monate gefährlicher als das ältere Python 2.7. Ich würde also nicht zu lange warten, um mit der Migration von Django 1.9 zu beginnen, und Ihre Arbeit wird nicht verschwendet. Wenn Sie den Fortschritt sehen, werden Sie die Projektrisiken besser erkennen.
Ihr anfänglicher 2to3-Fortschritt wird langsam sein, aber die Werkzeuge und Anleitungen sind gut genug, um schnell an Geschwindigkeit zu gewinnen. Denken Sie also nicht darüber nach, bevor Sie Erfahrungen sammeln. Die Django Seite hängt von Ihrer Exposition gegenüber Bruch Änderungen im Rahmen, weshalb ich denke , es ist am besten , früh zu beginnen.
PS (kontroverse / persönliche Meinung) Ich habe nicht viel sechs oder andere 2-zu-3-Brückenbibliotheken in Dosen verwendet.
Das liegt nicht daran, dass ich ihm nicht vertraue - es ist brillant für Bibliotheken von Drittanbietern -, sondern daran, dass ich keine komplexe permanente Abhängigkeit hinzufügen wollte (und ich war zu faul, um das Dokument zu lesen). Ich hatte lange Zeit 2.7-Code in 3.x-kompatibler Syntax geschrieben, daher hatte ich nicht wirklich das Bedürfnis, sie zu verwenden. Ihr Kilometerstand kann variieren und Sie sollten diesen Weg nicht beschreiten, wenn es nach viel Arbeit aussieht .
Stattdessen habe ich mit dieser Art von Inhalten ein py223.py (57 LOC inkl. Kommentare) erstellt, das sich hauptsächlich mit Problemumgehungen für Veralterungen und Namensänderungen in der Standardbibliothek befasst.
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)
Importieren Sie dann von diesem py223, um diese spezifischen Probleme zu umgehen. Später werde ich den Import einfach fallen lassen und die Verrückten dorthin verschieben isinstance(x, basestr_)
, isinstance(x, str)
aber ich weiß im Voraus, dass es wenig Grund zur Sorge gibt.