在我当前的工作环境中,我们生成了大量供内部使用的 Python 包(如果不是 100 也有 10 个)。每个包都有一些依赖关系,通常是内部和外部包的混合体,其中一些依赖关系是共享的。
当我们接近dependency hell ,更新依赖项成为一个耗时的过程。虽然我们关心新版本可能引入的功能变化,但同样重要(如果不是更重要)的是破坏代码的 API 变化。
尽管针对较新版本的依赖项运行单元/集成测试可以帮助我们发现一些问题,但我们的覆盖率还不够接近 100%,因此这不是一个稳健的策略。发行说明和变更日志有助于识别高级别的主要变更,但这些变更很少存在于内部开发的工具中,也没有足够的细节来理解新版本对(公共(public))API 的影响。
我正在寻找其他方法来自动执行此过程。
我希望能够自动比较 Python 包的两个版本并报告它们之间的 API 差异。特别是这将包括向后不兼容的更改,例如删除函数/方法/类/模块,向函数/方法/类添加位置参数以及更改函数/方法返回的项目数。作为一名开发人员,根据此生成的报告,我应该更深入地了解此版本更改将引入的代码级别影响,以及集成它所需的时间。
在其他地方,我们使用 C++ abi-compliance-checker正在查看 Java api-compliance-checker帮助完成这个过程。是否有适用于 Python 的类似工具?我发现了很多 lint/分析/重构工具,但没有一个提供这种级别的功能。我了解 Python 的动态类型将无法生成全面的报告。
如果不存在这样的工具,是否有任何库可以帮助实现解决方案?例如,我目前的方法是使用 ast.NodeVisitor遍历包并构建一棵树,其中每个节点代表一个模块/类/方法/函数,然后将此树与同一包的另一个版本的树进行比较。
编辑:发布问题后我发现了pysdiff这涵盖了我的一些要求,但仍然有兴趣查看替代方案。
编辑:还发现Upstream-Tracker would 是我希望得到的那种信息的一个很好的例子。
最佳答案
使用 AST 模块解析文件怎么样?
import ast
with file("test.py") as f:
python_src = f.read()
node = ast.parse(python_src) # Note: doesn't compile the src
print ast.dump(node)
ast 节点上有 walk 方法(描述 http://docs.python.org/2/library/ast.html )
astdump 可能有效(在 pypi 上可用)
这台过时的 pretty-print http://code.activestate.com/recipes/533146-ast-pretty-printer/
文档工具 Sphinx 还可以提取您要查找的信息。也许看一看。
因此遍历 AST 并构建一棵包含所需信息的树。一旦你有了一棵树,你就可以 pickle 它并稍后比较,或者将树转换为文本表示形式 您可以使用 difftools 或一些外部 diff 程序对文本文件进行 diff。
ast 有 parse() 和 compile() 方法。唯一的问题是我不完全确定解析后有多少信息可供您使用(因为您不想编译())。
关于Python API 兼容性检查器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21924287/