2015-05-10 5 views
7

Diese setup.py:Collapse mehrere Submodule zu einer Cython Erweiterung

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Build import cythonize 

extensions = (
    Extension('myext', ['myext/__init__.py', 
         'myext/algorithms/__init__.py', 
         'myext/algorithms/dumb.py', 
         'myext/algorithms/combine.py']) 
) 
setup(
    name='myext', 
    ext_modules=cythonize(extensions) 
) 

Hat nicht die beabsichtigte Wirkung. Ich will es eine einzige myext.so produzieren, was es tut; aber wenn ich es aufrufen über

python -m myext.so 

ich:

ValueError: Attempted relative import in non-package 

aufgrund der Tatsache, dass myext Versuche .algorithms zu verweisen.

Irgendeine Idee, wie man das funktioniert?

+0

Kann Ihnen dieser Leitfaden helfen? https://github.com/cython/cython/wiki/PackageHierarchy –

+0

Ich hatte tatsächlich gelesen und befolgt das bereits; das Problem ist, dass sie keine einzige binäre Ausgabe haben. Sie erzeugen eine Binärdatei für jede Python-Datei. – Reinderien

Antwort

4

Zunächst einmal sollte ich beachten, dass es impossible ist, eine einzelne .so Datei mit Unterpaketen mit Cython zu kompilieren. Wenn Sie also Unterpakete benötigen, müssen Sie mehrere .so Dateien erzeugen, da jedes .so nur ein einzelnes Modul darstellen kann.

Zweitens scheint es nicht, dass Sie mehrere Cython/Python-Dateien kompilieren können (ich verwende speziell die Cython-Sprache) und verknüpfen Sie sie in einem einzigen Modul überhaupt.

Ich habe versucht, multiplizieren Cython-Dateien in eine einzige .so jeder Weise, sowohl mit distutils und mit manueller Kompilierung, und es immer zur Laufzeit zu importieren.

Es scheint in Ordnung zu sein, eine kompilierte Cython-Datei mit anderen Bibliotheken oder sogar anderen C-Dateien zu verknüpfen, aber etwas schief geht beim Verknüpfen zweier kompilierter Cython-Dateien, und das Ergebnis ist keine richtige Python-Erweiterung.

Die einzige Lösung, die ich sehen kann, besteht darin, alles als eine einzige Cython-Datei zu kompilieren. In meinem Fall habe ich meine setup.py bearbeitet eine einzelne .pyx Datei zu erzeugen, die wiederum include s jede .pyx Datei in meinem Quellverzeichnis:

includesContents = "" 
for f in os.listdir("src-dir"): 
    if f.endswith(".pyx"): 
     includesContents += "include \"" + f + "\"\n" 

includesFile = open("src/extension-name.pyx", "w") 
includesFile.write(includesContents) 
includesFile.close() 

Dann einfach extension-name.pyx kompilieren ich. Natürlich wird dadurch die inkrementelle und parallele Kompilierung unterbrochen, und es könnte zu zusätzlichen Namenskonflikten kommen, da alles in die gleiche Datei eingefügt wird. Auf der hellen Seite müssen Sie keine Dateien schreiben.

Ich würde sicherlich nicht eine bevorzugte Build-Methode nennen, aber wenn alles absolut in einem Erweiterungsmodul sein muss, ist dies die einzige Möglichkeit, wie ich es sehen kann.

Verwandte Themen