blob: fb197a9b7874e770d50f3445420e145fb3b53807 [file] [log] [blame]
Jamie McCrae101ba4a2023-01-18 09:09:19 +00001# 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))