Documentar Python con autodoc¶
Guidedog documenta Python leyendo su código fuente. No importa el paquete. Las docstrings y las firmas pasan a formar parte del grafo de documentos. Los objetos creados únicamente en tiempo de ejecución necesitan una descripción explícita. Este límite es deliberado.
Configuración inicial¶
Indique la extensión y la ubicación de los paquetes respecto al directorio de fuentes, como hace sys.path en Python:
extensions = ["sphinx.ext.autodoc"]
autodoc_source_paths = ["../src"]
guidedog migrate genera autodoc_source_paths a partir de las líneas de conf.py que localizan el paquete, como sys.path.insert(0, os.path.abspath('..')). Para encontrar un paquete instalado en otro lugar, debe añadir el directorio que lo contiene, por ejemplo el código fuente de una dependencia. Guidedog nunca busca en el propio site-packages de Python.
A continuación, las directivas funcionan como en Sphinx:
.. automodule:: shop.cart
:members:
:show-inheritance:
.. autoclass:: shop.Cart
:members: add, remove
:inherited-members:
Se aceptan todas las opciones de Sphinx 9.1 con el mismo significado: :members:, :undoc-members:, :private-members:, :special-members:, :inherited-members:, :exclude-members:, :member-order:, :show-inheritance:, :imported-members:, :ignore-module-all:, :class-doc-from:, :no-value:, :annotation:, :no-index:, :no-index-entry:, :synopsis:, :platform:, :deprecated: y las formas no- que anulan autodoc_default_options.
Opciones¶
Estas opciones de conf.toml usan los mismos nombres, valores y valores predeterminados que Sphinx.
autodoc_source_paths-
Opción propia de Guidedog: directorios donde se buscan los módulos de Python, por orden y con rutas relativas al directorio de fuentes. Solo se leen archivos dentro de ellos. Se rechazan los enlaces simbólicos que llevan fuera.
autoclass_content-
Docstrings que describen una clase:
"class"(predeterminado),"init"o"both". autodoc_class_signature-
"mixed"(predeterminado) o"separated", que documenta__init__como método. autodoc_default_options-
Tabla de opciones que recibe cada directiva, como
members = trueomember-order = "bysource". El valorfalseomite la opción. autodoc_docstring_signature-
true(predeterminado): una primera línea del docstring comoname(args) -> resultse usa como firma. autodoc_inherit_docstrings-
true(predeterminado): un miembro sin docstring hereda el de su clase base. autodoc_member_order-
"alphabetical"(predeterminado),"groupwise"o"bysource". autodoc_preserve_defaults-
false(predeterminado): muestra los valores predeterminados como los escribiríarepr();trueconserva la forma del código fuente. autodoc_typehints-
"signature"(predeterminado),"description"(en campos:type:y:rtype:),"both"o"none". autodoc_typehints_description_target-
"all"(predeterminado),"documented"o"documented_params". autodoc_typehints_format-
"short"(predeterminado) o"fully-qualified". autodoc_use_type_comments-
true(predeterminado): los comentarios# type:cuentan como anotaciones. strip_signature_backslash-
Duplica las barras inversas en las firmas, como Sphinx.
autodoc_mock_imports,autodoc_type_aliases,autodoc_warningiserror-
Se aceptan. No se importa ningún módulo, por lo que no hace falta simularlo; los alias de tipos no se aplican.
Cómo deduce Guidedog el comportamiento de Python¶
Los nombres se resuelven según las reglas de enlace de Python. En el __init__.py de un paquete, from .app import Flask hace que flask.Flask sea la clase definida en flask/app.py; autodoc la muestra con :canonical: flask.app.Flask. Las clases base se resuelven igual. El orden de resolución de métodos se calcula como en Python y los miembros heredados se leen del código de las bases. Los nombres importados solo bajo if TYPE_CHECKING: no existen en ejecución. Las anotaciones que los usan se conservan tal cual, como en Sphinx.
Los docstrings son las cadenas que guardaría Python: se procesan los escapes y se quita la sangría como lo hace el compilador de Python 3.13. La documentación de atributos se lee en los mismos lugares que en el analizador de Sphinx: comentarios #: al final de la asignación o justo encima, y una cadena literal inmediatamente después. Las firmas proceden de def. Para las clases se busca, como en Python, en __call__ de la metaclase, __new__ o __init__. En dataclass y NamedTuple se usan los campos. Las variantes @overload sustituyen la firma de la implementación.
Qué no puede saberse sin ejecutar Python¶
Cuando el código fuente no permite deducir el comportamiento de Python, Guidedog lo indica y nombra el objeto. Emite una advertencia si no puede documentarlo y una nota, visible con -v, si ofrece menos información que Sphinx.
- Un módulo compilado (
.so,.pyd) no tiene código fuente que leer: sus objetos no se encuentran. - Un valor creado al ejecutar código (
app = Flask(__name__),now = datetime.now()) no tiene:value:. Los valores predeterminados calculados se muestran como están escritos. - Una función creada por un decorador ajeno a las rutas de fuentes (
@click.command()) se documenta como la función original. - Una clase de un paquete fuera de las rutas de fuentes se nombra con la ruta desde la que se importó, que puede diferir del módulo que la define. Se desconocen sus miembros, la firma del constructor y los docstrings que podría transmitir por herencia.
- Se desconocen los docstrings de los tipos integrados. Por eso se omite un método sin docstring propio que lo heredaría de
dict. - No se ejecutan las extensiones de Python que procesan eventos de autodoc (
autodoc-process-docstring,autodoc-skip-member, etc.). - No se analizan módulos con una profundidad de anidación muy superior a la del código real; se emite
autodoc.too_deep. Python ya rechaza 200 niveles de paréntesis. Guidedog también rechaza cadenas de+con varios cientos de operandos. - El trabajo que puede multiplicarse tiene límites. La resolución de un nombre por importaciones y alias se detiene tras 48 pasos por ruta y 100,000 en total. Los alias de tipos y las constantes se expanden hasta 10,000 pasos; después se conserva su forma escrita. El MRO se recorre hasta 100 clases. Una directiva genera como máximo 10,000 directivas, con la advertencia
autodoc.limital superar el límite. Solo alcanza este último límite una clase que se contiene a sí misma bajo su propio nombre.
Añadir los directorios de fuentes de los paquetes que faltan a autodoc_source_paths resuelve la mayoría de estas limitaciones.
Reconstrucción¶
Cada archivo de Python leído por una directiva autodoc es una dependencia de la página. Al editarlo, la página se vuelve a leer en el siguiente build. Si no se encontró un objeto, su página se lee en cada build para detectarlo en cuanto aparezca en el código fuente.
Seguridad¶
La documentación se construye sin ejecutar el código del proyecto. Guidedog lee el código Python como texto, con el mismo confinamiento que aplica a los includes: solo dentro de autodoc_source_paths y sin seguir enlaces que salgan de esas rutas.