From 101ba4ae09c0b9ae4a880c5ed0a9e9e64e550ba6 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 18 Jan 2023 09:09:19 +0000 Subject: [PATCH] scripts: pylint: Add argument parser abbreviation checker Adds a pylint checker for ensuring that the argument parser library is setup with abbreviations disabled. Signed-off-by: Jamie McCrae --- scripts/pylint/checkers/argparse-checker.py | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 scripts/pylint/checkers/argparse-checker.py diff --git a/scripts/pylint/checkers/argparse-checker.py b/scripts/pylint/checkers/argparse-checker.py new file mode 100644 index 0000000000..fb197a9b78 --- /dev/null +++ b/scripts/pylint/checkers/argparse-checker.py @@ -0,0 +1,54 @@ +# 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))