我正在使用openstack/bandit进行静态代码分析.有很多存储库,其中一些存在于python 2中的python 2中.如何在不运行代码的情况下检测代码是否在语法上与python 3兼容.
Jan*_*ann 12
如果2to3的工具打印任何的diff基本确认会(S.https://docs.python.org/3/library/2to3.html的基本用法)
在像..py这样的简单文件上:
import urllib2
print "printing something"
Run Code Online (Sandbox Code Playgroud)
你会得到:
> 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
Run Code Online (Sandbox Code Playgroud)
这是你可能想要做的一件事.我认为这是最简单的方法,您可以知道代码是否至少在语法上兼容.
有一个python3程序加载python模块(不执行它们).如果代码兼容,它将加载模块,如果不是......它将引发语法错误.
使用该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').read())
if not ast_tree:
print("File couldn't get loaded")
Run Code Online (Sandbox Code Playgroud)
如果无法加载代码,则会引发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%而没有实际运行它并比较结果.
小智 8
您可以确保您的代码在语法上与python3 兼容的最基本的验证是为该特定模块运行pylint3并查找错误。
安装pylint3
sudo apt-get install pylint3
Run Code Online (Sandbox Code Playgroud)
为 python 模块运行 pylint3
pylint3 -E <module.py>
Run Code Online (Sandbox Code Playgroud)
以上可用于捕获模块中与 python3 相关的语法错误。
您可以像这样使用“compileall”模块:
python3.6 -m compileall -q .
Run Code Online (Sandbox Code Playgroud)
根据您要使用的 python 版本进行适当修改。
Python3(自 3.something 起)将编译后的模块放入__pycache__目录中,并具有特定于 arch 的扩展,因此它们不会与 Python2 或其他 Python3 版本发生冲突。
给定的命令只会显示错误,并且将从当前目录递归。用于python3.6 -m compileall --help显示所有选项。