Quando utilizzare il file dei requisiti pip rispetto a install_requires in setup.py?


94

Sto usando pip con virtualenv per pacchettizzare e installare alcune librerie Python.

Immagino che quello che sto facendo sia uno scenario piuttosto comune. Sono il manutentore di diverse librerie per le quali posso specificare esplicitamente le dipendenze. Alcune delle mie librerie dipendono da librerie di terze parti che hanno dipendenze transitive sulle quali non ho alcun controllo.

Quello che sto cercando di ottenere è che una pip installdelle mie librerie scarichi / installi tutte le sue dipendenze a monte. Quello con cui sto lottando nella documentazione pip è se / come i file dei requisiti possono farlo da soli o se sono davvero solo un supplemento all'utilizzo install_requires.

Userei install_requiresin tutte le mie librerie per specificare le dipendenze e gli intervalli di versione e quindi userei solo un file dei requisiti per risolvere un conflitto e / o congelarli per una build di produzione?

Facciamo finta che io viva in un mondo immaginario (lo so, lo so) e le mie dipendenze a monte sono dirette e garantite per non entrare mai in conflitto o rompere la retrocompatibilità. Sarei costretto a utilizzare un file dei requisiti pip o semplicemente lasciare che pip / setuptools / distribute installi tutto in base a install_requires?

Ci sono molte domande simili qui, ma non sono riuscito a trovarne nessuna così basilare come quando usare l'una o l'altra o usarle entrambe insieme armoniosamente.


3
Questo è un articolo molto carino che spiega la relazione tra i due e anche come si integrano.
Björn Pollex

Risposte:


68

La mia filosofia è che install_requiresdovrebbe indicare un minimo di ciò di cui hai bisogno. Potrebbe includere requisiti di versione se sai che alcune versioni non funzioneranno; ma non dovrebbe avere requisiti di versione in cui non sei sicuro (ad esempio, non sei sicuro se un futuro rilascio di una dipendenza interromperà la tua libreria o meno).

Requisiti file d'altra parte devono indicare ciò che si sa fa il lavoro, e possono includere dipendenze opzionali che vi consigliamo. Ad esempio, potresti usare SQLAlchemy ma suggerire MySQL e quindi inserire MySQLdb nel file dei requisiti).

Quindi, in sintesi: install_requiresè tenere le persone lontane da cose che sai non funzionano, mentre i file di requisiti per guidare le persone verso cose che sai funzionano. Uno dei motivi è che i install_requiresrequisiti vengono sempre controllati e non possono essere disabilitati senza modificare effettivamente i metadati del pacchetto. Quindi non puoi provare facilmente una nuova combinazione. I file dei requisiti vengono controllati solo al momento dell'installazione.


5
significa che dovresti rispecchiare le setup.py install_requires=profondità requirements.txt?
proppy

9
Avere entrambi i requisiti in setup.py e un file dei requisiti è pericoloso, perché la duplicazione chiede solo di non essere sincronizzata.
Sebastian Blask

1
Inoltre, come ci lavorate effettivamente allora? Presumo che tu usi il file dei requisiti una volta per arrivare a uno stato che sta sicuramente funzionando. Quindi installa con il pacchetto effettivo con pip. Non sarai mai in grado di utilizzare -Uperché ciò potrebbe sovrascrivere le dipendenze dal file dei requisiti? Come si aggiorna?
Sebastian Blask

1
Questa risposta si applica allo stesso modo ad applicazioni e pacchetti? Immagina la mia app web (un'app) che dipende da qualche strumento (un pacchetto), entrambi dipendono dal pacchetto delle richieste. Se uno strumento ha un file requirements.txt che blocca una particolare versione o un intervallo di versioni di richieste, ciò sembrerebbe creare un potenziale problema per my-web-app, che potrebbe aver specificato una versione / intervallo di versioni in conflitto.
Reece

2
Ci dovrebbe essere un solo modo per installare un pacchetto. Quindi non è consigliabile avere entrambi, a meno che tu non voglia confondere gli altri contributori.
Gewthen

17

ecco cosa metto nel mio setup.py:

# this grabs the requirements from requirements.txt
REQUIREMENTS = [i.strip() for i in open("requirements.txt").readlines()]

setup(
    .....
    install_requires=REQUIREMENTS
)

20
Attenzione, i file dei requisiti potrebbero contenere commenti e inclusioni. Dovresti usare il parser pip
Romain Hardouin

1
sì, alla fine l'ho modificato per eliminare i commenti. pip parser sembra migliore della mia risposta.
rbp

7
Perché usare un file dei requisiti se tutto ciò che contiene è già in setup.py?
Sebastian Blask

2
@RomainHardouin, come menzionato nei commenti alla tua risposta collegata, pip non è pensato per essere utilizzato in questo modo.
akaihola

1
sì, questo ha funzionato per me fino a quando non è --extra-index-urlstato richiesto un critico nei requisiti e questo mi è esploso in faccia. Grazie @RomainHardouin
Tommy

11

La Python Packaging User Guide ha una pagina su questo argomento, ti consiglio vivamente di leggerla:

Sommario:

install_requiresè lì per elencare le dipendenze del pacchetto che deve essere assolutamente installato affinché il pacchetto funzioni. Non ha lo scopo di bloccare le dipendenze a versioni specifiche, ma sono accettati intervalli, ad esempio install_requires=['django>=1.8']. install_requiresè osservato da pip install name-on-pypie altri strumenti.

requirements.txtè solo un file di testo, su cui puoi scegliere di eseguire pip install -r requirements.txt. E 'destinata ad avere versioni di tutte le dipendenze e subdependencies appuntato, in questo modo: django==1.8.1. Puoi crearne uno usando pip freeze > requirements.txt. (Alcuni servizi, come Heroku, vengono eseguiti automaticamente pip install -r requirements.txtper te.) pip install name-on-pypiNon guarda requirements.txt, ma solo install_requires.


5

Uso sempre e solo setup.pye install_requiresperché c'è solo un posto da guardare. È potente quanto avere un file dei requisiti e non ci sono duplicazioni da mantenere.


La domanda è quando usare l'uno o l'altro, non l'ho spiegato, ma la mia risposta è dire che uso sempre l'uno e mai l'altro. Come mai questo non risponde alla domanda?
Sebastian Blask
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.