如何检测代码是否兼容 python 3

新手上路,请多包涵

我正在使用 openstack/bandit 进行静态代码分析。确实有很多存储库,其中一些在 python 2 中,其他在 python 3 中。如何在不运行代码的情况下检测代码是否在语法上与 python 3 兼容。

原文由 aisbaa 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 651
2 个回答

这是您可能想要做的一件事。我认为这是了解代码是否至少在语法上兼容的最简单方法。

让 python3 程序加载 python 模块(不执行它们)。如果代码兼容,它将加载模块,如果不兼容……将引发语法错误。

使用 ast 模块。

 import ast

def test_source_code_compatible(code_data):
    try:
        return ast.parse(code_data)
    except SyntaxError as exc:
        return False

ast_tree = test_source_code_compatible(open('file.py', 'rb').read())
if not ast_tree:
    print("File couldn't get loaded")

如果无法加载代码,则会引发 SyntaxError 错误。

Ast 模块 的文档

如果无法加载抽象语法树,那么您可能必须检查 python3 中不存在的 python2 方法或更改其行为的方法。

例如,python3 和 python2 中的划分工作方式不同。在 python2 中,除法以整数除法,因此如果不使用相同的除法方案,除法的结果将不同。在这种情况下,您必须查看模块是否正在导入 from __future__ import division 以在 python2 和 python3 中具有相同的行为。

以下是您可能想要处理的事情的详尽列表:

http://python-future.org/compatible_idioms.html

加载模块的 ast 将立即为您提供绝对无法工作的东西.. 但是知道可以解析的代码是否可以在 python3 中工作会受到许多误报的影响。如果不实际运行代码并比较结果,很难甚至不可能准确检测代码在 python2 和 3 中是否真的能 100% 工作。

原文由 Loïc Faure-Lacroix 发布,翻译遵循 CC BY-SA 4.0 许可协议

基本验证是 2to3 工具是否打印任何差异(基本用法见 https://docs.python.org/3/library/2to3.html

在像 a.py 这样的简单文件上:

 import urllib2

print "printing something"

你会得到:

> 2to3 a.py

 RefactoringTool: Skipping optional fixer: buffer
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: set_literal
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored a.py
--- a.py    (original)
+++ a.py    (refactored)
@@ -1,4 +1,4 @@
-import urllib2
+import urllib.request, urllib.error, urllib.parse

-print "printing something"
+print("printing something")

RefactoringTool: Files that need to be modified:
RefactoringTool: a.py

原文由 Jann 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题