Cory Walker
Estoy tratando de usar Sphinx para documentar un proyecto de más de 5000 líneas en Python. Tiene alrededor de 7 módulos base. Hasta donde yo sé, para usar autodoc necesito escribir un código como este para cada archivo en mi proyecto:
.. automodule:: mods.set.tests
:members:
:show-inheritance:
Esto es demasiado tedioso porque tengo muchos archivos. Sería mucho más fácil si pudiera especificar que quiero que se documente el paquete ‘mods’. Sphinx podría luego revisar recursivamente el paquete y crear una página para cada submódulo.
¿Hay una característica como esta? Si no, podría escribir un script para hacer todos los archivos .rst, pero eso llevaría mucho tiempo.
etienne
Puedes comprobar esto guion que he hecho. Creo que te puede ayudar.
Esta secuencia de comandos analiza un árbol de directorios en busca de módulos y paquetes de python y crea archivos ReST de manera adecuada para crear documentación de código con Sphinx. También crea un índice de módulos.
ACTUALIZAR
Este script ahora es parte de Sphinx 1.1 como apidoc.
-
¿Dónde se supone que debes enviar los archivos? Intenté enviarlos a la carpeta _build predeterminada de Sphinx, pero al ejecutar
sphinx-build -b html . ./_build
no los recoge.– Cerín
6 de enero de 2011 a las 18:13
-
Debes ponerlos en el
source directory
(. en tu caso). El directorio _build es donde se crearán los archivos HTML. Consulte para obtener más información: sphinx.pocoo.org/tutorial.html#running-the-build– Étienne
6 de enero de 2011 a las 20:16
-
@Erienne: guión fantástico! justo lo que estaba buscando. Ojalá generara encabezados para clases individuales (el aspecto normal de esfinge no es agradable para las clases. Se pierden en módulos más grandes)
– jbenet
22 de diciembre de 2011 a las 14:40
-
Incluso sphinx-apidoc es bastante rudimentario. Para un paquete con uno o dos módulos, funciona bien, pero tenemos módulos profundamente anidados y sphinx-apidoc produce una salida bastante inmanejable.
– slacy
27/04/2012 a las 20:35
-
respuesta automática: añadir
.. include:: modules.rst
para ustedindex.rst
– Ciro Santilli OurBigBook.com
4 de abril de 2013 a las 13:27
james leedham
Desde Sphinx versión 3.1 (junio de 2020), sphinx.ext.autosummary
(¡por fin!) tiene recursividad automática.
Por lo tanto, no es necesario codificar los nombres de los módulos ni depender de bibliotecas de terceros como Sphinx AutoAPI o Sphinx AutoPackageResumen para su detección automática de paquetes nunca más.
Ejemplo de paquete de Python 3.7 para documentar (ver código en Github y resultado en ReadTheDocs):
mytoolbox
|-- mypackage
| |-- __init__.py
| |-- foo.py
| |-- mysubpackage
| |-- __init__.py
| |-- bar.py
|-- doc
| |-- source
| |--index.rst
| |--conf.py
| |-- _templates
| |-- custom-module-template.rst
| |-- custom-class-template.rst
conf.py
:
import os
import sys
sys.path.insert(0, os.path.abspath('../..')) # Source code dir relative to this file
extensions = [
'sphinx.ext.autodoc', # Core library for html generation from docstrings
'sphinx.ext.autosummary', # Create neat summary tables
]
autosummary_generate = True # Turn on sphinx.ext.autosummary
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
index.rst
(nota nueva :recursive:
opción):
Welcome to My Toolbox
=====================
Some words.
.. autosummary::
:toctree: _autosummary
:template: custom-module-template.rst
:recursive:
mypackage
Esto es suficiente para resumir automáticamente todos los módulos del paquete, por muy anidados que estén. Para cada módulo, luego resume cada atributo, función, clase y excepción en ese módulo.
Curiosamente, sin embargo, el valor predeterminado sphinx.ext.autosummary
las plantillas no continúan generando páginas de documentación separadas para cada atributo, función, clase y excepción, y se vinculan a ellas desde las tablas de resumen. Es posible extender las plantillas para hacer esto, como se muestra a continuación, pero no puedo entender por qué este no es el comportamiento predeterminado; seguramente eso es lo que la mayoría de la gente querría… Lo he planteado como una solicitud de función..
Tuve que copiar las plantillas predeterminadas localmente y luego agregarlas:
- Copiar
site-packages/sphinx/ext/autosummary/templates/autosummary/module.rst
amytoolbox/doc/source/_templates/custom-module-template.rst
- Copiar
site-packages/sphinx/ext/autosummary/templates/autosummary/class.rst
amytoolbox/doc/source/_templates/custom-class-template.rst
el gancho en custom-module-template.rst
es en index.rst
arriba, usando el :template:
opción. (Elimine esa línea para ver qué sucede con las plantillas de paquetes de sitio predeterminadas).
custom-module-template.rst
(líneas adicionales anotadas a la derecha):
{{ fullname | escape | underline}}
.. automodule:: {{ fullname }}
{% block attributes %}
{% if attributes %}
.. rubric:: Module Attributes
.. autosummary::
:toctree: <-- add this line
{% for item in attributes %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block functions %}
{% if functions %}
.. rubric:: {{ _('Functions') }}
.. autosummary::
:toctree: <-- add this line
{% for item in functions %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block classes %}
{% if classes %}
.. rubric:: {{ _('Classes') }}
.. autosummary::
:toctree: <-- add this line
:template: custom-class-template.rst <-- add this line
{% for item in classes %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block exceptions %}
{% if exceptions %}
.. rubric:: {{ _('Exceptions') }}
.. autosummary::
:toctree: <-- add this line
{% for item in exceptions %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block modules %}
{% if modules %}
.. rubric:: Modules
.. autosummary::
:toctree:
:template: custom-module-template.rst <-- add this line
:recursive:
{% for item in modules %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
custom-class-template.rst
(líneas adicionales anotadas a la derecha):
{{ fullname | escape | underline}}
.. currentmodule:: {{ module }}
.. autoclass:: {{ objname }}
:members: <-- add at least this line
:show-inheritance: <-- plus I want to show inheritance...
:inherited-members: <-- ...and inherited members too
{% block methods %}
.. automethod:: __init__
{% if methods %}
.. rubric:: {{ _('Methods') }}
.. autosummary::
{% for item in methods %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block attributes %}
{% if attributes %}
.. rubric:: {{ _('Attributes') }}
.. autosummary::
{% for item in attributes %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
-
¡¡¡Muchas gracias por esto!!! Estuve a punto de rendirme y finalmente encontré esto. Una pregunta. yo estaba usando
sys.path.insert(0, os.path.abspath('../../mypackage'))
pero solo usas'../..'
. ¿Por qué no hace la diferencia?– Samlaf
6 de noviembre de 2020 a las 22:48
-
No hay problema, me alegro de que haya ayudado. Sphinx casi me vuelve loco hasta que me di cuenta; ahora todo funciona maravillosamente. En
index.rst
debe nombrar explícitamente el paquete donde desea:recursive:
extracción de docstring para comenzar, así que en mi ejemplomypackage
. Enconf.py
, solo proporciona la ruta a esa ubicación. Eso es porque en mi ejemplomypackage
es una carpeta de nivel superior enmytoolbox
pero si estaba (p. ej.) anidado en unsource/mypackage
subcarpeta entoncesconf.py
leería../../source
.– James Leedham
8 de noviembre de 2020 a las 9:58
-
@jamleed ¡Esto ha sido muy útil!. Gracias por tomarse el tiempo y escribir Sphinx AutoPackageSummary. Me ahorraste mucho tiempo. En ese proyecto de github, la parte make html (make.bat) no estaba disponible, por lo que el comando “make html” no funcionó de inmediato. Es posible que deba agregar algunas instrucciones al respecto o cargar ese archivo también. De lo contrario, funcionó como un encanto. (Editado – incluido el nombre de archivo que falta)
– SKG
17 de noviembre de 2020 a las 15:08
-
Esta respuesta vale oro, muchas gracias! Espero que su solicitud de función se implemente. De hecho, debería ser el comportamiento predeterminado.
– Rickstaa
24 de febrero de 2021 a las 15:47
-
Solo una pequeña mejora en
custom-module-template.rst
si agregas:members:
bajo la.. automodule:: {{ fullname }}
(línea 3), la documentación para ese módulo se completará automáticamente con miembros (clases, funciones, etc.) además del toctree. Esto brinda a los usuarios la opción de escanear rápidamente la documentación además de identificar funciones utilizando el toctree.– FullmetalIngeniero
11 de marzo de 2021 a las 16:57
firegurafiku
No sé si Sphinx había tenido autosummary
extensión en el momento en que se hizo la pregunta original, pero por ahora es muy posible configurar la generación automática de ese tipo sin usar sphinx-apidoc
o guión similar. A continuación hay configuraciones que funcionan para uno de mis proyectos.
-
Permitir
autosummary
extensión (así comoautodoc
) enconf.py
archivo y establezca suautosummary_generate
opción aTrue
. Esto puede ser suficiente si no está usando personalizado*.rst
plantillas. De lo contrario, agregue su directorio de plantillas a la lista de exclusión, oautosummary
intentará tratarlos como archivos de entrada (lo que parece ser un error).extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary'] autosummary_generate = True templates_path = [ '_templates' ] exclude_patterns = ['_build', '_templates']
-
Usar
autosummary::
en el árbol TOC en suindex.rst
archivo. En este ejemplo de documentación para módulosproject.module1
yproject.module2
se generará automáticamente y se colocará en_autosummary
directorio.PROJECT ======= .. toctree:: .. autosummary:: :toctree: _autosummary project.module1 project.module2
-
Por defecto
autosummary
generará solo resúmenes muy cortos para los módulos y sus funciones. Para cambiar eso, puede poner un archivo de plantilla personalizado en_templates/autosummary/module.rst
(que se analizará con Jinja2):{{ fullname }} {{ underline }} .. automodule:: {{ fullname }} :members:
En conclusión, no hay necesidad de mantener _autosummary
directorio bajo control de versiones. Además, puede ponerle el nombre que desee y colocarlo en cualquier lugar del árbol de fuentes (colocándolo debajo _build
aunque no funcionará).
-
Esto fue de gran ayuda. En el punto 2, donde tiene “project.module1” y “project.module2”, ¿hay alguna forma de generar automáticamente esa lista para cada módulo en un paquete determinado? ¿Simplemente poner “proyecto” y hacer que detecte “módulo1” y “módulo2”?
– Marrón
22 de junio de 2017 a las 21:24
-
Bastante sorprendido de que no pueda encontrar una respuesta a esto en ninguna parte, ¿alguna vez lo resolviste @Brown?
– Alisdair Robertson
9 de septiembre de 2017 a las 9:18
-
@AlisdairRobertson No, pero la solución de resumen automático provista terminó siendo más que adecuada para mis necesidades. Lo único que pensé en hacer fue escribir un script para generar el archivo index.rst y detectar automáticamente los nombres de los módulos. Sin embargo, en la práctica, la lista de módulos no cambia con tanta frecuencia, por lo que editar un archivo de vez en cuando no es tan descabellado. ¡Estoy seguro de que ya pasé mucho más tiempo buscando una solución de lo que se necesita para editar ese archivo!
– Marrón
13 de septiembre de 2017 a las 13:49
-
¿No hay otros pasos para esto? Actualizar a esto sigue siendo solo hacer el directorio actual y no recursivo. También veo: ADVERTENCIA: Error en la directiva “autosummary”: opción desconocida: “recursiva”. El directorio actual solo está hecho en html.
– lexalenka
1 de septiembre de 2021 a las 17:58
Sphinx AutoAPI hace exactamente esto.
S. Lott
En cada paquete, el __init__.py
archivo puede tener .. automodule:: package.module
componentes para cada parte del paquete.
Entonces tú puedes .. automodule:: package
y sobre todo hace lo que quieres.
-
¿Acabo de poner esa cadena entre comillas triples en en eso.py?
–Cory Walker
23 de abril de 2010 a las 21:36
-
@Cory Walker: No es una cadena “a”. Puedes – y debería — estar poniendo cadenas de documentos entre comillas triples en cada archivo. Todos. Eso incluye el
__init__.py
archivos en sus paquetes. La cadena de documentación puede incluir CUALQUIER directiva de documentación de Sphinx, incluidas.. automodule::
para módulos dentro del paquete.– S. Lott
24 de abril de 2010 a las 22:35
eduardo valle
Tal vez lo que estás buscando es Epydoc y esto Extensión de esfinge.
-
¿Acabo de poner esa cadena entre comillas triples en en eso.py?
–Cory Walker
23 de abril de 2010 a las 21:36
-
@Cory Walker: No es una cadena “a”. Puedes – y debería — estar poniendo cadenas de documentos entre comillas triples en cada archivo. Todos. Eso incluye el
__init__.py
archivos en sus paquetes. La cadena de documentación puede incluir CUALQUIER directiva de documentación de Sphinx, incluidas.. automodule::
para módulos dentro del paquete.– S. Lott
24 de abril de 2010 a las 22:35
Nadie dijo que fuera difícil. OP dijo que era tedioso, cual es. Dado que otros sistemas de documentos pueden hacer esto, no es irrazonable.
– Gregg Lind
26 de diciembre de 2010 a las 20:22
Solo usa pdoc.
– K3—rnc
15 de abril de 2020 a las 18:14