Wie steuern Sie, welche Dateien in einem Rad enthalten sind? Es scheint MANIFEST.in
nicht von verwendet zu werden python setup.py bdist_wheel
.
UPDATE :
Ich habe mich geirrt, was den Unterschied zwischen der Installation von einem Quell-Tarball und einem Rad betrifft. Die Quelldistribution enthält die in angegebenen Dateien MANIFEST.in
, das installierte Paket enthält jedoch nur Python-Dateien. Es sind Schritte erforderlich, um zusätzliche Dateien zu identifizieren, die installiert werden sollen, unabhängig davon, ob die Installation über die Quelldistribution, das Ei oder das Rad erfolgt. Paketdaten werden nämlich für zusätzliche Paketdateien und Datendateien für Dateien außerhalb Ihres Pakets wie Befehlszeilenskripte oder Systemkonfigurationsdateien benötigt.
Ursprüngliche Frage
Ich habe ein Projekt, in dem ich python setup.py sdist
mein Paket erstellt, MANIFEST.in
die eingeschlossenen und ausgeschlossenen Dateien gesteuert und Pyrom und Check-Manifest verwendet habe , um meine Einstellungen zu bestätigen.
Ich habe es kürzlich in dualen Python 2/3 Code konvertiert und eine setup.cfg mit hinzugefügt
[bdist_wheel]
universal = 1
Ich kann ein Rad mit bauen python setup.py bdist_wheel
, und es scheint wie gewünscht ein Universalrad zu sein. Es enthält jedoch nicht alle in angegebenen Dateien MANIFEST.in
.
Was wird installiert?
Ich habe tiefer gegraben und weiß jetzt mehr über Verpackung und Rad. Folgendes habe ich gelernt:
Ich lade zwei Paketdateien in das multigtfs-Projekt auf PyPi hoch :
multigtfs-0.4.2.tar.gz
- die Quell-Teerball, die alle Dateien enthältMANIFEST.in
.multigtfs-0.4.2-py2.py3-none-any.whl
- Die fragliche Binärverteilung.
Ich habe zwei neue virtuelle Umgebungen erstellt, beide mit Python 2.7.5, und jedes Paket installiert ( pip install multigtfs-0.4.2.tar.gz
). Die beiden Umgebungen sind nahezu identisch. Sie haben verschiedene .pyc
Dateien, die "kompilierten" Python-Dateien. Es gibt Protokolldateien, die die verschiedenen Pfade auf der Festplatte aufzeichnen. Die Installation von der Quell-Teerball enthält einen Ordner multigtfs-0.4.2-py27.egg-info
, in dem die Installation detailliert beschrieben ist, und die Radinstallation enthält einen multigtfs-0.4.2.dist-info
Ordner mit den Details dieses Vorgangs. Unter dem Gesichtspunkt des Codes, der das multigtfs-Projekt verwendet, gibt es jedoch keinen Unterschied zwischen den beiden Installationsmethoden.
Die von meinem Test verwendeten ZIP-Dateien wurden explizit nicht verwendet, sodass die Testsuite fehlschlägt:
$ django-admin startproject demo
$ cd demo
$ pip install psycopg2 # DB driver for PostGIS project
$ createdb demo # Create PostgreSQL database
$ psql -d demo -c "CREATE EXTENSION postgis" # Make it a PostGIS database
$ vi demo/settings.py # Add multigtfs to INSTALLED_APPS,
# Update DATABASE to set ENGINE to django.contrib.gis.db.backends.postgis
# Update DATABASE to set NAME to test
$ ./manage.py test multigtfs.tests # Run the tests
...
IOError: [Errno 2] No such file or directory: u'/Users/john/.virtualenvs/test/lib/python2.7/site-packages/multigtfs/tests/fixtures/test3.zip'
Zusätzliche Dateien angeben
Unter Verwendung der Vorschläge aus den Antworten fügte ich einige zusätzliche Anweisungen hinzu setup.py
:
from __future__ import unicode_literals
# setup.py now requires some funky binary strings
...
setup(
name='multigtfs',
packages=find_packages(),
package_data={b'multigtfs': ['test/fixtures/*.zip']},
include_package_data=True,
...
)
Dadurch werden die Zip-Dateien (sowie die README-Datei) im Ordner installiert, und die Tests werden jetzt ordnungsgemäß ausgeführt. Danke für die Vorschläge!
quelle
python setup.py bdist_wheel
. Weitere Informationen finden Sie in den Dokumenten unter Wheel.readthedocs.org (die meine Frage nicht beantworten) und auf pythonwheels.com .MANIFEST.in
und danninclude_package_data=True
zu setup.py hinzuzufügen .Antworten:
Haben Sie versucht,
package_data
in Ihrem zu verwendensetup.py
?MANIFEST.in
scheint auf Python-Versionen <= 2.6 ausgerichtet zu sein, ich bin mir nicht sicher, ob höhere Versionen es überhaupt sehen.Nachdem sie https://github.com/pypa/sampleproject erkundet haben ,
MANIFEST.in
heißt es:# If using Python 2.6 or less, then have to include package data, even though # it's already declared in setup.py include sample/*.dat
was zu implizieren scheint, dass diese Methode veraltet ist. Inzwischen
setup.py
erklären sie in:setup( name='sample', ... # If there are data files included in your packages that need to be # installed, specify them here. If using Python 2.6 or less, then these # have to be included in MANIFEST.in as well. package_data={ 'sample': ['package_data.dat'], }, ... )
(Ich bin nicht sicher, warum sie einen Platzhalter
MANIFEST.in
und einen Dateinamen gewählt habensetup.py
. Sie verweisen auf dieselbe Datei.)Dies scheint nicht nur einfacher zu sein, sondern auch zu implizieren, dass die
package_data
Route derMANIFEST.in
Methode überlegen ist . Nun, es sei denn, Sie müssen 2.6 unterstützen. In diesem Fall gehen meine Gebete an Sie.quelle
Bevor Sie Änderungen an vornehmen
MANIFEST.in
odersetup.py
alte Ausgabeverzeichnisse entfernen müssen. Setuptools speichert einige Daten zwischen und dies kann zu unerwarteten Ergebnissen führen.Wenn Sie dies nicht tun, erwarten Sie, dass nichts richtig funktioniert.
Das ist aus dem Weg.
Wenn Sie eine Quelldistribution (
sdist
) erstellen, können Sie eine der folgenden Methoden verwenden.Wenn Sie ein Rad (
bdist_wheel
) bauen, werdeninclude_package_data
undMANIFEST.in
ignoriert und Sie müssenpackage_data
und verwendendata_files
.INCLUDE_PACKAGE_DATA
Dies ist eine gute Option, wird aber
bdist_wheel
nicht berücksichtigt.setup( ... include_package_data=True ) # MANIFEST.in include package/data.json
DATA_FILES für Nicht-Paketdaten
Dies ist die flexibelste Option, da Sie eine beliebige Datei aus Ihrem Repo zu einem
sdist
oder hinzufügen könnenbdist_wheel
setup( .... data_files=[ ('output_dir',['conf/data.json']), ] # For sdist, output_dir is ignored! # # For bdist_wheel, data.json from conf dir in root of your repo # and stored at `output_dir/` inside of the sdist package. )
PACKAGE_DATA für Nicht-Python-Dateien im Paket
Ähnlich wie oben, aber zum Beispiel
bdist_wheel
legen Sie Ihre Datendateien in das Paket. Es ist identisch fürsdist
, hat aber mehr Einschränkungen alsdata_files
weil Dateien nur aus Ihrem Paket-Unterverzeichnis stammen können.setup( ... package_data={'package':'data.json'}, # data.json must be inside of your actual package )
quelle
glob
Musters hinzufügen ? Ichdata_files
('output_dir': ['conf/*.json'])
glob('conf/*.json')
,
nicht:
wie folgt sein :data_files=[('my_data', ['data/data_file'])],
Referenzdokument Ich hätte es bearbeitet, aber die Änderungen müssen 6 Zeichen lang sein ...include pkg/test/*.py
inMANIFEST.in
funktioniert gut (in setuptools 45.2.0).Sie können
package_data
unddata_files
in verwendensetup.py
, um zusätzliche Dateien anzugeben, aber es ist lächerlich schwer, sie richtig (und fehlerhaft) zu machen .Eine Alternative ist , zu verwenden ,
MANIFEST.in
und fügen Sieinclude_package_data=True
insetup()
Ihremsetup.py
wie hier angedeutet .Mit dieser Anweisung
MANIFEST.in
wird das verwendet, um die Dateien anzugeben, die nicht nur im Quell-Tarball / Zip, sondern auch im Wheel- und Win32-Installationsprogramm enthalten sein sollen. Dies funktioniert auch mit jeder Python-Version (ich habe an einem Projekt von py2.6 bis py3.6 getestet).UPDATE 2020: Es scheint, dass MANIFEST.in in Python 3 nicht mehr vom Rad geehrt wird, obwohl es sich immer noch im tar.gz befindet, selbst wenn Sie es einstellen
include_package_data=True
.So beheben Sie das: Sie müssen sowohl
include_package_data
als auch angebenpackages
.Wenn sich Ihr Python-Modul in einem Ordner "pymod" befindet, ist hier das entsprechende Setup:
setup( ... include_package_data = True, packages = ['pymod'], )
Wenn sich Ihre Python-Skripte im Stammverzeichnis befinden, verwenden Sie:
setup( ... include_package_data = True, packages = ['.'], )
Anschließend können Sie Ihre .whl-Datei mit einer Zip-Archivierungssoftware wie 7-zip öffnen, um zu überprüfen, ob sich tatsächlich alle gewünschten Dateien befinden.
quelle
package_data=...
wie in der anderen Antwort ist mit Gefahren behaftet (lesen Sie die Links und die Links hinter den Links)setup
innumpy.distutils.core
, kann ich nicht Räder an der Arbeit mitinclude_package_data=True
. Es hört nur zupackage_data
.Mit der Direktive data_files können Sie zusätzliche Dateien angeben, die installiert werden sollen . Ist es das, wonach du suchst? Hier ist ein kleines Beispiel:
from setuptools import setup from glob import glob setup( name='extra', version='0.0.1', py_modules=['extra'], data_files=[ ('images', glob('assets/*.png')), ], )
quelle
include_package_data
ist der richtige Weg, und es funktioniert für SDIST und Räder .Sie müssen es jedoch richtig machen, und ich habe Monate gebraucht, um das herauszufinden. Deshalb habe ich Folgendes gelernt.
Der Trick wird im Wesentlichen im Namen der Option angegeben
include_PACKAGE_data
: Die Datendateien müssen sich in einem Paketunterordner befindenDann und nur dann, wenn
include_package_data
ist wahrMANIFEST.in
(* siehe auch meine Anmerkung am Ende übersetuptools_scm
)dann werden die Datendateien aufgenommen.
Arbeitsbeispiel:
Vorausgesetzt, das Projekt hat die folgende Struktur und Dateien:
|- MANIFEST.in |- setup.cfg |- setup.py | \---foo |- __init__.py | \---data - example.png
Und die folgende Konfiguration:
Manifest.in:
setup.py
import setuptools setuptools.setup()
setup.cfg
[metadata] name = wheel-data-files-example url = www.example.com maintainer = None maintainer_email = [email protected] [options] packages = foo include_package_data = True
SDIST-Pakete und Ihre Räder, die Sie erstellen, enthalten auch die
example.png
Datendatei.(Anstelle von setup.cfg kann die Konfiguration natürlich auch direkt in setup.py angegeben werden. Dies ist jedoch für das Beispiel nicht relevant.)
Update: Für src-Layout-Projekte
Dies sollte auch für Projekte funktionieren, die ein src-Layout verwenden und folgendermaßen aussehen:
|- MANIFEST.in |- setup.cfg |- setup.py | \---src | \---foo |- __init__.py | \---data - example.png
Informieren Sie setuptools über das src-Verzeichnis, indem Sie Folgendes verwenden
package_dir
:setup.cfg
[metadata] name = wheel-data-files-example url = www.example.com maintainer = None maintainer_email = [email protected] [options] packages = foo include_package_data = True package_dir = =src
Und im Manifest den Pfad anpassen:
Manifest.in:
Hinweis: Bei Verwendung ist kein Manifest erforderlich
setuptools_scm
Wenn Sie setuptools verwenden und das
setuptools_scm
Plugin ( auf pypi ) hinzufügen , müssen Sie keine Manifest.in-Datei verwalten. Stattdessen sorgt setuptools_scm dafür, dass alle Dateien, die von git verfolgt werden, zum Paket hinzugefügt werden.In diesem Fall lautet die Regel für das Hinzufügen oder Nicht-Hinzufügen einer Datei zum SDIST / Wheel: Wenn und nur wenn
include_package_data
ist wahrdann werden die Datendateien aufgenommen.
quelle
data
ins Steuer zu setzen. Ich vermute, es ist meinsrc
basiertes Layout und die zusätzliche Indirektionsebene, die es einführt. Ich habe jetzt meindata
Verzeichnis wie vorgeschlagen in das Paketverzeichnis verschoben , aber stattdessen entferntMANIFEST.in
undinclude_package_data
verwendetpackage_data={'package': ['data/specific_file']}
. Alles ist golden für beidesdist
undbdist_wheel
. Viel Glück beim Verwenden von Globs mit all den impliziten beteiligten Unterverzeichnissen ... :-)numpy.distutils.core.setup
unterwegs eine Fortran-Erweiterung erstelle, aber dann musste ich auch zufällig importierensetuptools.setup
, damit derbdist_wheel
Befehl überhaupt funktioniert . Es baut das Rad, besteht aber darauf, es zu benutzenpackage_data
. Diese Frachtkult-Hacky-Sacky-Route, um zu einem funktionierenden Python-Paket zu gelangen, bringt mich dazu, die wenigen Haare herauszuziehen, die ich noch habe :-DIch hatte config / directory mit JSON-Dateien, die ich dem Radpaket hinzufügen musste. Also habe ich diese Zeilen hinzugefügt zu
MANIFEST.in
:Die folgende Richtlinie an
setup.py
:setup( ... include_package_data=True, )
Und nichts hat funktioniert. Bis ich eine leere Datei namens
__init__.py
insideconfig/
directory erstellt habe.(Python 3.6.7, Rad 3.6.7, Setuptools 39.0.1)
quelle