从Python代码中提取“额外”docstrings?
紧跟在类或函数声明之后的Python docstrings被放置在__doc__
属性中。从Python代码中提取“额外”docstrings?
问题:如何提取一个函数中稍后出现的额外“内部”文档字符串?
更新:这样的文字语句被编译器忽略。我可以通过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
通过提取文档字符串,所述测试运行框架能够产生输出是这样的:
Scenario: Adding two numbers
When I add 2 and 3 (PASS)
Then the result is 5 (FAIL)
AssertionError Traceback
...
我认为这将是比Behave采取Freshen,Lettuce,PyCukes的方法,这需要定义一个组合通道更简洁吃了每一步的功能。我不喜欢重复步骤的文本作为函数名称(@When("I add numbers") def add_numbers()
)。但是与普通的单元测试不同,文档将增加打印商业可读场景的能力以供参考。
你可以使用ast
模块解析您的测试,并手动行走树和安装测试等有这样做(你可以使用ast.NodeVisitor
或ast.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)
您可能也有兴趣konira。
由于编译器忽略了字面语句,所以不能。
>>> def foo():
... 'docstring'
... 3
... 'bar'
...
>>> dis.dis(foo)
4 0 LOAD_CONST 1 (None)
3 RETURN_VALUE
哦,回到制图板。 – Graham 2012-03-20 07:29:11
你可以使用'inspect.getsource(module)'获取源代码。你不需要'_ast'这个名字可以通过'ast'获得。 – jfs 2012-03-20 09:20:29
谢谢,更新! – zeekay 2012-03-20 09:25:58
我不确定你应该走'ast'路线,因为它本质上是为你的测试引入新的语法。如果有人忘记放置字符串会怎么样?等 也许你可以指定使用'with'语句的上下文并使用它们来构建整体测试。 – 2012-03-20 09:56:49