Domanda

Supponiamo di aver sviluppato un'utilità per l'utente finale per uso generico scritta in Python. In precedenza, avevo solo una versione disponibile che era adatta per Python dopo la versione 2.3 o giù di lì. Era sufficiente dire "scarica Python se necessario, quindi esegui questo script". C'era solo una versione dello script nel controllo del codice sorgente (sto usando Git) per tenere traccia di.

Con Python 3, questo non è più necessariamente vero. Per il prossimo futuro, dovrò sviluppare contemporaneamente due diverse versioni, una adatta per Python 2.xe una adatta per Python 3.x. Dal punto di vista dello sviluppo, posso pensare ad alcune opzioni:

  1. Mantieni due diversi script nello stesso ramo, migliorando entrambi contemporaneamente.
  2. Mantieni due rami separati e unisci le modifiche comuni avanti e indietro man mano che procede lo sviluppo.
  3. Mantiene solo una versione dello script e controlla in un file patch che converte lo script da una versione all'altra. Quando sono state apportate modifiche sufficienti affinché la patch non si applichi più in modo pulito, risolvi i conflitti e creane una nuova.

Al momento mi sto orientando verso l'opzione 3, poiché i primi due implicherebbero molto tedio soggetto a errori. Ma l'opzione 3 sembra disordinata e il mio sistema di controllo del codice sorgente dovrebbe gestire le patch per me.

Per l'imballaggio di distribuzione, ci sono più opzioni tra cui scegliere:

  1. Offri due diversi pacchetti di download, uno adatto per Python 2 e uno adatto per Python 3 (l'utente dovrà sapere di scaricare quello corretto per qualunque versione di Python abbia).
  2. Offri un pacchetto di download, con due diversi script all'interno (e quindi l'utente deve sapere per eseguire quello corretto).
  3. Un pacchetto di download con due script specifici della versione e un piccolo caricatore di stub che può essere eseguito in entrambe le versioni di Python, che esegue lo script corretto per la versione di Python installata.

Ancora una volta mi sto sporgendo verso l'opzione 3 qui, anche se non ho ancora provato a sviluppare un tale caricatore di tronchi.

Altre idee?

È stato utile?

Soluzione

Modifica: la mia risposta originale era basata sullo stato del 2009, con Python 2.6 e 3.0 come le versioni attuali. Ora, con Python 2.7 e 3.3, ci sono altre opzioni. In particolare, ora è abbastanza fattibile utilizzare una singola base di codice per Python 2 e Python 3.

Vedi Porting del codice Python 2 su Python 3

Risposta originale:

La raccomandazione ufficiale dice:

  

Per il porting di Python 2.5 o 2.6 esistenti   codice sorgente per Python 3.0, il migliore   la strategia è la seguente:

     
      
  1. (Prerequisito :) Inizia con un'eccellente copertura del test.

  2.   
  3. Porta a Python 2.6. Questo non dovrebbe essere più lavoro della porta media   da Python 2.xa Python 2. (x + 1).   Assicurati che tutti i test abbiano superato.

  4.   
  5. (Usando ancora 2.6 :) Attiva l'opzione -3 della riga di comando. Questo abilita   avvisi sulle funzionalità che saranno   rimosso (o modificato) in 3.0. Esegui il tuo   testare nuovamente la suite e correggere il codice   ricevi avvisi fino a quando non ci sono   nessun avviso lasciato e tutti i tuoi test   ancora passare.

  6.   
  7. Esegui il traduttore da 2 a 3 sorgente-sorgente sull'albero del codice sorgente.   (Vedi 2to3 - Python automatizzato da 2 a 3   traduzione del codice per ulteriori informazioni al riguardo   strumento.) Esegui il risultato di   traduzione in Python 3.0. manualmente   risolvere eventuali problemi rimanenti, risolvendo   problemi fino a quando tutti i test non passano di nuovo.

  8.   
     

Non è consigliabile provare a scrivere   codice sorgente che funziona invariato sotto   sia Python 2.6 che 3.0; dovresti farlo   usa uno stile di codifica molto contorto,   per esempio. evitando dichiarazioni stampate,   metaclassi e molto altro. Se sei   mantenere una biblioteca che deve   supporta sia Python 2.6 che Python   3.0, l'approccio migliore è modificare il passaggio 3 sopra modificando il 2.6   versione del codice sorgente ed esecuzione   il traduttore 2to3 di nuovo, piuttosto che   modifica della versione 3.0 della fonte   codice.

Idealmente, potresti finire con una singola versione, che è 2.6 compatibile e può essere tradotta in 3.0 usando 2to3. In pratica, potresti non essere in grado di raggiungere questo obiettivo completamente. Quindi potresti aver bisogno di alcune modifiche manuali per farlo funzionare sotto 3.0.

Manterrei queste modifiche in un ramo, come l'opzione 2. Tuttavia, piuttosto che mantenere la versione finale 3.0 compatibile in questo ramo, prenderei in considerazione l'applicazione delle modifiche manuali prima del 2to3 traduzioni e inserisci questo codice 2.6 modificato nella tua filiale. Il vantaggio di questo metodo sarebbe che la differenza tra questo ramo e il trunk 2.6 sarebbe piuttosto piccola e consisterebbe solo nelle modifiche manuali, non nelle modifiche apportate da 2to3. In questo modo, le filiali distinte dovrebbero essere più facili da mantenere e unire e si dovrebbe essere in grado di beneficiare dei futuri miglioramenti in 2to3.

In alternativa, prendi un po 'di " aspetta e vedi " approccio. Procedere con il porting solo fino a quando si può andare con una singola versione 2.6 più la traduzione 2to3 e rimandare la modifica manuale rimanente fino a quando non è realmente necessaria una versione 3.0. Forse a questo punto, non hai più bisogno di modifiche manuali ...

Altri suggerimenti

Per lo sviluppo, l'opzione 3 è troppo ingombrante. Mantenere due rami è il modo più semplice sebbene il modo per farlo varierà tra VCS. Molti DVCS saranno più felici con repository separati (con un antenato comune per aiutare la fusione) e VCS centralizzato sarà probabilmente più facile lavorare con due rami. L'opzione 1 è possibile ma potresti perdere qualcosa da unire e un IMO un po 'più soggetto a errori.

Per la distribuzione, utilizzerei anche l'opzione 3, se possibile. Tutte e 3 le opzioni sono valide comunque e ho visto variazioni su questi modelli di volta in volta.

Non credo che seguirei questa strada. È doloroso qualunque sia il modo in cui lo guardi. Davvero, a meno che non ci sia un forte interesse commerciale nel mantenere entrambe le versioni contemporaneamente, questo è più mal di testa che guadagno.

Penso che abbia più senso continuare a sviluppare per 2.x per ora, almeno per alcuni mesi, fino a un anno. Ad un certo punto sarà giusto il momento di dichiarare una versione definitiva e stabile per 2.xe sviluppare quelle successive per 3.x +

Ad esempio, non passerò alla 3.x fino a quando alcuni dei principali framework non andranno in questo modo: PyQt, matplotlib, numpy e altri. E non mi dispiace davvero se a un certo punto interrompono il supporto 2.x e iniziano a sviluppare per 3.x, perché saprò che in breve tempo sarò in grado di passare anche a 3.x.

Vorrei iniziare migrando verso 2.6, che è molto vicino a Python 3.0. Potresti anche voler aspettare la 2.7, che sarà ancora più vicina a Python 3.0.

E poi, una volta eseguita la migrazione a 2.6 (o 2.7), ti suggerisco semplicemente di conservare solo una versione dello script, con cose come " se PY3K: ... else: ... " nei rari luoghi in cui sarà obbligatorio. Ovviamente non è il tipo di codice che gli sviluppatori amano scrivere, ma poi non devi preoccuparti di gestire più script o rami o patch o distribuzioni, il che sarà un incubo.

Qualunque cosa tu scelga, assicurati di avere test approfonditi con una copertura del codice del 100%.

Buona fortuna!

Qualunque sia l'opzione scelta per lo sviluppo, la maggior parte dei potenziali problemi potrebbe essere alleviata con test unitari approfonditi per garantire che le due versioni producano risultati corrispondenti. Detto questo, l'opzione 2 mi sembra molto naturale: applicare le modifiche da un albero di fonte a un altro albero di fonte è un compito (la maggior parte) per cui sono stati progettati i sistemi di controllo della versione - perché non trarre vantaggio dagli strumenti che forniscono per facilitare questo.

Per lo sviluppo, è difficile dirlo senza "conoscere il pubblico". Gli utenti di Power Python apprezzerebbero probabilmente non dover scaricare due copie del software, ma per una base di utenti più generale dovrebbe probabilmente "funzionare".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top