<p>正如其他人提到的,您必须编写一个定制的<code>pylint</code>检查器。其工作方式是定义一个子类<code>pylint</code>的<code>BaseChecker</code>的类,并定义要发出的警告以及何时发出警告</p>
<p>下面的代码正是这样做的。它有点适合于<code>deprecated</code>包的特定关键字参数,但通常当有人使用名为<code>deprecated</code>的装饰器来标记函数或类,并发出<code>pylint</code>警告<code>W0001</code>(可以随意更改,例如错误)时,它就可以工作。它还应提供信息性信息</p>
<p>要使用它,请将代码添加到名为<code>deprecated_checker.py</code>的文件中,然后将包含<code>deprecated_checker.py</code>的文件夹添加到<code>PYTHONPATH</code>或将源代码添加到<code>pylint/checkers</code>文件夹中。然后,您可以通过使用<code> load-plugins=deprecated_checker</code>选项运行<code>pylint</code>进行lint</p>
<p>有关编写自己的跳棋的更多信息,请<a href="http://pylint.pycqa.org/en/latest/how_tos/custom_checkers.html" rel="noreferrer">look here</a></p>
<pre class="lang-py prettyprint-override"><code>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",
node=node.parent,
args=(
parent_type,
parent_name,
"(not specified)",
"not specified",
),
)
def register(linter):
linter.register_checker(DeprecatedChecker(linter))
</code></pre>
<p>如果您已经完成了所有这些,那么linting存根文件<code>tmp.py</code></p>
<pre class="lang-py prettyprint-override"><code>from deprecated import deprecated
@deprecated
def fn_stmt():
pass
@deprecated(version="0.1.0")
def fn_version():
pass
@deprecated(reason="I'm mean")
def fn_reason():
pass
@deprecated(version="0.1.0", reason="I'm mean")
def fn_both():
pass
@deprecated
class ClassStmt:
pass
@deprecated(version="0.1.0")
class ClassVersion:
pass
@deprecated(reason="I'm mean")
class ClassReason:
pass
@deprecated(version="0.1.0", reason="I'm mean")
class ClassBoth:
pass
</code></pre>
<p>使用命令<code>pylint load-plugins=deprecated_checker disable=all enable=deprecated tmp.py</code>将获得</p>
<pre class="lang-sh prettyprint-override"><code>************* Module tmp
tmp.py:5:0: W0001: Function fn_stmt is deprecated since version (not specified); reason: (not specified). (deprecated)
tmp.py:9:0: W0001: Function fn_version is deprecated since version 0.1.0; reason: (not specified). (deprecated)
tmp.py:13:0: W0001: Function fn_reason is deprecated since version (not specified); reason: I'm mean. (deprecated)
tmp.py:17:0: W0001: Function fn_both is deprecated since version 0.1.0; reason: I'm mean. (deprecated)
tmp.py:20:0: W0001: Class ClassStmt is deprecated since version (not specified); reason: (not specified). (deprecated)
tmp.py:24:0: W0001: Class ClassVersion is deprecated since version 0.1.0; reason: (not specified). (deprecated)
tmp.py:28:0: W0001: Class ClassReason is deprecated since version (not specified); reason: I'm mean. (deprecated)
tmp.py:32:0: W0001: Class ClassBoth is deprecated since version 0.1.0; reason: I'm mean. (deprecated)
-
Your code has been rated at 5.29/10 (previous run: -2.35/10, +7.65)
</code></pre>