1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-17 11:58:13 +00:00
trezor-firmware/tools/trezor-pylint-plugin/trezor_pylint_plugin.py

74 lines
2.5 KiB
Python
Raw Normal View History

from astroid import nodes
from pylint.checkers import BaseChecker
from pylint.checkers.utils import check_messages
from pylint.interfaces import IAstroidChecker
class AsyncAwaitableChecker(BaseChecker):
__implements__ = IAstroidChecker
name = "async-awaitable-checker"
priority = -1
msgs = {
"W9999": (
'Async function "%s" is likely not meant to return an Awaitable.',
"async-awaitable-return",
"Used when an async function returns an Awaitable instead of the result.",
),
}
@check_messages("async-awaitable-return")
def visit_asyncfunctiondef(self, node: nodes.AsyncFunctionDef):
# Check if the return type is explicitly an Awaitable
if node.returns and "Awaitable" in node.returns.as_string():
self.add_message("async-awaitable-return", node=node, args=(node.name,))
class InternalModelComparisonChecker(BaseChecker):
"""Check that utils.INTERNAL_MODEL is only compared using '==' or '!='.
This is because the static replacer does not support 'in' or 'not in' comparisons,
so the comparison is compiled into all models and performed at runtime. This is
typically not what you want.
When multiple comparisons are necessary, you may need to silence another
pylint warning: # pylint: disable=consider-using-in
"""
__implements__ = IAstroidChecker
name = "internal-model-comparison-checker"
priority = -1
msgs = {
"W9998": (
"Only compare INTERNAL_MODEL using '==' or '!='.",
"internal-model-tuple-comparison",
"Used when utils.INTERNAL_MODEL is compared using 'in' or 'not in' with a tuple.",
),
}
@staticmethod
def _is_internal_model(node):
return (
isinstance(node, nodes.Attribute)
and node.attrname == "INTERNAL_MODEL"
and isinstance(node.expr, nodes.Name)
and node.expr.name == "utils"
)
@check_messages("internal-model-tuple-comparison")
def visit_compare(self, node: nodes.Compare):
if not self._is_internal_model(node.left):
return
if len(node.ops) != 1:
return
op, _right = node.ops[0]
if op in ("in", "not in"):
self.add_message("internal-model-tuple-comparison", node=node)
def register(linter):
"""Required method to auto register this checker."""
linter.register_checker(AsyncAwaitableChecker(linter))
linter.register_checker(InternalModelComparisonChecker(linter))