我正在使用openstack / bandit进行静态代码分析。有很多存储库,其中一些存在于python 2中的python 2中。如何在不运行代码的情况下检测代码是否在语法上与python 3兼容。
答案 0 :(得分:8)
如果2to3工具打印任何差异(s。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
答案 1 :(得分:7)
这是您可能想要做的一件事。我认为这是最简单的方法,你可以知道代码是否至少具有语法兼容性。
让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")
如果无法加载代码,则会引发SyntaxError
错误。
如果无法加载抽象语法树,那么您可能必须检查python3中不存在的python2方法或改变其行为的方法。
例如,python3和python2中的除法的工作方式不同。在python2中,除法除以整数,因此如果你不使用相同的除法方案,除法的结果将是不同的。在这种情况下,您必须查看模块是否导入from __future__ import division
以在python2和python3中具有相同的行为。
这里列出了您可能想要处理的详尽清单:
http://python-future.org/compatible_idioms.html
加载模块的ast将立即为您提供绝对无法工作的东西..但是知道可以解析的代码是否可以在python3中运行会受到许多误报。如果没有实际运行代码并比较结果,那么准确检测代码在python2和3中是否实际100%工作是很困难的。
答案 2 :(得分:4)
您可以使用Pycharm IDE。只需打开pycharm编辑器中的python文件,如果代码与Python2或Python3不兼容,它将显示警告。
答案 3 :(得分:2)
您可以做的最基本的验证来确保代码与python3兼容语法:为该特定模块运行 pylint3 并查找错误。
安装pylint3
Observable.of(1).pipe(
concatMap(()=> {if(this.dataStoreService.currentAppMode !== newMode){
this.saveToLocalStorage.next([DataType.STORED_RESULTS, null])};
return of(true)}))
.subscribe(result => this.saveToLocalStorage.next([DataType.WEB_APP_MODE, newMode]));
为Python模块运行pylint3
sudo apt-get install pylint3
以上内容可用于捕获有关python3的模块中的语法错误。
答案 4 :(得分:0)
您可以像这样使用“ compileall”模块:
python3.6 -m compileall -q .
针对要使用的python版本进行适当修改。
Python3(自3.something起)将编译后的模块放入具有拱形特定扩展名的__pycache__
目录中,因此它们不会与Python2或其他Python3版本冲突。
给定的命令将仅显示错误,并将从当前目录递归。使用python3.6 -m compileall --help
来显示所有选项。