Ho pensato di aggiungere un po 'alla strategia sostenuta dalla risposta di Wim: far funzionare prima la versione appropriata di Django su 2.7 e 3.x e delineare alcune tattiche che hanno funzionato per me.
Python 2.7 è il tuo pod di escape, fino a quando non premi il grilletto su 3.x.
- i tuoi test dovrebbero essere eseguiti su entrambi
- non utilizzare alcuna funzionalità specifica 3.x, come f-string
- prima Python 3.x, poi solo successivamente Django 2.x che non funziona su 2.7
- iniziare presto, non analizzare troppo, ma evitare l'approccio big bang
- file per file all'inizio.
- iniziare con il codice di livello più basso, come le librerie di utilità, per cui si dispone di suite di test.
- se possibile, prova a unire gradualmente le tue modifiche ai rami di produzione 2.7 e mantieni aggiornato il tuo codice di porting 3.x con le modifiche prod.
Con quale versione minore di Django iniziare?
I miei criteri qui sono che le migrazioni di Django possono essere abbastanza coinvolte (e in realtà richiedono più pensiero di 2 => 3 lavori). Quindi passerei all'ultima e la più grande 1.11 in questo modo stai già fornendo un valore ai tuoi utenti 2.7. Probabilmente c'è un buon numero di spessori di compatibilità pre-2.x su 1.11 e riceverai i suoi avvisi di deprecazione 2.x.
Con quale versione minore di Python 3.x iniziare?
È meglio considerare tutti gli angoli, come la disponibilità delle librerie di terze parti, il supporto dalla suite CI / devops e la disponibilità sulle immagini del sistema operativo del server prescelte. Puoi sempre installare 3.8 e provare un'installazione pip del tuo requisito.txt da solo, per esempio.
Sfrutta git (o qualsiasi altra cosa tu usi) e virtualenv .
requirement.txt
file separati , ma ...
- se si dispone di un repository git basato su file, è possibile puntare ogni venv alla stessa codeline con a
pip install -e <your directory>
. ciò significa che, in 2 terminali diversi, è possibile eseguire 2.7 e 3.x contro gli stessi unittest (s).
- potresti persino eseguire server Django 2.7 e 3.x fianco a fianco su porte diverse e puntare su Firefox e Chrome.
- impegnarsi spesso (almeno sul ramo porting) e conoscere git bisect .
fare uso di 2to3
Sì, si romperà il codice 2.7 e Django se lo si lascia. Così...
eseguirlo in modalità anteprima o su un singolo file. vedere cosa si rompe ma anche vedere cosa ha fatto bene.
limitalo a determinate conversioni che non infrangono la 2.7 o Django. print x
=> print (x)
e except(Exception) as e
sono 2 senza cervello.
Ecco come appariva il mio comando strozzato:
2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
- eseguilo file per file fino a quando non sei davvero sicuro.
usa sed o awk anziché il tuo editor per conversioni collettive.
Il vantaggio è che, man mano che diventi più consapevole delle preoccupazioni specifiche delle tue app, puoi creare una suite di modifiche che possono essere eseguite su 1 o più file e svolgere la maggior parte del lavoro senza rompere 2.7 o Django. Applicare questo dopo il vostro opportunamente strozzato 2to3 pass. Questo ti lascia con le pulizie residue nel tuo editor e fa passare i test.
(facoltativo) inizia a funzionare in nero con il codice 2.7.
black, che è un formattatore di codice, utilizza AST Python 3 per eseguire la sua analisi. Non tenta di eseguire il codice, ma contrassegnerà gli errori di sintassi che gli impediscono di raggiungere lo stadio AST. Dovrai lavorare con qualche pip per installare la magia globale per arrivarci e devi acquistare l'utilità del nero.
Altre persone l'hanno fatto - impara da loro.
Ascolto del numero 155 I passaggi pratici per passare a Python 3 dovrebbero darti alcune idee sul lavoro. Guarda i link dello spettacolo per questo. Amano parlare della mossa di Instagram (?) Che ha comportato una graduale regolazione dell'esecuzione del codice 2.7 sulla sintassi 3.x su una base di codice comune e sullo stesso ramo git, fino al giorno del grilletto.
Vedi anche The Conservative Python 3 Porting Guide
e Instagram passa a Python 3 : il nuovo stack
Conclusione
Il tuo tempo a Django 1.11 EOL (aprile 2020) è piuttosto breve, quindi se hai 2+ risorse di sviluppo da lanciare, prenderei in considerazione la seguente procedura in parallelo:
DEV # 1: inizia con un bump di Django 1.11 (la teoria è che Django 1.11 è probabilmente il miglior punto di partenza per Django 2.x), usando 2.7.
DEV # 2: inizia su Python 3.6 / 3.7 del tuo codice di utilità non Django. Poiché il codice è 2.7 compatibile a questo punto, uniscilo al n. 1 mentre procedi.
Guarda come procedono entrambe le attività, valuta qual è il rischio del progetto relativo a Django e come si presenta il dolore di Python 3. Ti manca già l'EOL di Python 2.7, ma un framework Web obsoleto è probabilmente più pericoloso del precedente Python 2.7, almeno per alcuni mesi. Quindi non aspetterei troppo a lungo per iniziare a migrare da Django 1.9 e il tuo lavoro non sarà sprecato. Man mano che vedi i progressi, inizierai a vedere meglio i rischi del progetto.
I tuoi progressi iniziali 2to3 saranno lenti, ma gli strumenti e la guida sono abbastanza buoni da farti guadagnare rapidamente velocità, quindi non pensarci troppo prima di iniziare a raccogliere esperienza. Il lato di Django dipende dalla tua esposizione a cambiamenti radicali nel framework, motivo per cui penso sia meglio iniziare presto.
PS (opinione controversa / personale) Non ho usato molto sei o altre librerie di bridge da 2 a 3 in scatola.
E ' non è perché non mi fido - è brillante per 3rd librerie di partito - ma piuttosto che non volevo aggiungere un complesso di dipendenza permanente (e io ero troppo pigro per leggere il suo doc). Avevo scritto il codice 2.7 nella sintassi compatibile 3.x per molto tempo, quindi non sentivo davvero il bisogno di usarli. Il tuo chilometraggio può variare e non intraprendere questo percorso se sembra un sacco di lavoro .
Invece, ho creato un py223.py (57 LOC incl. Commenti) con questo tipo di contenuto, la maggior parte dei quali riguarda soluzioni alternative per ammortamenti e cambi di nome nella libreria 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)
Quindi importare da quel py223 per aggirare quelle preoccupazioni specifiche. In seguito mi limiterò a scavare l'importazione e spostare quegli strani isinstance(x, basestr_)
a isinstance(x, str)
ma so in anticipo c'è poco di cui preoccuparsi.