Come creare una distribuzione di origine senza utilizzare il file setup.py?


10

Con la seguente struttura del pacchetto

.
├── my_package
   └── __init__.py
├── setup.cfg
└── setup.py

Contenuti di setup.py

from setuptools import setup
setup()

Contenuti di setup.cfg

[metadata]
name = my_package
version = 0.1

[options]
packages = find:

Posso costruire una ruota o una distribuzione sorgente per my_packagequesto

pip wheel --no-deps -w dist .
# generates file ./dist/my_package-0.1-py3-none-any.whl
python setup.py sdist
# generates file ./dist/my_package-0.1.tar.gz

Ma secondo il manutentore di setuptools , una configurazione di build dichiarativa è l'ideale e l'uso di una build imperativa sarà un odore di codice. Quindi sostituiamo setup.pycon pyproject.toml:

.
├── my_package
   └── __init__.py
├── setup.cfg
└── pyproject.toml

Contenuti di pyproject.toml

[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools", "wheel"]

E puoi ancora costruire una ruota come prima, funziona. Ma sdist non funziona:

python: can't open file 'setup.py': [Errno 2] No such file or directory

Quindi, come dovresti effettivamente creare il file .tar.gz usando setuptools ? Qual è lo strumento rivolto all'utente per creare sdist? Non voglio cambiare il backend di build. Sembra che tutti gli altri strumenti di packaging scrivano tutti i propri punti di ingresso della build, ma ho pensato che il punto fondamentale della definizione di un sistema di build dichiarativo nei metadati fosse in modo che non fosse necessario fare pratica con il sistema di build, imparando come ciascuno diversi strumenti di packaging si aspettano di essere invocati o di dover accedere all'interprete e chiamare manualmente un'API Python. Ma il PEP per i requisiti di sistema di build ha ormai più di 2 anni. Mi sto perdendo qualcosa di ovvio qui?

Come creare una distribuzione di origine senza utilizzare il setup.pyfile?

Risposte:


10

Questo è un argomento alquanto controverso, e la risposta per il momento è che non esiste un singolo strumento che tutti concordano sia il "modo giusto" per costruire distribuzioni di origine, né quale sarebbe tale strumento. Puoi vedere un lungo thread al riguardo nel discorso sul Python Packaging .

Ho esitato a dare troppi consigli imballaggi in formati durevoli perché le sabbie sono sempre spostando, ma a partire da novembre 2019, setup.py sdistè non deprecato, ma fa hanno tutti i lati negativi che PEP 517 e PEP 518 sono stati destinati a fix - vale a dire che si deve per creare l'ambiente di compilazione da soli (e conoscere tutte le dipendenze di compilazione) e funziona solo con setuptools / distutils e i loro equivalenti.

Non è una raccomandazione "ufficiale", ma l'attuale migliore sostituto per setup.py sdiste setup.py bdist_wheelsta invocando la versione da riga di comando di pep517. Il sostituto di sdistè:

python -m pep517.build --source .

Puoi costruire contemporaneamente la ruota e la distribuzione del sorgente in questo modo:

python -m pep517.build --source --binary .

Ecco come costruisco i miei pacchetti compatibili con PEP 517.

Ciò richiede che il tuo progetto abbia un pyproject.toml, e il pyproject.tomlmust have build-system.requirese le build-system.build-backendchiavi, ma funzionerà per qualsiasi progetto con un backend compatibile PEP 517 (incluso flit).

Altri strumenti :

Perché non usare flito poetryo hatch? Questi strumenti sono tutti disponibili per coloro che vogliono usarli, ma non sono una risposta a questa domanda . Questa domanda è relativa ai progetti creati con setuptoolsquell'uso in setup.cfgformato dichiarativo . Né flitpoetryfungere generici PEP 517 di generazione front-end, e quindi solo il lavoro come comandi di compilazione dei progetti utilizzando i rispettivi backend.

Io sono abbastanza non hanno familiarità con hatchdire se sia o non in grado di gestire i progetti con backend altri oltre setuptools, ma (ancora una volta, a partire da novembre 2019), è non è un frontend PEP 517, e non funzionerà se non si dispone a setup.py(genererà l'errore "impossibile aprire il file setup.py" e ignorerà il tuo pyproject.tomlfile).


Perché concentrarsi su ciò pep517.buildche si intende solo come un esperimento, una stampella temporanea quando ci sono strumenti produttivi come flauto, poesia, tratteggio e probabilmente anche di più?
sinoroc

1
Perché è stato un esperimento di successo nella mia stima (io e molte altre persone PyPA lo usiamo), poiché ha la semantica giusta per il lavoro e perché è l'unico front-end PEP 517 di tipo generico che conosco. flit e poesia sono integrati verticalmente in quanto si aspettano che tu usi il loro backend. il tratteggio sembra fare molte altre cose. pep517.buildè uno strumento semplice creato proprio per questo scopo.
Paul,

Ah giusto, buon punto. Mi stavo concentrando sul back-end della build. E in realtà pensavo pep517.buildfosse uno di loro. Ma per niente, è in realtà un front-end di build. Anche il tratteggio non è pronto per PEP517 come vedo ora.
sinoroc,

1
Ho aggiornato la mia risposta per rispondere alla tua domanda.
Paul,

Si perfetto. Cancella la mia risposta.
sinoroc,

-1

Non c'è niente di "ovvio" quando si tratta di packaging Python. Infatti, per il momento, almeno se stai usando distutils / setuptools è necessario creare un file (quasi) vuoto setup.py, anche se stai usando un dichiarativo completo setup.cfg:

#!/usr/bin/env python
from setuptools import setup
setup()

Consiglio anche io chmod +x setup.py.

In questo caso stai scrivendo tu stesso il "punto di ingresso" sul sistema di compilazione, ed setup()è solo la main()funzione per esso - ma ora tutti gli argomenti che sono stati tradizionalmente passati setup()possono essere letti setup.cfginvece.

Ora puoi ancora usare setup.py sdistse vuoi creare un tarball sorgente:

./setup.py sdist

Puoi anche provare uno dei sistemi di generazione alternativi che sono abilitati tramite pyproject.toml, come Flit .


Non sono sicuro del motivo per cui questo è stato sottoposto a downgrade; è sostanzialmente corretto anche se ci sono altre soluzioni.
Iguananaut,

2
Il titolo della domanda è "Come creare una distribuzione di origine senza utilizzare il file setup.py?" Questa risposta sembra dimostrare semplicemente "ecco come ricreare lo stesso file setup.py che hai appena eliminato", il che non è utile.
ornitorinco

Sì, ma ciò si basava su un malinteso secondo cui scrivere un dichiarativo setup.cfgsignifica che a setup.pynon è più necessario utilizzare setuptools, il che non è vero. Solo perché il titolo della domanda è fuorviante non significa che la risposta sia. Hanno scritto nel corpo della domanda "Quindi, come si dovrebbe effettivamente costruire il file .tar.gz usando setuptools ?" cui questo risponde correttamente.
Iguananaut,

1
In realtà è vero. setuptools non richiede un file setup.py se si utilizza PEP 517.
Paul

"se stai usando PEP 517" Tranne la maggior parte delle persone non lo è. È ancora provvisorio ed è appena menzionato in packaging.python.org . Non è qualcosa che avresti se non sapessi di cercarlo. Se vuoi solo che setuptools funzioni come sempre, è corretto.
Iguananaut,
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.