diff --git a/doc/whatsnew/fragments/9334.feature b/doc/whatsnew/fragments/9334.feature new file mode 100644 index 0000000000..ec4b62a704 --- /dev/null +++ b/doc/whatsnew/fragments/9334.feature @@ -0,0 +1,3 @@ +Check for `.clear`, `.discard`, `.pop` and `remove` methods being called on a set while it is being iterated over. + +Closes #9334 diff --git a/pylint/checkers/modified_iterating_checker.py b/pylint/checkers/modified_iterating_checker.py index 9f876b1abc..be8d967abb 100644 --- a/pylint/checkers/modified_iterating_checker.py +++ b/pylint/checkers/modified_iterating_checker.py @@ -16,7 +16,7 @@ _LIST_MODIFIER_METHODS = {"append", "remove"} -_SET_MODIFIER_METHODS = {"add", "remove"} +_SET_MODIFIER_METHODS = {"add", "clear", "discard", "pop", "remove"} class ModifiedIterationChecker(checkers.BaseChecker): diff --git a/tests/functional/m/modified_iterating.py b/tests/functional/m/modified_iterating.py index bd2d0dd13d..1fc11f9f5b 100644 --- a/tests/functional/m/modified_iterating.py +++ b/tests/functional/m/modified_iterating.py @@ -39,6 +39,22 @@ for item in item_set: item_set.add(item + 10) # [modified-iterating-set] +item_set = {1, 2, 3} +for item in item_set: + item_set.clear() # [modified-iterating-set] + +item_set = {1, 2, 3} +for item in item_set: + item_set.discard(1) # [modified-iterating-set] + +item_set = {1, 2, 3} +for item in item_set: + item_set.pop() # [modified-iterating-set] + +item_set = {1, 2, 3} +for item in item_set: + item_set.remove() # [modified-iterating-set] + for item in item_set.copy(): item_set.add(item + 10) diff --git a/tests/functional/m/modified_iterating.txt b/tests/functional/m/modified_iterating.txt index 66544da386..ccaec69fe7 100644 --- a/tests/functional/m/modified_iterating.txt +++ b/tests/functional/m/modified_iterating.txt @@ -2,16 +2,20 @@ modified-iterating-list:9:4:9:26::Iterated list 'item_list' is being modified in 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-set:44:4:44:20::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE +modified-iterating-set:48:4:48:23::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE +modified-iterating-set:52:4:52:18::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE +modified-iterating-set:56:4:56:21::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE +modified-iterating-list:63:8:63:27::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE +modified-iterating-set:64:8:64:26::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 -modified-iterating-dict:126:8:126:15:my_call:Iterated dict '' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE +modified-iterating-list:68:4:68:12::Iterated list 'list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE +modified-iterating-list:71:4:71:20::Iterated list 'list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE +modified-iterating-dict:74:4:74:9::Iterated dict 'my_dict' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE +modified-iterating-set:77:4:77:15::Iterated set 'item_set' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE +modified-iterating-list:81:4:81:23::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE +modified-iterating-list:84:12:84:31::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE +modified-iterating-list:86:16:86:35::Iterated list 'item_list' is being modified inside for loop body, consider iterating through a copy of it instead.:INFERENCE +modified-iterating-dict:112:8:112: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:124:12:124: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-dict:142:8:142:15:my_call:Iterated dict '' is being modified inside for loop body, iterate through a copy of it instead.:INFERENCE