2012-01-13 17 views
6

¿Es posible usar Sphinx autodoc para generar documentación para mi fabfile, desde la función docstrings?Usando sphinx autodoc para un fabfile

E.g. para un fabfile que contiene una tarea setup_development he intentado:

.. automodule::fabfile 
    :members: 
    .. autofunction:: setup_development 

sino que se genera nada.

fabfile fragmento:

@task 
def setup_development(remote='origin', branch='development'): 
    """Setup your development environment. 

    * Checkout development branch & pull updates from remote 
    * Install required python packages 
    * Symlink development settings 
    * Sync and migrate database 
    * Build HTML Documentation and open in web browser 

    Args: 
     remote: Name of remote git repository. Default: 'origin'. 
     branch: Name of your development branch. Default: 'development'. 
    """ 
    <code> 
+1

Un problema es la falta de espacio entre '.. automodule ::' y 'fabfile'. Y si desea usar' ..autofunction :: '(No creo que lo necesite), debe ir precedido de una línea en blanco. – mzjn

+0

¡Gracias, eso funcionó! Parece que '': miembros: '' no recoge las funciones envueltas (según la respuesta dada por shahjapan) , así que puedo usar '' wraps'' o usar '' .. autofunction :: '' que funciona con el decorador '' @ task'' –

Respuesta

1

que era capaz de producir una documentación completa con la firma de función conservada mediante el uso de la receta decorator_applyfound in the documentation para el módulo decorator.

""" myfabfile.py """ 

from fabric.api import task as origtask 
from decorator import FunctionMaker 

def decorator_apply(dec, func): 
    return FunctionMaker.create(
     func, 'return decorated(%(signature)s)', 
     dict(decorated=dec(func)), __wrapped__=func) 

def task(func): 
    return decorator_apply(origtask, func) 

@task 
def setup_development(remote='origin', branch='development'): 
    """Setup your development environment. 

    * Checkout development branch & pull updates from remote 
    * Install required python packages 
    * Symlink development settings 
    * Sync and migrate database 
    * Build HTML Documentation and open in web browser 

    :param remote: Name of remote git repository. 
    :param branch: Name of your development branch. 
    """ 
    pass 

Ésta es la fuente simple descanso que he utilizado:

.. automodule:: myfabfile 
    :members: 

Algunos comentarios:

La respuesta presentada por shahjapan explica cómo preservar la cadena de documentación en el caso general, pero lo hace no aborda el hecho de que el decorador @task se define en una biblioteca externa.

De todos modos, resulta que el docstring se conserva automáticamente para las funciones decoradas con @task. El siguiente es en el método de la clase de tela tasks.WrappedCallableTask__init__:

if hasattr(callable, '__doc__'): 
    self.__doc__ = callable.__doc__ 

Así que ya funciona como es (una explícita .. autofunction:: se necesita). Para garantizar que la firma de la función también se conserve, el módulo decorator se puede usar como se muestra arriba.


actualización

El uso del módulo decorator rompe cosas en el funcionamiento de Tela (ver comentario). Entonces eso puede no ser factible después de todo. Como alternativa, sugiero la siguiente marcación reST modificada:

.. automodule:: myfabfile2 
    :members: 

    .. autofunction:: setup_development(remote='origin', branch='development') 

Es decir, deberá incluir la firma de la función completa. Esto también es lo que se sugiere en la documentación de Sphinx (vea "This is useful if the signature from the method is hidden by a decorator.").

+0

Esto funciona para autodoc, pero al usar este método el tejido ya no reconoce sus tareas decoradas '' fab --list'' enumera todas las funciones (este es el comportamiento alternativo para la compatibilidad con versiones anteriores), en cuyo caso sería más fácil omitir ' '@ task'' por completo. También evita que las tareas importadas se encuentren en otros archivos cuando se utiliza '' fabfile'' como módulo. –

+0

Supongo que la única manera entonces es duplicar los nombres de las funciones y las firmas en ambos archivos. Un poco de dolor, pero gracias por investigar. –

+0

Como realmente no hemos encontrado una manera de generar automáticamente documentos para un archivo fab, he creado un problema para Fabric en github: https://github.com/fabric/fabric/issues/569 –

3

Es porque usted ha solicitado decorador en su función de setup_development

que necesita para actualizar su función task con functools.wraps como abajo,

from functools import wraps 

def task(calling_func): 
    @wraps(calling_func) 
    def wrapper_func(self, *args, **kw): 
     return calling_func(*args, **kw) 
    return wrapper_func 

Si documentar funciones o métodos, tenga en cuenta que autodoc recupera sus documentos importando el módulo e inspeccionando el atributo __doc__ de la función o método dados.

Eso significa que si un decorador reemplaza la función decorada por otra, debe copiar el __doc__ original a la nueva función. De Python 2.5, functools.wraps() se puede utilizar para crear funciones de decoración de buen comportamiento.

Referencias:

+0

No puedo por mi vida hacer que esto funcione con el decorador de '' fabric.api.task'' existente. Cualquier cambio podría proporcionar el código específico para decorar este decorador existente para pasar '' __doc__'' Gracias. –

+0

@Matt Austin: Entonces 'autofunction' no funciona con '@ task' después de todo? – mzjn

+0

@mzjn autofunction funciona a medias, la información de docstring se genera, pero la función args/kwargs falta. –

Cuestiones relacionadas