2012-04-07 3 views
12

Ho recentemente Cythonized un mio progetto rinominando tutti i moduli (ad eccezione del livello superiore __init__.py) a *.pyx e inserendo ext_modules = [Extension('foo', ['foo.pyx'])] in setup.py. Costruire e installare funziona bene. Tuttavia, quando faccio cd doc; make html, Sphinx fallisce perché non può importare nessuno dei moduli che ora sono *.pyx.Come uso Sphinx con Cython?

Se modifico doc/conf.py e cambiare sys.path.insert(0, os.path.abspath('..')) a sys.path.insert(0, os.path.abspath('../build/temp.linux-x86_64-2.7')), poi Sfinge possono trovare tutti i moduli e possono generare la documentazione, ma in quel caso io ottenere errori come error while formatting arguments for foo.bar: <built-in function bar> is not a Python function. Presumibilmente questo perché ora Sphinx ha solo accesso ai file *.so, non ai file sorgente. La stessa modifica sys.path consente inoltre di eseguire i doctest tramite Sfinge (make doctest).

L'altra soluzione che ho provato era usare l'estensione *.py anziché *.pyx (e utilizzare ext_modules = [Extension('foo', ['foo.py'])] in setup.py). In questo caso, la documentazione viene compilata correttamente, ma penso che i doctest ora ignorino Cython.

Non sono stato in grado di trovare alcuna informazione online sull'utilizzo di Sphinx e Cython insieme. Ho esaminato il codice sorgente per alcuni progetti che utilizzano entrambi, ma non sembrano fare uso di docstrings nei file *.pyx. So che Sage lo fa, ma quel progetto è troppo complicato per me da scegliere.

Sphinx supporta le docstring nei file Cython? Se sì, come faccio a fare questo lavoro?

risposta

4

Sentiti libero di lasciare una risposta migliore, ma ecco una soluzione che ho trovato.

Il progetto dipy importa manualmente il proprio modulo da doc/conf.py. Ciò richiede che il modulo sia prima installato, ma corregge gli errori di importazione (e i doctest funzioneranno sui file Cythonized).

Tuttavia, il problema error while formatting arguments è ancora lì. Innanzitutto è necessario istruire Cython per incorporare le firme metodo/funzione nei file *.so. A tale scopo, impostare la direttiva embedsignature Cython. Il progetto dipy lo imposta in ciascun file *.pyx, ma è anche possibile impostarlo in setup.py (consultare la documentazione di Cython per sapere come farlo). Questo comunque non inserisce le firme del metodo nella documentazione di Sphinx! C'è un bug report e patch per il problema delle firme dei metodi here. Ad oggi non è ancora incluso nell'ultima versione di Sphinx (1.1.3), ma se si installa Sphinx dal repository di sviluppo funzionerà.

6

Sei un po 'confuso qui. Sfinge non è davvero un analista sintattico. Il tuo codice Python deve essere eseguibile per rendere Sphinx in grado di catturare le docstring. Ecco perché non rinominare i file di estensione in ".py".

Bene, ho lavorato di recente con Sphinx e Cython e vorrei condividere la mia esperienza ... Ecco la procedura dettagliata per ottenere la generazione automatica di una documentazione HTML per una determinata estensione Cython compilata da docstrings:

[Nota: ho usato Sphinx 1.1.3 e 0.17.4 Cython]

Prima di tutto, utilizzare "docstring" del Python (con tutti i limiti che può avere - per esempio, non si può descrivere un costruttore.Vedere docstrings specifiche) nel codice Cython:

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 

e ricompilare "yourextension.so".

Quindi eseguire "sphinx-quickstart" e rispondere alle domande. Non dimenticare di dire di sì quando viene richiesto "autodoc". Questo genererà il "Makefile", il file "index.rst" e i file "conf.py".

Quest'ultimo "conf.py" deve essere modificato per dire Sfinge sono stati per trovare il modulo:

# 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/')) 

Il file "index.rst" deve essere modificato anche per dire a quale modulo potrebbe essere analizzati:

Contents: 

.. toctree:: 
    :maxdepth: 2 


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

Infine costruire la documentazione da fare:

$ make html 

che era abbastanza per me (Ho ottenuto il set risultante di file html in una directory ".../_ build/html /"). Può essere che Sphinx e Cython si siano evoluti da quando è stata posta la domanda precedente, ma non ho avuto problemi di "firma" da affrontare. Nessuna particolare direttiva Cython da utilizzare, né alcuna correzione da applicare a Sphinx ...

Spero che questo aiuti.

EDIT: Bene, vorrei riprendere le mie parole. Ho incontrato il problema "Dan" stava menzionando riguardo alla questione "embedingegneria" durante l'utilizzo di Epydoc (quindi suppongo che questo sia un problema con Sphinx pure). L'attivazione di questa direttiva del compilatore non invia pitone firme conformi in ogni caso:

PyLabNode.SetNetwork(self, PyLabNetwork net) 

Questo ha 2 inconveniente: La notazione punteggiata per il prefisso di classe e il parametro digitato.

Alla fine, l'unico modo che ho potuto capire per inviare quei corretti è stato quello di scrivere una firma compatibile alla prima riga delle corde doc in questo modo:

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 

Spero che questo possa aiutare sia Sfinge e gli utenti Epydoc ...


EDIT: relativa alla __cinit__, sono stato in grado di generare il documento con successo con Epidoc (non provate con Sfinge) raddoppiando la descrizione , In questo modo:

# 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

Chi Sfinge, param dovrebbe essere documentato nella documentazione classe, non nel costruttore, in modo da sarà bello nella documentazione generata. –

0

Come Golgauth spiega, modulo autodoc della Sfinge prende le docstring dal .so, non il .pyx. Il modo più semplice di generare la documentazione, senza dover apportare alcuna modifica alla configurazione Sfinge quando cythonizing un modulo Python è quello di semplice compilazione dei moduli di estensione in atto prima di generare la documentazione:

python setup.py build_ext --inplace 

questo modo AutoDoc volontà trova i moduli di estensione accanto ai normali moduli Python e sarai in grado di generare la documentazione come ti aspetteresti.

per non rischiare di dimenticare questo passo è possibile modificare il Makefile generato da sphinx-quickstart per costruire i moduli di estensione prima di eseguire sphinx-build:

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