1# Copyright (c) 2023 Nordic Semiconductor ASA 2# SPDX-License-Identifier: Apache-2.0 3 4from __future__ import annotations 5 6from pylint.checkers import BaseChecker 7 8import astroid 9from astroid import nodes 10 11class ZephyrArgParseChecker(BaseChecker): 12 """Class implementing function checker for Zephyr.""" 13 14 # The name defines a custom section of the config for this checker. 15 name = "zephyr-arg-parse" 16 17 # Register messages emitted by the checker. 18 msgs = { 19 "E9901": ( 20 "Argument parser with abbreviations is disallowed", 21 "argument-parser-with-abbreviations", 22 "An ArgumentParser object must set `allow_abbrev=false` to disable " 23 "abbreviations and prevent issues with these being used by projects" 24 " and/or scripts." 25 ) 26 } 27 28 # Function that looks at evert function call for ArgumentParser invocation 29 def visit_call(self, node: nodes.Call) -> None: 30 if isinstance(node.func, astroid.nodes.node_classes.Attribute) and \ 31 node.func.attrname == "ArgumentParser": 32 abbrev_disabled = False 33 34 # Check that allow_abbrev is set and that the value is False 35 for keyword in node.keywords: 36 if keyword.arg == "allow_abbrev": 37 if not isinstance(keyword.value, astroid.nodes.node_classes.Const): 38 continue 39 if keyword.value.pytype() != "builtins.bool": 40 continue 41 if keyword.value.value is False: 42 abbrev_disabled = True 43 44 if abbrev_disabled is False: 45 self.add_message( 46 "argument-parser-with-abbreviations", node=node 47 ) 48 49 return () 50 51# This is called from pylint, hence PyLinter not being declared in this file 52# pylint: disable=undefined-variable 53def register(linter: PyLinter) -> None: 54 linter.register_checker(ZephyrArgParseChecker(linter)) 55