2016-05-26 5 views
15

Ich erstelle eine setup.py Datei für ein Projekt mit einigen Cython-Erweiterungsmodulen.setup_requires mit Cython?

Ich habe schon bekommen dies funktioniert:

from setuptools import setup, Extension 
from Cython.Build import cythonize 

setup(
    name=..., 
    ..., 
    ext_modules=cythonize([ ... ]), 
) 

Das installiert in Ordnung. Dies setzt jedoch voraus, dass Cython installiert ist. Was ist, wenn es nicht installiert ist? Ich verstehe, das ist, was die setup_requires Parameter sind für:

from setuptools import setup, Extension 
from Cython.Build import cythonize 

setup(
    name=..., 
    ..., 
    setup_requires=['Cython'], 
    ..., 
    ext_modules=cythonize([ ... ]), 
) 

Wenn jedoch Cython nicht bereits installiert ist, wird dies natürlich fehlschlagen:

$ python setup.py install 
Traceback (most recent call last): 
    File "setup.py", line 2, in <module> 
    from Cython.Build import cythonize 
ImportError: No module named Cython.Build 

Was ist der richtige Weg, dies zu tun? Ich muss irgendwie importieren nur nach dem setup_requires Schritt läuft, aber ich brauche Cython, um die ext_modules Werte zu spezifizieren.

Antwort

4

Sie müssen die from Cython.Build import cythonize in einem try-except wickeln, und in den except, cythonize als Dummy-Funktion definieren. Auf diese Weise kann das Skript geladen werden, ohne dass ein Fehler mit einer ImportError auftritt.

Dann später, wenn das setup_requires Argument behandelt wird, wird Cython installiert und das Setup-Skript wird erneut ausgeführt. Da an diesem Punkt Cython installiert ist, werden Sie in der Lage sein, erfolgreich in den Kommentaren cythonize

try: 
    from Cython.Build import cythonize 
except ImportError: 
    def cythonize(*args, **kwargs): 
     from Cython.Build import cythonize 
     return cythonize(*args, **kwargs) 

EDIT

Wie bereits erwähnt zu importieren, nachdem Setuptools beschäftigt sich mit fehlenden Abhängigkeiten, wird es nicht wieder Last Cython. Ich hatte nicht vor daran gedacht, aber man könnte auch einen späte Bindung Ansatz versuchen, herauszufinden, stubbing cythonize

+0

Das ist etwas hacky, und doch ziemlich cool! Wusste nicht, dass das Skript neu ausgeführt wird, das macht sehr viel Sinn. – Claudiu

+0

Hmm, wenn ich also installiere, ohne dass Cython zuerst installiert wurde, funktioniert das Setup (es installiert Cython), aber die Erweiterungsmodule sind nicht installiert (können nicht aus Skripten importiert werden). Irgendwelche Ideen, was passieren könnte? – Claudiu

+0

Neugierig. Ah, es muss nicht wirklich neu ausgeführt werden. Normalerweise benötige ich 'Cython' nicht für die Installation, sondern nur für die Entwicklung. Anstatt "Extension" -Instanzen mit "cythonize" zu erstellen, erstellen Sie sie einfach direkt in den 'Cython'-generierten .c-Dateien. Überprüfen Sie dieses Beispiel https://github.com/mobiusklein/brainpy/blob/master/setup.py – mobiusklein

17

ab 18.0 Freisetzung von setuptools (veröffentlicht am 2015.06.23) ist es möglich Cython in setup_requires angeben und übergeben *.pyx Module Quellen für regelmäßige setuptools.Extension:

from setuptools import setup, Extension 


setup(
    # ... 
    setup_requires=[ 
     # Setuptools 18.0 properly handles Cython extensions. 
     'setuptools>=18.0', 
     'cython', 
    ], 
    ext_modules=[ 
     Extension(
      'mylib', 
      sources=['src/mylib.pyx'], 
     ), 
    ], 
) 
+0

Große Antwort, danke! Würden Sie diesen Ansatz neben dem Ansatz bevorzugen, bei dem Cython-Dateien im Voraus kompiliert werden und .c-Dateien in setup.py verwendet werden, was bedeutet, dass Cython zum Erstellen des Pakets nicht benötigt wird? – Martinsos

+1

@Martinsos unter der Annahme, dass Cython auf allen Zielplattformen mithilfe von setuptools installierbar ist (sollte es, aber es gibt immer Ausnahmen), die Verwendung spezifizierter Ansatz entfernt Schwierigkeiten, diese zu generieren.c-Dateien während der Bibliotheksbereitstellung, ohne etwas zu verlieren, also würde ich diesen Ansatz empfehlen. Die einzige Ausnahme, wenn dieser Prozess nicht funktioniert, z.B. wenn du System mit sehr alten setuptools anvisierst, was ich standardmäßig nicht tun würde. – rutsky