从 Python 代码中提取“额外”文档字符串?

Gra*_*ham 4 python docstring

紧跟在类或函数声明之后的 Python 文档字符串放置在__doc__属性中。

问题:如何提取函数中稍后出现的附加“内部”文档字符串?

更新:编译器会忽略此类文字语句。我可以通过 AST 找到他们(以及他们的线路号码)吗?


我为什么要问?

我有一个(尚未完全成熟的)想法,使用此类“内部”文档字符串来描述敏捷场景的给定/何时/然后部分:

def test_adding():
    """Scenario: Adding two numbers"""
    adder = Adder()
    """When I add 2 and 3"""
    result = adder.add(2, 3)
    """Then the result is 5"""
    assert result == 5
Run Code Online (Sandbox Code Playgroud)

通过提取文档字符串,测试运行框架可以生成如下输出:

Scenario: Adding two numbers
   When I add 2 and 3 (PASS)
   Then the result is 5 (FAIL)

AssertionError   Traceback
...
Run Code Online (Sandbox Code Playgroud)

我认为这比BehaveFreshenLettucePyCukes中采用的方法更简洁,这些方法需要为每个步骤定义一个单独的函数。我不喜欢必须将步骤文本作为函数名称重复 ( @When("I add numbers") def add_numbers())。但与普通的单元测试不同,文档字符串将添加打印出业务可读场景以供参考的功能。

zee*_*kay 5

您可以使用该模块解析您的测试ast,并手动遍历树并设置测试等。可能有更好的方法来执行此操作(您可能可以使用ast.NodeVisitororast.NodeTransfomer和访问者模式),但这里有一个示例:

import ast, inspect

def find_tests(module):
    # generate AST from module's source
    tree = ast.parse(inspect.getsource(module))
    # return tests in module, assuming they are top level function definitions
    return [node for node in tree.body if isinstance(node, ast.FunctionDef)]

def print_docstrings(test):
    for node in test.body:
        if isinstance(node, ast.Expr):
            # print lineno and docstring
            print node.value.lineno, node.value.s

if __name__ == '__main__':
    import test_adding
    for test in find_tests(test_adding):
        print_docstrings(test)
Run Code Online (Sandbox Code Playgroud)

浏览本次作品的您可能还对科尼拉感兴趣。