Comprendere le modifiche strutturali ai pacchetti di Qiskit v1.0
Qiskit v1.0 utilizza una struttura di packaging diversa rispetto alle versioni precedenti e causerà probabilmente problemi negli ambienti che usano pacchetti non ancora compatibili con Qiskit v1.0.
Non cercare di aggiornare un ambiente virtuale Python esistente a Qiskit v1.0 sul posto.
Non apporteremo modifiche simili che rompono la compatibilità in futuro. Si tratta di un evento unico, al momento del rilascio di Qiskit v1.0, pensato proprio per rendere la gestione dei pacchetti il più semplice possibile in futuro.
Questa pagina contiene informazioni dettagliate sul pacchetto Qiskit precedente alla versione 1.0 e sui motivi che ci hanno spinto a fare queste modifiche strutturali.
Sappiamo che il cambiamento è scomodo, ma ristabilisce per Qiskit la struttura semplice dei pacchetti che la maggior parte dei progetti Python adotta, il che renderà le cose più facili per utenti, sviluppatori e autori di librerie una volta completata la transizione a Qiskit v1.0.
Prefazione: glossario della terminologia di packaging Python​
Per spiegare meglio come era strutturato il vecchio metapacchetto Qiskit e come questo è cambiato con il rilascio di Qiskit v1.0, di seguito trovi un glossario del gergo comunemente usato nel packaging Python. Le parole seguenti hanno significati precisi che verranno usati in questo documento.
Clicca qui per leggere il glossario di questa pagina
-
modulo (module): Un singolo file Python.
-
pacchetto (package): Una directory contenente un
__init__.pye altri file o pacchetti che Python può leggere. Questo è il codice effettivo installato sul tuo computer ed è ciò che viene eseguito quando eseguiimport something. Python considera importabile qualsiasi directory che si trovi nel percorso di ricerca (e importerà molti elementi aggiuntivi).Questo oggetto non è lo stesso che si installa con
pip install(che è una distribuzione), ma di solito ciò che si installa conpip installe ciò che si importa conimporthanno lo stesso nome. -
sottomodulo (submodule), sottopacchetto (subpackage): Questi termini sono imprecisi, ma comunemente usati. La parte sub significa "contenuto all'interno di un pacchetto". Un sottomodulo è un modulo e un sottopacchetto è un pacchetto, ma entrambi fanno parte di un pacchetto più grande.
-
pacchetto namespace (namespace package): Un pacchetto che può ricevere sottomoduli o sottopacchetti installati al suo interno da altre distribuzioni. In modo critico, nessuna delle distribuzioni che contribuisce a un pacchetto namespace possiede necessariamente tutti i file installati, il che può rendere difficile disinstallarlo o aggiornarlo completamente.
-
distribuzione (distribution): I file Python compressi, i file di dati e i metadati che vengono scaricati quando esegui
pip install something. Spesso una distribuzione contiene esattamente un pacchetto e i metadati su come installarlo (i suoi requisiti e così via), ma non è obbligatorio. Una distribuzione può contenere zero o più moduli o pacchetti.Se conosci i "gestori di pacchetti" al di fuori del contesto Python, come
aptdi Debian/Ubuntu o Homebrew su macOS, ciò che loro chiamano "pacchetto" Python lo chiama distribuzione, e non esiste una corrispondenza esatta per ciò che Python chiama pacchetto.La maggior parte delle fonti che parlano di packaging Python usa il termine package per indicare sia distribuzioni che pacchetti, e devi fare riferimento al contesto per capire cosa si intende. In generale, se lo si importa con
import, la fonte intende "pacchetto", se lo si installa conpip install, la fonte intende "distribuzione". -
percorso di ricerca (search path): Quando si tenta di eseguire
import something, Python cerca in un elenco predefinito di posizioni un modulo o pacchetto chiamatosomething. L'elenco di posizioni è il percorso di ricerca. Puoi vedere e modificare il percorso di ricerca insys.path. -
requisito (requirement): Una distribuzione contiene informazioni sulle altre distribuzioni da cui dipende al momento dell'installazione. Qualsiasi altra distribuzione necessaria è un requisito, e il gestore di pacchetti (di solito
pipoconda) deve assicurarsi che tutti i requisiti siano installati con versioni compatibili.
Python è altamente dinamico e possono sorgere molte complessità ; ad esempio, è possibile che un modulo o un pacchetto non corrisponda a file su disco, o che si tratti di estensioni compilate.
Il percorso di ricerca non è solo una ricerca tra directory, ma per questa discussione sono rilevanti solo i file su disco. Le ulteriori complicazioni non sono necessarie per comprendere i problemi descritti in questa sezione, quindi puoi usare il modello descritto sopra.
La vecchia struttura di Qiskit​
Storicamente, Qiskit era composto da molte distribuzioni Python: qiskit-terra, il nucleo del compilatore; qiskit-aer, il simulatore ad alte prestazioni; il provider originale di IBM Quantum®; e diversi pacchetti ora obsoleti che fornivano particolari funzionalità algoritmiche esplorative o di esecuzione di esperimenti.
Per comodità degli utenti, fornivamo anche una distribuzione Python chiamata qiskit, che non conteneva codice proprio, ma causava l'installazione di tutti gli altri componenti.
La chiamavamo metapacchetto, per analogia con concetti simili in altri gestori di pacchetti.
Il codice del nucleo di Qiskit risiedeva in qiskit-terra, che possedeva la radice del pacchetto Python qiskit. In altre parole, qiskit-terra controllava cosa accadeva quando si eseguiva import qiskit.
Fino a Qiskit v1.0, il pacchetto qiskit era un pacchetto namespace e conteneva un secondo pacchetto namespace in qiskit.providers.
Questa organizzazione ci ha causato e ha causato ai nostri utenti non pochi problemi.
Ad esempio, le librerie downstream che dipendevano da Qiskit spesso avevano bisogno solo del nucleo del compilatore e non richiedevano il resto del grande ecosistema che veniva installato con pip install qiskit.
Specificavano quindi correttamente il loro requisito come qiskit-terra.
Tuttavia, quando le persone cercavano di disinstallare Qiskit eseguendo pip uninstall qiskit, pip incontrava dei problemi:
pipnon rimuove le distribuzioni che non sono più utilizzate. Quindipip uninstall qiskitnon faceva quasi nulla; non c'era codice nella distribuzione, quindi non veniva rimosso alcun codice.- Anche se avesse rimosso il codice, molte distribuzioni downstream sarebbero rimaste installate perché dipendevano da
qiskit-terra. - Anche se
qiskit-terrafosse stato disinstallato, avrebbe potuto comunque lasciare una directoryqiskitimportabile ma priva di codice utilizzabile, perché era un pacchetto namespace.
Quando si installano o aggiornano distribuzioni con un comando pip install, pip non tiene conto delle precedenti risoluzioni dei requisiti.
Poiché c'erano due pacchetti, aggiornare un pacchetto che richiedeva l'aggiornamento di qiskit-terra causava un ambiente non valido; pip aggiornava qiskit-terra ma lasciava qiskit invariato.
Emetteva un avviso per questo e per tutti i successivi comandi pip install, ma poiché nulla sembrava rotto, gli utenti di solito ignoravano l'avviso e pip non restituiva uno stato di errore né vietava operazioni.
Nel tempo, abbiamo rimosso elementi dal metapacchetto qiskit finché, a partire da Qiskit v0.44, rimane solo qiskit-terra.
Tra questi componenti, qiskit-aer esiste ancora ed è attivamente aggiornato, ma ora viene installato come distribuzione separata.
Allo stesso modo, abbiamo sempre più scoraggiato le altre librerie dall'usare i hook del namespace.
Abbiamo rimosso l'ultimo utilizzo Qiskit degli hook nei pacchetti non obsoleti con il rilascio di Qiskit Aer v0.11 e il suo nuovo pacchetto Python qiskit_aer, sebbene fino a Qiskit v1.0 abbiamo anche forzato il funzionamento del percorso namespace qiskit.providers.aer.
A partire da Qiskit v1.0, abbiamo rimosso la possibilità per i pacchetti di estendere qualsiasi namespace qiskit. Quindi, pip uninstall sulla distribuzione corretta in un ambiente valido ora funziona come previsto.
La nuova struttura di Qiskit​
A partire dalla versione 1.0, Qiskit comprende una singola distribuzione, chiamata qiskit, che installa un unico pacchetto, anch'esso chiamato qiskit, che possiede tutto il codice contenuto nella sua directory.
Questa è la struttura normale del codice Python, ed è la struttura più semplice e meno soggetta a errori.
La distribuzione qiskit-terra su PyPI non verrà mai aggiornata alla versione 1.0 o successiva; è interamente sostituita da qiskit.
Il nome qiskit-terra non è più coinvolto nell'installazione.
Tuttavia, il pacchetto qiskit-terra non viene rimosso da PyPI, e lasceremo la sua versione più recente in uno stato funzionante, in modo che il vecchio codice scientifico e i pacchetti legacy possano continuare a usarlo più facilmente.
Purtroppo, a causa del retaggio del metapacchetto e delle carenze di pip come gestore di pacchetti, non ci è possibile creare un percorso di aggiornamento completamente agevole per gli utenti verso Qiskit v1.0, soprattutto mentre alcuni pacchetti dipendono da versioni precedenti di Qiskit e altri richiedono solo Qiskit v1.0+.
Questi problemi si attenueranno man mano che una parte più ampia dell'ecosistema migrerà a Qiskit v1.0.
Dove sono finiti i moduli applicativi?​
Potresti notare che il comando pip install qiskit non include più pacchetti come qiskit-aer o qiskit-nature. Con la rimozione della struttura del metapacchetto, molti di questi pacchetti sono stati separati in distribuzioni che devono essere installate singolarmente.
Prima del rilascio di Qiskit SDK v1.0, Qiskit era composto da molte distribuzioni Python diverse, come qiskit-terra, il nucleo del compilatore; qiskit-aer, il simulatore ad alte prestazioni; il provider originale di IBM Quantum®; e diversi pacchetti ora obsoleti che fornivano particolari funzionalità algoritmiche esplorative o di esecuzione di esperimenti.
Se vuoi installare i pacchetti che erano precedentemente inclusi nel metapacchetto Qiskit, visita l'ecosistema Qiskit per trovare una gamma di pacchetti adatti alle tue esigenze. Puoi anche leggere la guida alla migrazione v1.0 per ulteriori informazioni su come installare la nuova distribuzione.