Skip to content

Commit

Permalink
Fix crash in modified_iterating checker for set defined as a clas…
Browse files Browse the repository at this point in the history
…s attribute (#7541)

Co-authored-by: Daniël van Noord <[email protected]>
Co-authored-by: Pierre Sassoulas <[email protected]>
  • Loading branch information
3 people authored Sep 30, 2022
1 parent 530d790 commit aca8dd5
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 19 deletions.
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/7528.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed a crash of the ``modified_iterating`` checker when iterating on a set defined as a class attribute.

Closes #7528
9 changes: 7 additions & 2 deletions pylint/checkers/modified_iterating_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,16 @@ def _is_node_expr_that_calls_attribute_name(node: nodes.NodeNG) -> bool:
@staticmethod
def _common_cond_list_set(
node: nodes.Expr,
iter_obj: nodes.NodeNG,
iter_obj: nodes.Name | nodes.Attribute,
infer_val: nodes.List | nodes.Set,
) -> bool:
iter_obj_name = (
iter_obj.attrname
if isinstance(iter_obj, nodes.Attribute)
else iter_obj.name
)
return (infer_val == utils.safe_infer(iter_obj)) and ( # type: ignore[no-any-return]
node.value.func.expr.name == iter_obj.name
node.value.func.expr.name == iter_obj_name
)

@staticmethod
Expand Down
15 changes: 14 additions & 1 deletion tests/functional/m/modified_iterating.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Tests for iterating-modified messages"""
# pylint: disable=not-callable,unnecessary-comprehension,too-few-public-methods
# pylint: disable=not-callable,unnecessary-comprehension,too-few-public-methods,missing-class-docstring,missing-function-docstring

import copy
from enum import Enum

item_list = [1, 2, 3]
for item in item_list:
Expand Down Expand Up @@ -117,3 +118,15 @@ def my_method(self):
for key in self.attribute:
tmp = self.attribute.copy()
tmp[key] = None

class MyEnum(Enum):
FOO = 1
BAR = 2

class EnumClass:
ENUM_SET = {MyEnum.FOO, MyEnum.BAR}

def useless(self):
other_set = set(self.ENUM_SET)
for obj in self.ENUM_SET:
other_set.remove(obj)
32 changes: 16 additions & 16 deletions tests/functional/m/modified_iterating.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
modified-iterating-list:8:4:8:26::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:11:4:11:26::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-dict:29:4:29:18::Iterated dict 'my_dict' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-set:39:4:39:27::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-list:46:8:46:27::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-set:47:8:47:26::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-list:48:4:48:23::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:51:4:51:12::Iterated list 'list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:54:4:54:20::Iterated list 'list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-dict:57:4:57:9::Iterated dict 'my_dict' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-set:60:4:60:15::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-list:64:4:64:23::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
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
modified-iterating-list:9:4:9:26::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:12:4:12:26::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-dict:30:4:30:18::Iterated dict 'my_dict' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-set:40:4:40:27::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-list:47:8:47:27::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-set:48:8:48:26::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-list:49:4:49:23::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:52:4:52:12::Iterated list 'list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:55:4:55:20::Iterated list 'list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-dict:58:4:58:9::Iterated dict 'my_dict' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-set:61:4:61:15::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE
modified-iterating-list:65:4:65:23::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:68:12:68:31::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-list:70:16:70:35::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE
modified-iterating-dict:96:8:96: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:108:12:108:19:MyClass.my_method:Iterated list 'attribute' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE

0 comments on commit aca8dd5

Please sign in to comment.