diff options
author | Dani Alcala <112832187+clavedeluna@users.noreply.github.com> | 2022-11-23 14:11:20 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-23 18:11:20 +0100 |
commit | f7d681b5a79e5781ab8072fe64459b199955a1f6 (patch) | |
tree | 57e5c051cf7384ae01d50007386b73b1dab616e1 /pylint | |
parent | ed404d361f24f068693d59619961e575810af3d9 (diff) | |
download | pylint-git-f7d681b5a79e5781ab8072fe64459b199955a1f6.tar.gz |
Add a new check `dict-init-mutate` (#7794)
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Diffstat (limited to 'pylint')
-rw-r--r-- | pylint/extensions/dict_init_mutate.py | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/pylint/extensions/dict_init_mutate.py b/pylint/extensions/dict_init_mutate.py new file mode 100644 index 000000000..fb4c83647 --- /dev/null +++ b/pylint/extensions/dict_init_mutate.py @@ -0,0 +1,66 @@ +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE +# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt + +"""Check for use of dictionary mutation after initialization.""" +from __future__ import annotations + +from typing import TYPE_CHECKING + +from astroid import nodes + +from pylint.checkers import BaseChecker +from pylint.checkers.utils import only_required_for_messages +from pylint.interfaces import HIGH + +if TYPE_CHECKING: + from pylint.lint.pylinter import PyLinter + + +class DictInitMutateChecker(BaseChecker): + name = "dict-init-mutate" + msgs = { + "C3401": ( + "Declare all known key/values when initializing the dictionary.", + "dict-init-mutate", + "Dictionaries can be initialized with a single statement " + "using dictionary literal syntax.", + ) + } + + @only_required_for_messages("dict-init-mutate") + def visit_assign(self, node: nodes.Assign) -> None: + """ + Detect dictionary mutation immediately after initialization. + + At this time, detecting nested mutation is not supported. + """ + if not isinstance(node.value, nodes.Dict): + return + + dict_name = node.targets[0] + if len(node.targets) != 1 or not isinstance(dict_name, nodes.AssignName): + return + + first_sibling = node.next_sibling() + if ( + not first_sibling + or not isinstance(first_sibling, nodes.Assign) + or len(first_sibling.targets) != 1 + ): + return + + sibling_target = first_sibling.targets[0] + if not isinstance(sibling_target, nodes.Subscript): + return + + sibling_name = sibling_target.value + if not isinstance(sibling_name, nodes.Name): + return + + if sibling_name.name == dict_name.name: + self.add_message("dict-init-mutate", node=node, confidence=HIGH) + + +def register(linter: PyLinter) -> None: + linter.register_checker(DictInitMutateChecker(linter)) |