Wie erstelle ich eine Quelldistribution ohne die Datei setup.py?

10

Mit folgender Paketstruktur

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

Inhalt von setup.py

from setuptools import setup
setup()

Inhalt von setup.cfg

[metadata]
name = my_package
version = 0.1

[options]
packages = find:

Ich kann für Rad oder eine Quelldistribution bauen my_packagewie diese

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

Laut dem Betreuer von setuptools ist eine deklarative Build-Konfiguration jedoch ideal und die Verwendung eines imperativen Builds wird ein Code-Geruch sein. So ersetzen wir setup.pymit pyproject.toml:

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

Inhalt von pyproject.toml

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

Und Sie können ein Rad immer noch so bauen wie zuvor, es funktioniert. Aber sdist funktioniert nicht:

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

Wie sollten Sie die .tar.gz-Datei mit setuptools erstellen ? Was ist das benutzerbezogene Tool zum Erstellen von SDIST? Ich möchte das Build-Backend nicht ändern. Es sieht so aus, als ob andere Verpackungswerkzeuge alle ihre eigenen Build-Einstiegspunkte schreiben, aber ich dachte, der Sinn der Definition eines deklarativen Build-Systems in den Metadaten bestand darin, dass Sie sich nicht mit dem Build-System vertraut machen mussten, um zu lernen, wie die einzelnen Tools erstellt wurden Es wird erwartet, dass ein anderes Verpackungstool aufgerufen wird oder in den Interpreter gehen und eine Python-API manuell aufrufen muss. Der PEP für Build-Systemanforderungen ist jetzt über 2 Jahre alt. Vermisse ich hier etwas Offensichtliches?

Wie erstelle ich eine Quelldistribution ohne setup.pyDatei?

Schnabeltier
quelle

Antworten:

10

Dies ist ein etwas kontroverses Thema, und die Antwort für den Moment ist, dass es kein einziges Tool gibt, dem alle zustimmen, dass es der "richtige Weg" ist, Quelldistributionen zu erstellen, und auch nicht das, was dieses Tool wäre. Sie können einen langen Thread darüber im Python Packaging-Diskurs sehen .

Ich zögere , zu viel Verpackung Beratung in dauerhafte Formate zu geben , weil der Sand immer verlagern, aber ab November 2019 setup.py sdistist nicht veraltet, aber es tut haben alle die Nachteile , dass PEP 517 und PEP 518 fix bestimmt waren - nämlich , dass Sie um die Build-Umgebung selbst zu erstellen (und alle Build-Abhängigkeiten zu kennen), und es funktioniert nur mit setuptools / distutils und ihren Äquivalenten.

Es ist keine "offizielle" Empfehlung, sondern der derzeit beste Ersatz für die Befehlszeilenversion von setup.py sdistund setup.py bdist_wheelruft diese auf pep517. Der Ersatz für sdistist:

python -m pep517.build --source .

Sie können das Rad und die Quelldistribution gleichzeitig wie folgt erstellen:

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

So erstelle ich meine PEP 517-kompatiblen Pakete.

Dies setzt voraus, dass Ihr Projekt über ein pyproject.tomlund das pyproject.tomlMuss build-system.requiresund build-system.build-backendSchlüssel verfügt, funktioniert jedoch für jedes Projekt mit einem PEP 517-kompatiblen Backend (einschließlich flit).

Andere Werkzeuge :

Warum nicht verwenden flitoder poetryoder hatch? Diese Tools sind alle für diejenigen verfügbar, die sie verwenden möchten, aber sie sind keine Antwort auf diese Frage . Diese Frage bezieht sich auf Projekte, die mit setuptoolsdem deklarativen setup.cfgFormat erstellt wurden. Weder flitnoch poetrywirken als generischer PEP 517 Build - Front-Ends, und so sie nur Arbeit als Build - Befehle für Projekte mit ihrem jeweiligen Backends.

Ich bin nicht vertraut genug, um hatchzu sagen, ob es Projekte mit anderen Backends als Setuptools verwalten kann oder nicht , aber (wieder ab November 2019) ist es kein PEP 517-Frontend und es wird nicht funktionieren, wenn Sie es nicht haben a setup.py(es wird den Fehler "Datei setup.py kann nicht geöffnet werden" ausgelöst und Ihre pyproject.tomlDatei wird ignoriert ).

Paul
quelle
Warum sollte man sich darauf konzentrieren, pep517.buildwas nur als Experiment gedacht ist, als temporäre Krücke, wenn es produktive Werkzeuge wie Flit, Poesie, Luke und wahrscheinlich noch mehr gibt?
Sinoroc
1
Weil es nach meiner Einschätzung ein erfolgreiches Experiment war (ich und viele andere PyPA-Leute verwenden es), weil es die richtige Semantik für den Job hat und weil es das einzige PEP 517-Build-Frontend ist, das ich kenne. Flit und Poetry sind vertikal integriert, da sie erwarten, dass Sie ihr Backend verwenden. Luke scheint viele andere Dinge zu tun. pep517.buildist ein einfaches Werkzeug, das genau für diesen Zweck entwickelt wurde.
Paul
Ah richtig, guter Punkt. Ich habe mich auf die Build-Backends konzentriert. Und ich dachte tatsächlich, pep517.buildeiner von ihnen. Aber überhaupt nicht, es ist eigentlich ein Build-Frontend. Auch Luke ist nicht PEP517 bereit, wie ich jetzt sehe.
Sinoroc
1
Ich habe meine Antwort aktualisiert, um Ihre Frage zu beantworten.
Paul
Ja super. Ich lösche meine Antwort.
Sinoroc
-1

Es gibt nichts "Offensichtliches", wenn es um Python-Verpackungen geht. In der Tat ist es vorerst erforderlich, zumindest wenn Sie distutils / setuptools verwenden, eine (fast) leere setup.pyDatei zu erstellen , selbst wenn Sie eine vollständig deklarative Datei verwenden setup.cfg:

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

Ich empfehle auch chmod +x setup.py.

In diesem Fall schreiben Sie nur den "Einstiegspunkt" selbst in das Build-System und setup()sind nur die main()Funktion dafür - aber jetzt setup()können setup.cfgstattdessen alle Argumente gelesen werden , an die traditionell übergeben wurde .

Jetzt können Sie immer noch verwenden, setup.py sdistwenn Sie einen Quell-Tarball erstellen möchten:

./setup.py sdist

Sie können auch eines der alternativen Build-Systeme ausprobieren, die über aktiviert sind pyproject.toml, z. B. Flit .

Leguananaut
quelle
Ich bin mir nicht sicher, warum dies abgelehnt wird. Es ist grundsätzlich richtig, auch wenn es andere Lösungen gibt.
Iguananaut
2
Der Fragentitel lautet "Wie erstelle ich eine Quelldistribution ohne die Datei setup.py?" Diese Antwort scheint nur zu demonstrieren, "hier erfahren Sie, wie Sie dieselbe setup.py-Datei neu erstellen, die Sie gerade gelöscht haben", was nicht hilfreich ist.
Schnabeltier
Ja, aber das beruhte auf einem Missverständnis, dass das Schreiben eines Deklarativs setup.cfgbedeutet, dass a setup.pynicht mehr erforderlich ist, um Setuptools zu verwenden, was nicht stimmt. Nur weil der Titel der Frage irreführend ist, heißt das nicht, dass die Antwort lautet. Sie schrieben in den Text der Frage: "Wie sollten Sie also die .tar.gz-Datei mit setuptools erstellen ?" was dies richtig beantwortet.
Iguananaut
1
Es ist tatsächlich wahr. setuptools benötigt keine setup.py-Datei, wenn Sie PEP 517 verwenden.
Paul
"Wenn Sie PEP 517 verwenden" Außer die meisten Menschen nicht. Es ist immer noch vorläufig und wird in package.python.org kaum erwähnt . Es ist nichts, was Sie hätten, wenn Sie nicht wissen, dass Sie danach suchen müssen. Wenn Sie nur möchten, dass Setuptools wie immer funktionieren, ist dies korrekt.
Iguananaut