将sphinx autodoc用于fabfile

时间:2012-01-13 02:33:50

标签: python python-sphinx fabric autodoc

是否可以使用Sphinx autodoc从函数docstrings生成fabfile的文档?

E.g。对于包含我尝试过的setup_development任务的fabfile:

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

但没有生成任何东西。

fabfile片段:

@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>

2 个答案:

答案 0 :(得分:3)

因为您已在函数setup_development

上应用了装饰器

您需要使用task更新functools.wraps功能,如下所示

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

如果您记录修饰的函数或方法,请记住autodoc通过导入模块并检查给定函数或方法的__doc__属性来检索其文档字符串。

这意味着如果装饰器将装饰的函数替换为另一个,它必须将原始__doc__复制到新函数。 从Python 2.5开始,functools.wraps()可用于创建表现良好的装饰功能。

参考文献:

答案 1 :(得分:1)

通过使用found in the documentation模块的decorator_apply食谱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

这是我使用的简单ReST源:

.. automodule:: myfabfile
   :members:

一些意见:

shahjapan提交的答案解释了如何在一般情况下保留docstring,但它没有解决@task装饰器在外部库中定义的事实。

无论如何,事实证明,对于用@task修饰的函数,docstring会自动保留。以下是Fabric __init__类的tasks.WrappedCallableTask方法:

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

所以它已经按原样运行(需要一个明确的.. autofunction::)。为确保保留函数签名,可以使用decorator模块,如上所示。


<强>更新

使用decorator模块会破坏Fabric的工作方式(请参阅注释)。毕竟这可能是不可行的。作为替代方案,我建议使用以下修改的reST标记:

.. automodule:: myfabfile2
   :members: 

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

也就是说,您必须包含完整的功能签名。这也是Sphinx文档中的建议(参见"This is useful if the signature from the method is hidden by a decorator.")