我正在使用openstack/bandit进行静态代码分析。有很多个代码库,其中一些是用Python 2编写的,另一些是用Python 3编写的。如何在不运行代码的情况下检测代码是否与Python 3的语法兼容。
我正在使用openstack/bandit进行静态代码分析。有很多个代码库,其中一些是用Python 2编写的,另一些是用Python 3编写的。如何在不运行代码的情况下检测代码是否与Python 3的语法兼容。
基本验证方法是检查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
以下是需要翻译的内容:
这里有一件你可能想做的事情。我认为这是你可以知道代码是否至少在语法上兼容的最简单方法。
编写一个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")
from __future__ import division
以在Python2和Python3中具有相同的行为。code_data
是如何得到的。 - Stefan Pochmann确保你的代码在语法上与Python3兼容的最基本验证是针对该特定模块运行pylint3并查找错误。
安装pylint3
sudo apt-get install pylint3
运行pylint3检查Python模块
pylint3 -E <module.py>
上述内容可用于捕获模块在Python3方面的语法错误。
python3.6 -m compileall -q .
根据您想要使用的Python版本做适当修改。
自Python3(从3.x开始)以来,编译后的模块会被放置到一个名为__pycache__
的目录中,并带有特定于架构的扩展名,因此它们不会与Python2或其他Python3版本冲突。
给定的命令只会显示错误,并从当前目录递归。使用python3.6 -m compileall --help
可以显示所有选项。
print((42))
替换print(42)
,很痛苦。所以你会看到一个差异并认为它是Python 2吗? - Stefan Pochmannprint("testing")
没有被修改。 - Jann