检查弃用警告的代码

ale*_*cxe 9 python static-code-analysis python-2.7 deprecation-warning

请考虑以下示例代码:

data = []
try:
    print data[0]
except IndexError as error:
    print error.message
Run Code Online (Sandbox Code Playgroud)

在代码中没有任何语法错误(使用Python2.7),除非你打开警告并运行python ,你会看到DeprecationWarning:

$ python -W always test.py
test.py:5: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
  print error.message
list index out of range
Run Code Online (Sandbox Code Playgroud)

仅供参考,这是因为.messagepython2.6已弃用并在python3中被删除.

现在,我想通过使用静态代码分析工具找到项目中所有.message在任何异常实例上调用的位置.作为最终目标,我计划将此检查作为日常构建和测试以及代码质量检查任务的一部分运行,并在语法仍然使用时引发错误.

可能吗?有什么事情pylint,pyflakes或其他代码分析工具能够?


我发现该pep8工具实现了几个类似的检查,例如,has_key()使用检查:

$ cat test.py
my_dict = {}
print my_dict.has_key('test')
$ pep8 test.py
test.py:2:14: W601 .has_key() is deprecated, use 'in'
Run Code Online (Sandbox Code Playgroud)

作为替代解决方案,我可以将所有警告视为错误(如此处所示)并使我的测试失败,但这有其缺点:

  • 还有来自第三方软件包的其他弃用警告我无法修复
  • 严格地说,这需要100%的覆盖率,这是难以维护的

ran*_*ame 7

由于您希望静态地执行此操作,因此可以使用该ast模块解析代码,然后使用NodeVisitor该类的子类对任何已弃用的代码进行扫描.像这样:

import ast, sys

class UsingMessageAttr(ast.NodeVisitor):

    error_object_names = []

    def visit_Attribute(self, node):
        if (node.attr == 'message' and 
            hasattr(node.value, 'id') and 
            node.value.id in self.error_object_names):

            print("Danger Will Robinson!!")
            sys.exit(1)

        self.generic_visit(node)

    def visit_ExceptHandler(self, node):
        if node.name is not None:
            self.error_object_names.append(node.name)
            self.generic_visit(node)
            self.error_object_names.pop()
        else:
            self.generic_visit(node)

with open('sourcefile.py', 'r') as f:
    UsingMessageAttr().visit(ast.parse(f.read()))
Run Code Online (Sandbox Code Playgroud)

这可以通过使用python将源文件解析为AST然后使用访问者模式遍历整个文件并查找不推荐使用的属性的任何实例来实现.有关其工作原理的更多信息,请参阅ast模块上的python文档.

请注意,如果您使用聪明的东西来引用异常对象,这将不起作用.它只是获取异常对象绑定的变量名称,并检查是否message从异常处理程序主体内的同名变量访问属性.