如何解决@deprecated装饰器对函数的使用
是否有一个linter能够检测到@deprecated
包中的deprecated
装饰器将其标记为已弃用的功能的使用情况?
例如在
from deprecated import deprecated
def realfun():
print('Hey there')
@deprecated(reason="this is a test")
def myfun():
realfun()
if __name__ == "__main__":
myfun()
以PYTHONWARNINGS="default::DeprecationWarning" python testfile.py
运行时,我会收到运行时警告,但pylint
,mypy
和flake8
似乎(至少是如何运行)对此感到满意呼叫myfun
。
解决方法
正如其他人所提到的,您必须编写一个自定义pylint
检查器。运作方式是定义一个pylint
的{{1}}的子类,并定义发出什么警告以及何时发出警告。
以下代码正是这样做的。它是针对BaseChecker
包的特定关键字参数量身定制的,但是通常只要有人使用称为deprecated
的修饰符来标记函数或类,它就可以正常工作,并且会发出deprecated
警告{ {1}}(可以随意更改,例如更改为错误)。它还应提供信息性消息。
要使用它,请将代码添加到名为(例如)pylint
的文件中,然后将包含W0001
的文件夹添加到deprecated_checker.py
或将源代码添加到{{ 1}}文件夹。然后,您可以通过运行带有选项deprecated_checker.py
的{{1}}来完成工作。
有关编写自己的检查器的更多信息,look here。
PYTHONPATH
如果您已完成所有操作,请整理存根文件pylint/checkers
pylint
使用命令--load-plugins=deprecated_checker
可以帮助您
from astroid.nodes import Call,ClassDef,FunctionDef,Name
from pylint.checkers import BaseChecker
from pylint.interfaces import IAstroidChecker
class DeprecatedChecker(BaseChecker):
__implements__ = IAstroidChecker
name = "no-deprecated"
priority = -1
msgs = {
"W0001": (
"%s %s is deprecated since version %s; reason: %s.","deprecated","Functions that have been marked via annotations as deprecated should not be used.",)
}
def __init__(self,linter=None):
super().__init__(linter)
def visit_decorators(self,node):
# Check if there are decorators
if node.nodes is None:
return
# Figure out whether its a class or function
# that is deprecated,and get relevant info
if isinstance(node.parent,ClassDef):
parent_type = "Class"
elif isinstance(node.parent,FunctionDef):
parent_type = "Function"
parent_name = node.parent.name
# Check each decorator to see if its deprecating
for decorator in node.get_children():
if isinstance(decorator,Call):
if decorator.func.name == "deprecated":
version = "(not specified)"
reason = "not specified"
if decorator.keywords is not None:
for kw in decorator.keywords:
if kw.arg == "version":
version = f'"{kw.value.value}"'
if kw.arg == "reason":
reason = f'"{kw.value.value}"'
self.add_message(
"deprecated",node=node.parent,args=(parent_type,parent_name,version,reason),)
elif isinstance(decorator,Name):
if decorator.name == "deprecated":
self.add_message(
"deprecated",args=(
parent_type,"(not specified)","not specified",),)
def register(linter):
linter.register_checker(DeprecatedChecker(linter))
,
您应该查看How to warn about class (name) deprecation,以便将自己的规则添加到皮棉中。没有用于标记弃用的标准库方法,因此它不会内置在工具中。最接近的是warnings
库中的特定类。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。