|  | # 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)) |