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

时间:2016-11-30 10:52:49

标签: python

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

5 个答案:

答案 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错误。

Ast Module

的文档

如果无法加载抽象语法树,那么您可能必须检查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不兼容,它将显示警告。

以下是显示打印命令语法警告的屏幕截图。 enter image description here

答案 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来显示所有选项。