检查代码是否有弃用警告 [英] Checking code for deprecation warnings

查看:79
本文介绍了检查代码是否有弃用警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下示例代码:

data = []
try:
    print data[0]
except IndexError as error:
    print error.message

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

There is nothing syntactically wrong (using Python2.7) with the code except that if you run python with warnings turned on, you would see a 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

仅供参考,这是因为 .message 是从 python2.6 开始弃用,在 python3 中删除.

FYI, this is because .message was deprecated since python2.6 and removed in python3.

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

Now, I'd like to find all places in the project where .message is called on any exception instance by using static code analysis tools. As an end goal, I'm planning to have this check running as a part of a daily build&test&code quality check task and raise an error if the syntax is still used.

有可能吗?pylintpyflakes 或其他代码分析工具能做到吗?

Is it possible? Is it something that pylint, pyflakes or other code analysis tools are capable of?

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

I found that pep8 tool has several similar checks implemented, for instance, has_key() usage check:

$ 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'

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

As an alternative solution, I can treat all warnings as errors (like suggested here) and make my tests fail but this has its disadvantages:

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

推荐答案

既然你想静态地做到这一点,你可以使用 ast 模块来解析代码,然后扫描它以查找任何出现的带有 NodeVisitor 类的子类的弃用代码.像这样:

Since you want to do this statically, you can use the ast module to parse the code and then scan it for any occurrence of the deprecated code with a subclass of the NodeVisitor class. Like so:

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()))

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

This works by using python parse the source file into an AST and then uses the visitor pattern to walk through the entire file and find any instances of the deprecated attribute. For more information on how this works, see the python documentation on the ast module.

请注意,如果您使用一些巧妙的方法来引用异常对象,这将不起作用.它只是获取异常对象绑定到的变量名称,并检查是否曾经从异常处理程序主体内的同名变量访问过 message 属性.

Note that this won't work if you use something clever to refer to the exception object. It simply takes the variable name that the exception object was bound to and checks if a message attribute is ever accessed from a variable of the same name inside the body of the exception handler.

这篇关于检查代码是否有弃用警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆