55 lines
1.9 KiB
Python
55 lines
1.9 KiB
Python
|
# 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))
|