2012-04-07 3 views
12

Ich habe kürzlich ein Projekt von mir Cythonized durch Umbenennen aller Module (mit Ausnahme der obersten Ebene __init__.py) zu *.pyx, und indem ext_modules = [Extension('foo', ['foo.pyx'])] in setup.py setzen. Bauen und Installieren funktioniert gut. Wenn ich jedoch cd doc; make html mache, schlägt Sphinx fehl, weil es keines der Module importieren kann, die jetzt *.pyx sind.Wie benutze ich Sphinx mit Cython?

Wenn ich doc/conf.py bearbeiten und sys.path.insert(0, os.path.abspath('..')) zu sys.path.insert(0, os.path.abspath('../build/temp.linux-x86_64-2.7')) ändern, dann kann Sphinx können alle Module finden und Dokumentation erzeugen, aber in diesem Fall, dass ich Fehler wie error while formatting arguments for foo.bar: <built-in function bar> is not a Python function bekommen. Vermutlich liegt das daran, dass Sphinx jetzt nur Zugriff auf die *.so Dateien hat, nicht auf die Quelldateien. Die gleiche sys.path Modifikation ermöglicht auch das Ausführen der Doctests über Sphinx (make doctest).

Die andere Lösung, die ich versuchte, war die Verwendung der Erweiterung *.py anstelle von *.pyx (und ext_modules = [Extension('foo', ['foo.py'])] in setup.py). In diesem Fall wird die Dokumentation korrekt erstellt, aber ich denke, die Doctests umgehen Cython jetzt.

Ich konnte online keine Informationen über die Verwendung von Sphinx und Cython zusammen finden. Ich habe Quellcode für einige Projekte angeschaut, die beide verwenden, aber sie scheinen keine Docstrings in den *.pyx Dateien zu verwenden. Ich weiß, dass Sage das tut, aber dieses Projekt ist zu kompliziert, als dass ich es auseinander nehmen könnte.

Unterstützt Sphinx Docstrings in Cython-Dateien? Wenn ja, wie mache ich das?

Antwort

4

Fühlen Sie sich frei, eine bessere Antwort zu hinterlassen, aber hier ist eine Lösung, die ich gefunden habe.

Das Projekt dipy importiert manuell ein eigenes Modul von doc/conf.py. Dies erfordert, dass das Modul zuerst installiert wird, aber es behebt die Importfehler (und Doctests werden auf den Cythonized-Dateien ausgeführt).

Allerdings ist das error while formatting arguments Problem immer noch da. Zuerst müssen Sie Cython anweisen, die Methoden-/Funktionssignaturen in die *.so Dateien einzubetten. Tun Sie dies, indem Sie die embedsignature Cython-Direktive festlegen. Das dipy Projekt setzt dies in jeder *.pyx Datei, aber es ist auch möglich, es in setup.py zu setzen (siehe Cython Dokumentation, wie man das macht). Dies bringt die Methodensignaturen jedoch immer noch nicht in die Sphinx-Dokumentation! Es gibt einen Fehlerbericht und einen Patch für das Methodensignaturproblem here. Es ist immer noch nicht in der neuesten Sphinx-Version enthalten (1.1.3), aber wenn Sie Sphinx aus dem Entwicklungs-Repo installieren, wird es funktionieren.

6

Sie sehen ein wenig verwirrt hier. Sphinx ist nicht wirklich ein syntaktischer Analysator. Ihr Python-Code muss ausführbar sein, damit Sphinx die Docstrings abfangen kann. Aus diesem Grund hilft das Umbenennen der Erweiterungsdateien in ".py" nicht.

Nun, ich habe vor kurzem mit Sphinx und Cython gearbeitet und würde gerne meine Erfahrung teilen ... Hier ist das vollständige detaillierte Verfahren, um die automatisierte Generierung einer HTML-Dokumentation für eine bestimmte kompilierte Cython-Erweiterung von Docstrings zu erhalten:

[Anmerkung: ich verwendete Sphinx 1.1.3 und 0.17.4 Cython]

Vor allem die „Docstrings“ Python verwenden (mit allen Einschränkungen kann es haben - durch Beispiel können Sie nicht beschreiben ein Konstruktor.Siehe docstrings Spezifikationen) in Ihrem Cython Code:

cdef class PyLabNode: 
    """ 
    This is a LabNode !!! 
    """ 
    cdef LabNode* thisptr 
    cdef PyLabNetwork network 

    def __cinit__(self): 
     self.thisptr = new LabNode() 

    def __dealloc__(self): 
     if self.thisptr: 
      del self.thisptr 

    def SetNetwork(self, PyLabNetwork net): 
     """ 
     Set the network !!! 
     """ 
     self.network = net 

und neu kompilieren "yourextension.so".

Dann starten Sie "sphinx-quickstart" und beantworten Sie die Fragen. Vergessen Sie nicht, Ja zu sagen, wenn Sie nach "Autodoc" gefragt werden. Dadurch werden das "Makefile", die "index.rst" -Datei und die "conf.py" -Dateien erzeugt.

Dieser letzte „conf.py“ hat bearbeitet werden Sphinx zu sagen, waren Ihr Modul zu finden:

# If extensions (or modules to document with autodoc) are in another directory, 
# add these directories to sys.path here. If the directory is relative to the 
# documentation root, use os.path.abspath to make it absolute, like shown here. 
#sys.path.insert(0, os.path.abspath('.')) 
sys.path.insert(0, os.path.abspath('../../parent/dir/of/yourextension/')) 

Die „index.rst“ Datei muss auch bearbeitet werden, welches Modul zu sagen, könnte sein, analysiert:

Contents: 

.. toctree:: 
    :maxdepth: 2 


.. automodule:: yourextension 
    :members: 
    :undoc-members: 
    :show-inheritance: 

schließlich die Dokumentation bauen, indem Sie:

$ make html 

das war genug für mich (Ich habe die resultierende Menge von HTML-Dateien in einem Verzeichnis ".../_ build/html /"). Mag sein, dass Sphinx und Cython sich weiterentwickelt haben, seit die vorhergehende Frage gestellt wurde, aber ich hatte keine "Signatur" Probleme zu bewältigen. Keine bestimmte Cython-Anweisung zu verwenden, noch irgendeine zu Sphinx zu ...

Hoffe, das hilft.

EDIT: Nun, ich möchte meine Worte zurücknehmen. Ich stieß auf das Problem, das "Dan" bezüglich der "embedsignature" -Atmosphäre bei der Verwendung von Epydoc erwähnte (also nehme ich an, dass dies auch bei Sphinx ein Problem ist). Die Aktivierung dieser Compiler-Direktive konforme Signaturen nicht Python sowieso nicht senden:

PyLabNode.SetNetwork(self, PyLabNetwork net) 

Dies hat 2 Nachteil: Die Punktnotation für die Klasse Präfix und dem eingegebenen Parameter.

Am Ende ist die einzige Art, wie ich herausfinden konnte Richtigen senden war wie so eine nachgiebige Unterschrift auf der ersten Zeile der doc-Strings zu schreiben:

def SetNetwork(self, PyLabNetwork net): 
    """ 
    SetNetwork(self, net) 
    Set the net !!! 
    @param self: Handler to this. 
    @type self: L{PyLabNode} 
    @param net: The network this node belongs to. 
    @type net: L{PyLabNetwork} 
    """ 
    self.network = net 

Hope this sowohl Sphinx helfen und Epydoc Benutzer ...


EDIT: bezüglich der __cinit__, konnte ich das Dokument erfolgreich mit Epidoc erzeugen (nicht mit Sphinx versuchen) durch die Beschreibung Verdoppelung dies, wie:

# For Epydoc only (only used for docstring) 
def __init__(self, sim): 
    """ 
    __init__(self, sim) 
    Constructor. 
    @param sim: The simulator this binding is attached to. 
    @type sim: L{PyLabSimulatorBase} 
    """ 

# Real Cython init 
def __cinit__(self, PyLabSimulatorBase sim): 
    self.thisptr = new LabNetBinding() 
    self.sites = [] 
    simulator = sim 
+0

Über Sphinx, param in Klassendokumentation dokumentiert werden sollen, in Konstruktor nicht, so es wird in der generierten Dokumentation gut aussehen. –

0

Wie Golgauth erklärt, nimmt Sphinx Autodoc Modul die Docstrings vom .so, nicht die .pyx. Der einfachste Weg, um Ihre Dokumentation zu erzeugen, ohne dass Änderungen an der Sphinx-Konfiguration vornehmen zu müssen, wenn ein Python-Modul cythonizing ist einfach bauen die Erweiterungsmodule anstelle, bevor Sie die Dokumentation generieren: wird

python setup.py build_ext --inplace 

auf diese Weise Autodoc finde die Erweiterungsmodule neben den regulären Python-Modulen und kann die Dokumentation wie erwartet erzeugen.

nicht riskieren dieser Schritt zu vergessen Sie die Makefile von sphinx-quickstart erzeugt bearbeiten können die Erweiterungsmodule vor der Ausführung sphinx-build zu bauen:

html: 
    @cd /path/to/setup.py; python setup.py build_ext --inplace 
    ...