Ich möchte ein Python-Paket erstellen, das Cython- Code enthält. Ich habe den Cython-Code gut funktionieren lassen. Jetzt möchte ich jedoch wissen, wie ich es am besten verpacken kann.
Für die meisten Leute, die nur das Paket installieren möchten, möchte ich .c
die von Cython erstellte Datei einschließen und veranlassen, diese setup.py
zu kompilieren, um das Modul zu erstellen. Dann muss Cython nicht installiert werden, um das Paket zu installieren.
Aber für Leute , die das Paket ändern möchten, würde ich auch wie die Cython bieten .pyx
Dateien, und irgendwie auch erlauben setup.py
sie Cython mit aufzubauen (so die Benutzer würden brauchen Cython installiert ist ).
Wie soll ich die Dateien im Paket strukturieren, um diese beiden Szenarien zu berücksichtigen?
Die Cython-Dokumentation gibt eine kleine Anleitung . Es heißt jedoch nicht, wie man eine Single erstellt setup.py
, die beide Fälle mit / ohne Cython behandelt.
Antworten:
Ich habe dies jetzt selbst in einem Python-Paket gemacht
simplerandom
( BitBucket repo - EDIT: jetzt github ) (Ich erwarte nicht, dass dies ein beliebtes Paket ist, aber es war eine gute Chance, Cython zu lernen).Diese Methode basiert auf der Tatsache, dass beim Erstellen einer
.pyx
Datei mitCython.Distutils.build_ext
(zumindest mit Cython Version 0.14) immer eine.c
Datei im selben Verzeichnis wie die Quelldatei.pyx
erstellt wird.Hier ist eine gekürzte Version, von
setup.py
der ich hoffe, dass sie das Wesentliche zeigt:Ich habe auch bearbeitet,
MANIFEST.in
um sicherzustellen, dassmycythonmodule.c
es in einer Quelldistribution enthalten ist (eine Quelldistribution, mit der erstellt wirdpython setup.py sdist
):Ich verpflichte mich nicht
mycythonmodule.c
zur Versionskontrolle 'trunk' (oder 'default' für Mercurial). Wenn ich eine Veröffentlichung mache, muss ich daran denken, einepython setup.py build_ext
erste zu machen, um sicherzustellen, dass diesemycythonmodule.c
für die Verteilung des Quellcodes vorhanden und aktuell ist. Ich mache auch einen Release-Zweig und schreibe die C-Datei in den Zweig. Auf diese Weise habe ich eine historische Aufzeichnung der C-Datei, die mit dieser Version verteilt wurde.quelle
Hinzufügen zu Craig McQueens Antwort: Im Folgenden
sdist
erfahren Sie, wie Sie den Befehl überschreiben , damit Cython Ihre Quelldateien automatisch kompiliert, bevor Sie eine Quelldistribution erstellen.Auf diese Weise besteht kein Risiko, dass veraltete
C
Quellen versehentlich verteilt werden . Dies ist auch hilfreich, wenn Sie nur begrenzte Kontrolle über den Verteilungsprozess haben, z. B. wenn Sie automatisch Verteilungen aus der kontinuierlichen Integration usw. erstellen.quelle
http://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
quelle
Am einfachsten ist es, beide einzuschließen, aber nur die C-Datei zu verwenden? Das Einfügen der .pyx-Datei ist nett, wird aber nicht benötigt, sobald Sie die .c-Datei haben. Personen, die die .pyx-Datei neu kompilieren möchten, können Pyrex installieren und manuell ausführen.
Andernfalls benötigen Sie einen benutzerdefinierten Befehl build_ext für distutils, der zuerst die C-Datei erstellt. Cython enthält bereits eine. http://docs.cython.org/src/userguide/source_files_and_compilation.html
Was diese Dokumentation nicht tut, ist zu sagen, wie man dies bedingt, aber
Sollte damit umgehen.
quelle
setup.py
direkt aus der.pyx
Datei erstellt werden kann . Meine Antwort hat das auch umgesetzt.Das Einschließen von (Cython) generierten .c-Dateien ist ziemlich seltsam. Besonders wenn wir das in git aufnehmen. Ich würde lieber setuptools_cython verwenden . Wenn Cython nicht verfügbar ist, erstellt es ein Ei mit integrierter Cython-Umgebung und erstellt dann Ihren Code mithilfe des Eies.
Ein mögliches Beispiel: https://github.com/douban/greenify/blob/master/setup.py
Update (05.01.2017):
Da
setuptools 18.0
gibt es keine Notwendigkeit zu verwendensetuptools_cython
. Hier ist ein Beispiel, um ein Cython-Projekt von Grund auf ohne zu erstellensetuptools_cython
.quelle
'setuptools>=18.0'
setup_requires einzugeben, anstatt die Methode zu erstellenis_installed
?setuptools>=18.0
installiert wurde, dann müssen Sie nur setzen'Cython >= 0.18'
insetup_requires
und Cython wird während der Installation Fortschritte installiert werden. Wenn Sie jedoch setuptools <18.0 verwenden, selbst wenn Sie in setup_requires ein bestimmtes Cython verwenden, wird es nicht installiert. In diesem Fall sollten Sie die Verwendung in Betracht ziehensetuptools_cython
.pip install wheel
. Dann muss es Grund 1 sein. Bitte zuerst das Rad einbauen und es erneut versuchen.Dies ist ein Setup-Skript, das ich geschrieben habe und das es einfacher macht, verschachtelte Verzeichnisse in den Build aufzunehmen. Man muss es aus einem Ordner innerhalb eines Pakets ausführen.
Gegebene Struktur wie folgt:
setup.py
Viel Spaß beim Kompilieren;)
quelle
Der einfache Hack, den ich mir ausgedacht habe:
Installieren Sie einfach Cython, wenn es nicht importiert werden konnte. Man sollte diesen Code wahrscheinlich nicht teilen, aber für meine eigenen Abhängigkeiten ist er gut genug.
quelle
Alle anderen Antworten stützen sich entweder auf
Cython.Build
, wodurch ein Henne-Ei-Problem zwischen dem Erfordernis von Cython übersetup_requires
und dem Importieren entsteht.Eine moderne Lösung besteht darin, stattdessen Setuptools zu verwenden (siehe diese Antwort) (für die automatische Behandlung von Cython-Erweiterungen sind Setuptools 18.0 erforderlich, dh sie sind bereits seit vielen Jahren verfügbar). Ein moderner Standard
setup.py
mit Anforderungshandhabung, einem Einstiegspunkt und einem Cython-Modul könnte folgendermaßen aussehen:quelle
Cython.Build
zur Setup-Zeit verursacht für mich ImportError. Setuptools zum Kompilieren von Pyx sind der beste Weg, dies zu tun.Der einfachste Weg, den ich gefunden habe, nur Setuptools anstelle der Feature-Limited Distutils zu verwenden, ist
quelle
Cython.Build
, siehe meine Antwort.Ich denke, ich habe einen ziemlich guten Weg gefunden, dies zu tun, indem ich einen benutzerdefinierten
build_ext
Befehl bereitgestellt habe . Die Idee ist die folgende:Ich füge die Numpy-Header hinzu, indem ich sie überschreibe
finalize_options()
undimport numpy
im Hauptteil der Funktion ausführe, wodurch das Problem vermieden wird, dass Numpy vor dersetup()
Installation nicht verfügbar ist.Wenn Cython auf dem System verfügbar ist, wird es in die
check_extensions_list()
Methode des Befehls eingebunden und alle veralteten Cython-Module cythonisiert und durch C-Erweiterungen ersetzt, die später von derbuild_extension()
Methode verarbeitet werden können. Wir stellen nur den letzten Teil der Funktionalität in unserem Modul zur Verfügung: Dies bedeutet, dass Cython, wenn es nicht verfügbar ist, aber eine C-Erweiterung vorhanden ist, weiterhin funktioniert, sodass Sie Quelldistributionen durchführen können.Hier ist der Code:
Dies ermöglicht es einem, nur die
setup()
Argumente zu schreiben , ohne sich um Importe zu kümmern und ob man Cython zur Verfügung hat:quelle