Skip to content

Commit

Permalink
provide dict suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
clavedeluna committed Nov 22, 2022
1 parent 4649373 commit 3cac8cc
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 11 deletions.
2 changes: 1 addition & 1 deletion doc/user_guide/checkers/extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ Verbatim name of the checker is ``dict-init-mutate``.

Dict-Init-Mutate checker Messages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:dict-init-mutate (W3301): *Dictionary mutated immediately after initialization*
:dict-init-mutate (C3301): *Dictionary mutated immediately after initialization*
Dictionaries can be initialized with a single statement using dictionary
literal syntax.

Expand Down
21 changes: 13 additions & 8 deletions pylint/extensions/dict_init_mutate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@
# 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
from pylint.lint.pylinter import PyLinter

if TYPE_CHECKING:
from pylint.lint.pylinter import PyLinter


class DictInitMutateChecker(BaseChecker):
name = "dict-init-mutate"
msgs = {
"W3301": (
"Dictionary mutated immediately after initialization",
"C3301": (
"Declare all known key/values when initializing the dictionary.",
"dict-init-mutate",
"Dictionaries can be initialized with a single statement "
"using dictionary literal syntax.",
Expand All @@ -37,15 +42,15 @@ def visit_assign(self, node: nodes.Assign) -> None:
if len(node.targets) != 1 or not isinstance(dict_name, nodes.AssignName):
return

next_sibling = node.next_sibling()
first_sibling = node.next_sibling()
if (
not next_sibling
or not isinstance(next_sibling, nodes.Assign)
or len(next_sibling.targets) != 1
not first_sibling
or not isinstance(first_sibling, nodes.Assign)
or len(first_sibling.targets) != 1
):
return

sibling_target = next_sibling.targets[0]
sibling_target = first_sibling.targets[0]
if not isinstance(sibling_target, nodes.Subscript):
return

Expand Down
5 changes: 5 additions & 0 deletions tests/functional/ext/dict_init_mutate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@

fruits = {}
for fruit in ["apple", "orange"]:
fruits[fruit] = 1
fruits[fruit] += 1

count = 10
fruits = {"apple": 1}
fruits["apple"] += count

config = {} # [dict-init-mutate]
config['pwd'] = 'hello'

config = {} # [dict-init-mutate]
config['dir'] = 'bin'
config['user'] = 'me'
config['workers'] = 5
print(config)

config = {} # Not flagging calls to update for now
config.update({"dir": "bin"})
Expand Down
5 changes: 3 additions & 2 deletions tests/functional/ext/dict_init_mutate.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dict-init-mutate:14:0:14:11::Dictionary mutated immediately after initialization:HIGH
dict-init-mutate:22:0:22:11::Dictionary mutated immediately after initialization:HIGH
dict-init-mutate:15:0:15:11::Declare all known key/values when initializing the dictionary.:HIGH
dict-init-mutate:18:0:18:11::Declare all known key/values when initializing the dictionary.:HIGH
dict-init-mutate:27:0:27:11::Declare all known key/values when initializing the dictionary.:HIGH

0 comments on commit 3cac8cc

Please sign in to comment.