2012-04-07 33 views
12

Recientemente hice un proyecto mío mediante el cambio de nombre de todos los módulos (excepto el nivel superior __init__.py) al *.pyx, y poniendo ext_modules = [Extension('foo', ['foo.pyx'])] en setup.py. La construcción y la instalación funcionan bien. Sin embargo, cuando hago cd doc; make html, Sphinx falla porque no puede importar ninguno de los módulos que ahora son *.pyx.¿Cómo uso Sphinx con Cython?

Si edito doc/conf.py y cambiar sys.path.insert(0, os.path.abspath('..')) a sys.path.insert(0, os.path.abspath('../build/temp.linux-x86_64-2.7')), a continuación, Sphinx puede encontrar todos los módulos y puede generar la documentación, pero en ese caso, recibo errores como error while formatting arguments for foo.bar: <built-in function bar> is not a Python function. Presumiblemente, esto se debe a que ahora Sphinx solo tiene acceso a los archivos *.so, no a los archivos fuente. Esa misma modificación sys.path también permite ejecutar los doctests a través de Sphinx (make doctest).

La otra solución Probé estaba usando la extensión *.py en lugar de *.pyx (y usando ext_modules = [Extension('foo', ['foo.py'])] en setup.py). En este caso, la documentación se crea correctamente, pero creo que ahora los doctests omiten Cython.

No he podido encontrar ninguna información en línea sobre el uso de Sphinx y Cython juntos. He examinado el código fuente para algunos proyectos que usan ambos, pero no parecen hacer uso de docstrings en los archivos *.pyx. Sé que Sage sí, pero ese proyecto es demasiado complicado para separarlo.

¿Sphinx es compatible con documentos en archivos Cython? Si es así, ¿cómo hago que esto funcione?

Respuesta

4

Siéntase libre de dejar una respuesta mejor, pero aquí hay una solución que he encontrado.

El proyecto dipy importa manualmente su propio módulo desde doc/conf.py. Esto requiere que primero se instale el módulo, pero corrige los errores de importación (y los doctest se ejecutarán en los archivos de Cythonized).

Sin embargo, el problema error while formatting arguments todavía está allí. Primero, debe indicar a Cython que incruste las firmas de método/función en los archivos *.so. Haga esto configurando la directiva embedsignature Cython. El proyecto dipy establece esto en cada archivo *.pyx, pero también es posible configurarlo en setup.py (consulte la documentación de Cython para saber cómo hacerlo). ¡Sin embargo, esto aún no coloca las firmas de métodos en la documentación de Sphinx! Hay un informe de error y un parche para el problema de firmas de método here. Todavía no está incluido en la última versión de Sphinx a partir de ahora (1.1.3), pero si instala Sphinx desde el repositorio de desarrollo, funcionará.

6

Pareces un poco confundido aquí. Sphinx no es realmente un analizador sintáctico. Su código Python tiene que ser ejecutable para que Sphinx pueda atrapar las cadenas de documentos. Es por eso que renombrar los archivos de extensiones a ".py" no ayuda.

Bueno, he estado trabajando con Sphinx y Cython recientemente, y me gustaría compartir mi experiencia ... Aquí está el procedimiento detallado para obtener la generación automática de una documentación html para una extensión compilada de Cython de docstrings:

[Nota: he utilizado Sphinx 1.1.3 y 0.17.4 Cython]

en primer lugar, utilice "cadenas de documentación" de la pitón (con todas las limitaciones que puede tener - por ejemplo, no se puede describir un constructorVer docstrings especificaciones) en su código 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 

y recompilar "yourextension.so".

A continuación, ejecute "sphinx-quickstart" y responda las preguntas. No olvides decir que sí cuando te pregunten por "autodoc". Esto generará el archivo "Makefile", el archivo "index.rst" y los archivos "conf.py".

Esta última "conf.py" tiene que ser editado para contar Esfinge fueron para encontrar su módulo:

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

El archivo "index.rst" tiene que ser editado, así decir cuál podría ser el módulo analizados:

Contents: 

.. toctree:: 
    :maxdepth: 2 


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

Finalmente construir la documentación haciendo:

$ make html 

Eso fue suficiente para mí (Obtuve el conjunto resultante de archivos html en un directorio ".../_ build/html /"). Puede ser que Sphinx y Cython hayan evolucionado desde que se hizo la pregunta anterior, pero no tenía problemas de "firma" para tratar. Ninguna directiva particular de Cython para usar, ni ninguna corrección para aplicar a Sphinx ...

Espero que esto ayude.

EDIT: Bueno, me gustaría recuperar mis palabras. Me encontré con el problema que "Dan" mencionaba sobre el tema "Embedsignature" durante el uso de Epydoc (así que supongo que este es un problema con Sphinx también). La activación de esta directiva del compilador no envía las firmas que cumplen con pitón de todos modos:

PyLabNode.SetNetwork(self, PyLabNetwork net) 

Esto tiene 2 inconveniente: la notación para el prefijo de clase y el parámetro escrito.

Al final, la única manera de que pudiera averiguar para enviar las correctas fue escribir una firma conformes en la primera línea de las cadenas de documentación de este 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 

la esperanza que esto puede ayudar tanto Sphinx y los usuarios Epydoc ...


EDIT: en cuanto a la __cinit__, yo era capaz de generar el documento con éxito con Epidoc (no probé con Sphinx) al duplicar la descripción , De esta manera:

# 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

sobre Sphinx, parámetro debe ser documentada en la documentación de la clase, no en el constructor, por lo se verá bien en la documentación generada. –

0

Como explica Golgauth, módulo de autodoc de Sphinx toma las cadenas de documentación de la .so, no el .pyx. La forma más sencilla de generar la documentación sin tener que realizar ningún cambio a la configuración de la esfinge cuando cythonizing un módulo de Python es sencillo construir los módulos de extensión en su lugar antes de generar la documentación:

python setup.py build_ext --inplace 

De esa manera autodoc se encuentre los módulos de extensión junto con los módulos normales de Python y podrá generar la documentación como era de esperar.

Para no el riesgo de olvidar este paso se puede editar el Makefile generada por sphinx-quickstart para construir los módulos de extensión antes de ejecutar sphinx-build:

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