Welche Version von Python & Django eignet sich am besten für die Konvertierung von Python2 in Python3-Code?

11

Derzeit arbeite ich in einer großen Firma, in der wir das alte große Django-Projekt von Python2 in die Python3-Version konvertieren müssen. Daher habe ich viele Nachforschungen angestellt, aber immer noch keine perfekte Antwort gefunden, die sich auf die für die Konvertierung am besten geeignete Version von Python und Django bezieht.

Derzeit verwende ich Python: 2.7.16 & Django: 1.9.13 in meiner alten Version.

Jeder kann mir die am besten geeignete Version von Python & Django für die oben genannte alte Version für die Konvertierung von Python2 in Python3 vorschlagen.

Mond
quelle
Die aktuelle Version von Python3 ist Python 3.8 und die neueste Version von Django ist Django 3.0. Auf der Website von Django wird die neueste Version von Python 3 empfohlen , nämlich 3.8. Gibt es einen bestimmten Grund, warum Sie Python und Django nicht auf die neuesten Versionen beschleunigen möchten?
Green Cloak Guy
2
Anekdotisch habe ich erst vor ein paar Tagen festgestellt, dass die Django-basierte Website, die ich seit einigen Jahren pflege, tatsächlich auf dem Server ausgeführt wird, auf dem sie mit Python2.7 gehostet wird, während ich sie lokal mit Python3 ausgeführt habe. 7. Der einzige Unterschied, den ich fand, war, als ich zum ersten Mal versuchte, irgendwo F-Strings zu verwenden, und die Version des Webservers abstürzte. Andernfalls wird es zum Testen und Hinzufügen von Funktionen lokal und remote genau wie erwartet (genau gleich) ausgeführt. Meine völlig anekdotische Schlussfolgerung ist, dass Django im Allgemeinen mit den meisten Dingen kompatibel ist.
Green Cloak Guy
1
Für die neueste Version habe ich festgestellt, dass einige Leute dies nicht empfehlen, da es in der neuesten Version manchmal schwierig ist, eine Lösung zu finden, wenn es Probleme im Zusammenhang mit neuen Updates gibt. Daher möchte ich im aktuellen Projekt kein solches Risiko eingehen und auch nicht für Beim Testen habe ich begonnen, mein Projekt auf die neueste Version von Python 3.7.3 mit dem neuesten Django zu konvertieren, und bereits 30 Probleme gefunden.
Mond
Es sollte angemerkt werden, dass diese Frage in einem Überprüfungsaudit für mich aufgeworfen wurde. "Gibt es ein Dokument oder eine Referenz" ist ganz klar nicht zum Thema (nach einer externen Ressource fragen). Ich glaube jedoch, dass die Frage so bearbeitet werden könnte, dass sie besser zu der unten akzeptierten Antwort führt.
theMayer

Antworten:

3

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.txtDateien, aber ...
  • Wenn Sie ein dateibasiertes Git-Repo haben, können Sie jedes Venv mit einem auf dieselbe Codeline richtenpip 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 esind 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.

JL Peyret
quelle
Guter Rat. Nur eine Anmerkung, die Django selbst bereits sixfür die Kompatibilitätsebene verwendet. Wenn Sie sie also während des Übergangs in einem Django-Projekt verwenden möchten, bedeutet dies nicht, dass "eine komplexe permanente Abhängigkeit hinzugefügt wird".
wim
@wim. Ich stimme dir zu. sechs, aber es kommt auf den Standpunkt an. Ich habe bereits bemerkt, dass es mit Bibliotheken von Drittanbietern geliefert wird, sodass es in Bezug auf Anforderungen und allgemeine Abhängigkeiten nicht "kostet". Ich habe es jedoch - vielleicht zu Unrecht - als große Black Box / Warze in der Mitte meines Codes angesehen. Wenn Sie nur Instanz-String / Unicode / Basestring testen und wissen, wie das geht, wissen Sie genau, wie Sie Ihre Shims zurücksetzen können, wenn sie nicht mehr benötigt werden. Ich werde das aber bis zum Ende verschieben.
JL Peyret
Es ist pip install -e ...(mit Kleinbuchstaben -e), richtig?
Thebjorn
es ist wahrscheinlich. wird korrigieren
JL Peyret
3

Mein Vorschlag ist, zuerst auf Django==1.11.26die neueste Version von Django zu aktualisieren , die sowohl Python 2 als auch Python 3 unterstützt. Bleiben Sie vorerst auf Ihrer aktuellen Version von Python 2.7.

Lesen Sie die Versionshinweise für 1.10.x und 1.11.x sorgfältig durch, prüfen Sie, ob sie veraltet sind, und beheben Sie alle Probleme, die mit Ihrem 1.9.x-Code nicht mehr funktionieren. Dinge werden brechen. Django bewegt sich schnell. Für ein großes Django-Projekt sind möglicherweise viele Codeänderungen erforderlich. Wenn Sie viele Plugins oder Bibliotheken von Drittanbietern verwenden, müssen Sie möglicherweise deren Versionen miteinander in Einklang bringen. Einige Ihrer Abhängigkeiten von Drittanbietern wurden wahrscheinlich vollständig aufgegeben, sodass Sie Ersatz finden oder die Funktionen entfernen müssen.

Um die Versionshinweise für jedes Versions-Upgrade zu finden, googeln Sie einfach "Was ist neu in Django". Die Treffer dokumentieren akribisch alle Abwertungen und Änderungen:

Sobald die Webapp 1.11 fein auf Django zu arbeiten scheinen, mit allen Tests vorbei (Sie tun eine Testsuite haben, nicht wahr?) , Dann können Sie die Python 3 Konvertierung tun, während das gleiche , die Django - Version zu halten. Django 1.11 unterstützt bis zu Python 3.7, daher wäre dies eine gute Version für das Targeting. Erwarten Sie überall Unicode, da die impliziten Konvertierungen zwischen Bytes und Text jetzt weg sind und sich viele Python 2-Webanwendungen darauf verlassen haben.

Sobald das Projekt unter Django 1.11 und Python 3.7 einwandfrei zu funktionieren scheint, können Sie über ein Upgrade auf Django 3.0 nach dem gleichen Verfahren wie zuvor nachdenken - Lesen der Versionshinweise, Vornehmen der erforderlichen Änderungen, Ausführen der Testsuite und Auschecken die webapp in einem dev server manuell.

wim
quelle
1
Auf jeden Fall der richtige Weg. Lassen Sie Ihren Testcode sowohl auf 2.7 als auch auf 3.x ausführen. Sie können 2 verschiedene virtuelle Umgebungen haben, die auf dasselbe Git-Repo mit zeigen pip install -E. Sobald die Komponententests ausgeführt werden, starten Sie die Testverwendung von Django-on-3x und lassen Sie den Code in 2 und 3 weiter funktionieren. Mit etwas sorgfältiger Codierung und darauf, dass Sie Ihre 2.7-Brücken nicht verbrennen - zum Beispiel keine F-Strings - erfolgt die Umschaltung sehr antiklimaktisch. Sobald 3.x vollständig stabil ist, verwenden Sie nur 3.x-Code. Der Vorteil ist, dass die Produktion 2.7 bis zum Wechsel immer im Gleichschritt ist.
JL Peyret
2

Ich würde zuerst auf py3 upgraden. Sie müssen sich setup.pydas Django-Repo im Stable / 1.9.x-Zweig ( https://github.com/django/django/blob/stable/1.9.x/setup.py ) ansehen, um herauszufinden, dass der py3 Unterstützte Versionen sind 3.4 (tot) und 3.5.

Sobald Sie auf py3.5 und Django 1.9 sind, können Sie nacheinander ein Upgrade durchführen, bis Sie zu der Version gelangen, bei der Sie enden möchten. ZB unterstützt Django 1.11 py3.5 und py3.7

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

dj2.2 ist die erste Version, die py3.8 unterstützt, aber ich würde wahrscheinlich bei py37 / dj2.2 aufhören, wenn Sie in einer normalerweise konservativen Umgebung arbeiten.

Wenn Sie andere Pakete haben, müssen Sie Versionskombinationen finden, die bei jedem Schritt zusammenarbeiten. Ein Plan ist der Schlüssel, und wenn Sie jeweils nur eine Komponente aktualisieren, sparen Sie normalerweise Zeit.

Die zukünftige Bibliothek ( https://python-future.org/ ) hilft Ihnen in vielen schwierigen Situationen, während Sie Code benötigen, um sowohl auf py27 als auch auf 3.x ausgeführt zu werden. Sechs ist auch großartig. Ich würde es vermeiden, Ihre eigene Kompatibilitätsebene zu rollen (warum das Rad neu erfinden?)

Wenn möglich, versuchen Sie, Ihre Unit-Test-Abdeckung vor dem Start auf 75-85% zu erhöhen, und richten Sie für jeden Upgrade-Schritt auf jeden Fall automatische Tests für die Versionen "von" und "bis" ein. Stellen Sie sicher, dass Sie alle Warnungen von Django gelesen und behoben haben, bevor Sie auf die nächste Version aktualisieren. Django kümmert sich kaum um die Abwärtskompatibilität. Daher würde ich normalerweise empfehlen, jede kleinere Version auf dem Upgrade-Pfad zu treffen (oder zumindest die "Rückwärts" zu lesen Inkompatibilitäten "und Verfallslisten für jede Nebenversion).

Viel Glück (wir aktualisieren gerade eine 300 + Kloc-Codebasis von py27 / dj1.7, also fühle ich deinen Schmerz ;-)

thebjorn
quelle
1
+1 bei Testabdeckung. Das ist hier eine Schlüsselmetrik, egal welchen Ansatz man letztendlich verfolgt. Es hilft wirklich , wenn sie mit Pervasive Code - Änderungen zu experimentieren und das sage ich als jemand, der ist nicht Aficionado bei allen ein TDD Rot / Grün - Test. Finden Sie heraus, wie Sie Ihre 2.7-Ergebnisse ermitteln können, und das Upgrade wird viel einfacher.
JL Peyret
2

Ich habe das gleiche Problem mit meinem Projekt und habe Python 3.7.5 mit Django Version 2.2.7 ausprobiert.

Sie sollten sich nicht für die neueste Version 3.8 von Python oder die neueste Version 3.0 von Django entscheiden, da Sie möglicherweise die Möglichkeit hatten, für jede Art von Fehler möglicherweise keine geeignete Lösung für die neuesten Versionen zu finden.

Alpesh
quelle
Dies sollte ein Kommentar sein
Bruno
-2

Sie sollten versuchen, für die aktuellen Versionen zu fotografieren. Python 3.8 und Django 3.0. Die Six-Bibliothek hilft bei einigen Konventionsänderungen. In beiden Fällen müssen Sie einige Umgestaltungen vornehmen, damit Sie es genauso gut aktuell machen können.

Dave
quelle
3
Haben Sie jemals ein Django-Upgrade durchgeführt? Das ist nur Wunschdenken. Es ist praktisch unmöglich, von 2.7 / 1.9 direkt zu Python 3.8 und Django 3.0 zu wechseln. Selbst das Aktualisieren kleinerer Versionen wie Django 1.9 auf 1.10 kann ein schwieriger Prozess sein, da viele Codeänderungen erforderlich sind.
wim
Ja, vorausgesetzt, ich hatte die Luxus- und Zeitgenehmigung, einen kompletten Refactor durchzuführen und den Antrag auf den neuesten Stand zu bringen. Wiederum sind Anwendungsgröße, Logik und Zeitbeschränkungen für die meisten Leute ein großes Problem, aber sie haben nie die Anwendungsgröße oder Zeitbeschränkung erwähnt, daher empfahl ich meine Meinung zu "bester Lösung" oder "Wunschdenken";)
Dave
Wenn Sie sich um Ansible kümmern müssen und auch auf einem LTS Ubuntu laufen müssen, werden Sie feststellen, dass unter Ubuntu 18.04 sogar 3.7-Unterstützung fehlt. Sicherheits-Podcasts, die ich höre, raten dazu, 3.8 bis zu einer Punktfreigabe oder 2. -1 für unnötiges Risiko ein wenig einwirken zu lassen.
JL Peyret
Irgendwelche guten Empfehlungen für Sicherheits-Podcasts?
Dave
Für Python sec, listennotes.com/podcasts/talk-python-to-me/… Aber ich denke, die Vorsicht vor 3.8 für eine Weile ist neuer. Risky Business ist ein guter und unterhaltsamer Sicherheitspodcast, insbesondere wenn Sie den internationalen Beziehungen folgen. Entschuldigung für die Ablehnung, aber ja, was in Ihrem Fall funktioniert hat, könnte jemand anderen in einem anderen Kontext ansprechen. Für die Konvertierung von 2 zu 3 siehe listennotes.com/podcasts/talk-python-to-me/…
JL Peyret