summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2022-08-31 22:06:40 +0200
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2022-09-06 23:33:59 +0200
commita10406ab31725993b9c6b44154d71166f10e248d (patch)
tree967087c04d9c0f83bc6d9124d1e898711c3526d3
parentb1b067e8c540070cd1814f6cc3c8fcdf68e4807f (diff)
downloadpylint-git-a10406ab31725993b9c6b44154d71166f10e248d.tar.gz
Fix crash while iteraring over a class attribute (#7386)
Co-authored-by: orSolocate <38433858+orSolocate@users.noreply.github.com>
-rw-r--r--doc/whatsnew/fragments/7380.bugfix3
-rw-r--r--pylint/checkers/modified_iterating_checker.py8
-rw-r--r--tests/functional/m/modified_iterating.py16
-rw-r--r--tests/functional/m/modified_iterating.txt1
4 files changed, 24 insertions, 4 deletions
diff --git a/doc/whatsnew/fragments/7380.bugfix b/doc/whatsnew/fragments/7380.bugfix
new file mode 100644
index 000000000..dc5ea5fa6
--- /dev/null
+++ b/doc/whatsnew/fragments/7380.bugfix
@@ -0,0 +1,3 @@
+Update ``modified_iterating`` checker to fix a crash with ``for`` loops on empty list.
+
+Closes #7380
diff --git a/pylint/checkers/modified_iterating_checker.py b/pylint/checkers/modified_iterating_checker.py
index bdabc2650..62e887a95 100644
--- a/pylint/checkers/modified_iterating_checker.py
+++ b/pylint/checkers/modified_iterating_checker.py
@@ -81,7 +81,7 @@ class ModifiedIterationChecker(checkers.BaseChecker):
msg_id = "modified-iterating-dict"
elif isinstance(inferred, nodes.Set):
msg_id = "modified-iterating-set"
- elif not isinstance(iter_obj, nodes.Name):
+ elif not isinstance(iter_obj, (nodes.Name, nodes.Attribute)):
pass
elif self._modified_iterating_list_cond(node, iter_obj):
msg_id = "modified-iterating-list"
@@ -90,10 +90,14 @@ class ModifiedIterationChecker(checkers.BaseChecker):
elif self._modified_iterating_set_cond(node, iter_obj):
msg_id = "modified-iterating-set"
if msg_id:
+ if isinstance(iter_obj, nodes.Attribute):
+ obj_name = iter_obj.attrname
+ else:
+ obj_name = iter_obj.name
self.add_message(
msg_id,
node=node,
- args=(iter_obj.name,),
+ args=(obj_name,),
confidence=interfaces.INFERENCE,
)
diff --git a/tests/functional/m/modified_iterating.py b/tests/functional/m/modified_iterating.py
index 166bf4f6c..527ce358c 100644
--- a/tests/functional/m/modified_iterating.py
+++ b/tests/functional/m/modified_iterating.py
@@ -1,5 +1,5 @@
"""Tests for iterating-modified messages"""
-# pylint: disable=not-callable,unnecessary-comprehension
+# pylint: disable=not-callable,unnecessary-comprehension,too-few-public-methods
import copy
@@ -26,7 +26,7 @@ my_dict = {"1": 1, "2": 2, "3": 3}
i = 1
for item in my_dict:
item_list[0] = i # for coverage, see reference at /pull/5628#discussion_r792181642
- my_dict[i] = 1 # [modified-iterating-dict]
+ my_dict[i] = 1 # [modified-iterating-dict]
i += 1
i = 1
@@ -93,3 +93,15 @@ def update_existing_key():
for key in my_dict:
new_key = key.lower()
my_dict[new_key] = 1 # [modified-iterating-dict]
+
+
+class MyClass:
+ """Regression test for https://github.com/PyCQA/pylint/issues/7380"""
+
+ def __init__(self) -> None:
+ self.attribute = [1, 2, 3]
+
+ def my_method(self):
+ """This should raise as we are deleting."""
+ for var in self.attribute:
+ del var # [modified-iterating-list]
diff --git a/tests/functional/m/modified_iterating.txt b/tests/functional/m/modified_iterating.txt
index c63095556..7d5e3014d 100644
--- a/tests/functional/m/modified_iterating.txt
+++ b/tests/functional/m/modified_iterating.txt
@@ -13,3 +13,4 @@ modified-iterating-list:64:4:64:23::Iterated list 'item_list' is being modified
modified-iterating-list:67:12:67:31::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:69:16:69:35::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-dict:95:8:95:28:update_existing_key:Iterated dict 'my_dict' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
+modified-iterating-list:107:12:107:19:MyClass.my_method:Iterated list 'attribute' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE