blob: fb197a9b7874e770d50f3445420e145fb3b53807 [file] [log] [blame] [edit]
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
from pylint.checkers import BaseChecker
import astroid
from astroid import nodes
class ZephyrArgParseChecker(BaseChecker):
"""Class implementing function checker for Zephyr."""
# The name defines a custom section of the config for this checker.
name = "zephyr-arg-parse"
# Register messages emitted by the checker.
msgs = {
"E9901": (
"Argument parser with abbreviations is disallowed",
"argument-parser-with-abbreviations",
"An ArgumentParser object must set `allow_abbrev=false` to disable "
"abbreviations and prevent issues with these being used by projects"
" and/or scripts."
)
}
# Function that looks at evert function call for ArgumentParser invocation
def visit_call(self, node: nodes.Call) -> None:
if isinstance(node.func, astroid.nodes.node_classes.Attribute) and \
node.func.attrname == "ArgumentParser":
abbrev_disabled = False
# Check that allow_abbrev is set and that the value is False
for keyword in node.keywords:
if keyword.arg == "allow_abbrev":
if not isinstance(keyword.value, astroid.nodes.node_classes.Const):
continue
if keyword.value.pytype() != "builtins.bool":
continue
if keyword.value.value is False:
abbrev_disabled = True
if abbrev_disabled is False:
self.add_message(
"argument-parser-with-abbreviations", node=node
)
return ()
# This is called from pylint, hence PyLinter not being declared in this file
# pylint: disable=undefined-variable
def register(linter: PyLinter) -> None:
linter.register_checker(ZephyrArgParseChecker(linter))