Pomyślałem, że dodam trochę do strategii zalecanej przez odpowiedź Wima - najpierw zdobądź odpowiednią wersję Django działającą na wersjach 2.7 i 3.x - i opisz kilka taktyk, które działały dla mnie.
Python 2.7 jest twoją kapsułą ratunkową, dopóki nie pociągniesz za spust w 3.x
- twoje testy powinny działać na obu
- nie używaj żadnych specyficznych funkcji 3.x, takich jak struny F.
- najpierw Python 3.x, a dopiero później Django 2.x, który nie działa w wersji 2.7
- zacznij wcześnie, nie analizuj zbytnio, ale unikaj podejścia wielkiego wybuchu
- plik po pliku na początku.
- zacznij od kodu najniższego poziomu, takiego jak biblioteki narzędziowe, dla których masz zestawy testowe.
- jeśli to możliwe, spróbuj stopniowo scalać zmiany w gałęziach produkcyjnych 2.7 i dbać o to, aby Twój kod wersji 3.x był aktualizowany o zmiany prod.
Od jakiej małej wersji Django zacząć?
Moje kryterium jest takie, że migracje Django mogą być dość zaangażowane (i faktycznie wymagają więcej myślenia niż 2 => 3 pracy). Chciałbym przejść do najnowszej i najlepszej wersji 1.11 w ten sposób, że już zapewniasz pewną wartość swoim użytkownikom w wersji 2.7. Prawdopodobnie istnieje duża liczba podkładek kompatybilnych przed wersją 2.x na 1.11 i otrzymasz ostrzeżenia o wycofaniu 2.x.
Od jakiej małej wersji Python 3.x na początek?
Najlepiej jest wziąć pod uwagę wszystkie aspekty, takie jak dostępność bibliotek stron trzecich, wsparcie z pakietu CI / devops i dostępność na wybranych obrazach systemu operacyjnego serwera. Zawsze możesz na przykład zainstalować wersję 3.8 i samodzielnie wypróbować instalację PIP wymagań.txt.
Wykorzystaj git (lub inny scm, którego używasz) i virtualenv .
- oddzielny
requirement.txt
pliki, ale ...
- jeśli masz oparte na plikach, git repo, możesz skierować każdy venv na tę samą linię kodową za pomocą
pip install -e <your directory>
. oznacza to, że w 2 różnych terminalach możesz uruchamiać 2.7 i 3.x przeciwko tym samym unittest (s).
- możesz nawet uruchomić serwery Django 2.7 i 3.x obok siebie na różnych portach i wskazać na nich Firefox i Chrome.
- często zatwierdzaj (przynajmniej na gałęzi portującej) i dowiedz się o git bisect .
zrobić użytek z 2to3
Tak, złamie kod 2.7 i Django, jeśli na to pozwolisz. Więc...
uruchom go w trybie podglądu lub na jednym pliku. zobacz, co się psuje, ale także zobacz, co zrobiło dobrze.
ogranicz go tylko do niektórych konwersji, które nie łamią wersji 2.7 lub Django. print x
=> print (x)
i except(Exception) as e
są 2 bezmyślnymi.
Tak wyglądało moje zdławione polecenie:
2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
- uruchamiaj plik po pliku, aż będziesz naprawdę pewny siebie.
używaj sed lub awk zamiast edytora do konwersji zbiorczych.
Zaletą jest to, że gdy stajesz się bardziej świadomy obaw związanych ze swoimi aplikacjami, możesz zbudować zestaw zmian, które można uruchomić na jednym pliku lub wielu plikach i wykonać większość pracy bez złamania wersji 2.7 lub Django. Zastosuj to po odpowiednio przepustnicy 2 do 3 . To pozostawia resztki porządków w edytorze i pozwala przejść testy.
(opcjonalnie) zacznij wyświetlać czarny kod 2.7.
czarny, który jest formatatorem kodu, używa Pythona 3 AST do uruchomienia analizy. Nie próbuje uruchomić kodu, ale oznaczy błędy składniowe, które uniemożliwiają mu przejście do etapu AST. Będziesz musiał jednak popracować nad globalną magią instalacji, aby się tam dostać, i musisz kupić użyteczność czarnych.
Inni to zrobili - ucz się od nich.
Słuchanie # 155 Praktyczne kroki do przejścia na Python 3 powinny dać ci kilka pomysłów na temat pracy. Spójrz na linki do niego. Uwielbiają mówić o ruchu na Instagramie (?), Który polegał na stopniowym dostosowywaniu działania kodu 2.7 do składni 3.x na wspólnej bazie kodu i na tej samej gałęzi git, aż do dnia uruchomienia.
Zobacz też The Conservative Python 3 Porting Guide
a Instagram płynnie przechodzi do Pythona 3 - Nowy stos
Wniosek
Twój czas na Django 1.11 EOL (kwiecień 2020) jest raczej krótki, więc jeśli masz do dyspozycji ponad 2 zasoby deweloperskie, rozważę wykonanie następujących czynności równolegle:
DEV # 1: zacznij od wypukłości Django 1.11 (zgodnie z teorią, że Django 1.11 jest prawdopodobnie najlepiej ustawiony jako punkt wyjścia do Django 2.x), używając 2.7.
DEV # 2: zacznij na Pythonie 3.6 / 3.7 swojego kodu narzędzia innego niż Django. Ponieważ kod jest w tym momencie kompatybilny z wersją 2.7, scal go z numerem 1 w miarę upływu czasu.
Zobacz, jak przebiegają oba zadania, oceń ryzyko związane z projektem Django i jak wygląda ból w Pythonie 3. Już brakuje EOL języka Python 2.7, ale przestarzała platforma internetowa jest prawdopodobnie bardziej niebezpieczna niż starsza wersja Python 2.7, przynajmniej przez kilka miesięcy. Nie będę więc długo czekać na migrację z Django 1.9, a twoja praca nie będzie zmarnowana. Gdy zobaczysz postęp, zaczniesz lepiej widzieć ryzyko związane z projektem.
Początkowy postęp 2 do 3 będzie powolny, ale oprzyrządowanie i wskazówki są na tyle dobre, że szybko przyspieszysz, więc nie zastanawiaj się nad nim, zanim zaczniesz zbierać doświadczenia. Strona Django zależy od tego, czy jesteś narażony na przełomowe zmiany w frameworku, dlatego myślę, że najlepiej zacząć od początku.
PS (kontrowersyjne / osobiste zdanie) Nie użyłem sześciu używałem zbyt często lub innych puszkowanych bibliotek mostowych 2 do 3.
To nie dlatego, że nie ufa - to genialna na 3rd bibliotekami partii - ale raczej, że nie chcą, aby dodać kompleksową stałą zależność (a byłem zbyt leniwy, aby przeczytać jego doc). Długo pisałem kod 2.7 w składni zgodnej z 3.x, więc tak naprawdę nie czułem potrzeby ich używania. Twój przebieg może się różnić i nie zaczynaj na tej ścieżce, jeśli wydaje się, że to dużo pracy .
Zamiast tego stworzyłem py223.py (57 LOC wraz z komentarzami) z tego rodzaju treściami, z których większość dotyczy obejść przestarzałości i zmian nazw w standardowej bibliotece.
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)
Następnie zaimportuj z tego py223, aby obejść te konkretne problemy. Później będzie tylko rów import i przenieść te dziwnie isinstance(x, basestr_)
się isinstance(x, str)
ale wiem z góry nie ma się czym martwić.