summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Mueller <30130371+cdce8p@users.noreply.github.com>2021-08-13 01:34:41 +0200
committerMarc Mueller <30130371+cdce8p@users.noreply.github.com>2021-08-13 01:37:52 +0200
commitba9ba45f418f94da4c5444f7aec9dfcb869dd977 (patch)
treec85234cc04d96982143b422cd0e08da6c052360e
parent4a4220f1c60236d3afed751f9278b5311dcbc1e4 (diff)
downloadpylint-git-ba9ba45f418f94da4c5444f7aec9dfcb869dd977.tar.gz
Add new check - use-sequence-for-iteration
-rw-r--r--ChangeLog2
-rw-r--r--doc/whatsnew/2.10.rst2
-rw-r--r--pylint/checkers/refactoring/recommendation_checker.py28
-rw-r--r--tests/functional/u/use/use_sequence_for_iteration.py16
-rw-r--r--tests/functional/u/use/use_sequence_for_iteration.txt4
5 files changed, 49 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index fae693a3d..ecfe42ff0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -118,6 +118,8 @@ Release date: TBA
Closes #4828
+* Added ``use-sequence-for-iteration``: Emitted when iterating over an in-place defined ``set``.
+
What's New in Pylint 2.9.6?
===========================
diff --git a/doc/whatsnew/2.10.rst b/doc/whatsnew/2.10.rst
index 585ac8cc7..d13099989 100644
--- a/doc/whatsnew/2.10.rst
+++ b/doc/whatsnew/2.10.rst
@@ -28,6 +28,8 @@ New checkers
Closes #3692
+* Added ``use-sequence-for-iteration``: Emitted when iterating over an in-place defined ``set``.
+
Other Changes
=============
diff --git a/pylint/checkers/refactoring/recommendation_checker.py b/pylint/checkers/refactoring/recommendation_checker.py
index 252ae684a..b7bda5754 100644
--- a/pylint/checkers/refactoring/recommendation_checker.py
+++ b/pylint/checkers/refactoring/recommendation_checker.py
@@ -1,6 +1,6 @@
# 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
-from typing import cast
+from typing import Union, cast
import astroid
@@ -43,6 +43,12 @@ class RecommendationChecker(checkers.BaseChecker):
"str.split(sep, maxsplit=1)[0] or str.rsplit(sep, maxsplit=1)[-1] "
"instead.",
),
+ "C0208": (
+ "Use a sequence type when iterating over values",
+ "use-sequence-for-iteration",
+ "When iterating over values, sequence types (e.g., ``lists``, ``tuples``, ``ranges``) "
+ "are more efficient than ``sets``.",
+ ),
}
@staticmethod
@@ -134,10 +140,15 @@ class RecommendationChecker(checkers.BaseChecker):
)
self.add_message("use-maxsplit-arg", node=node, args=(new_name,))
- @utils.check_messages("consider-using-enumerate", "consider-using-dict-items")
+ @utils.check_messages(
+ "consider-using-enumerate",
+ "consider-using-dict-items",
+ "use-sequence-for-iteration",
+ )
def visit_for(self, node: astroid.For) -> None:
self._check_consider_using_enumerate(node)
self._check_consider_using_dict_items(node)
+ self._check_use_sequence_for_iteration(node)
def _check_consider_using_enumerate(self, node: astroid.For) -> None:
"""Emit a convention whenever range and len are used for indexing."""
@@ -262,9 +273,13 @@ class RecommendationChecker(checkers.BaseChecker):
self.add_message("consider-using-dict-items", node=node)
return
- @utils.check_messages("consider-using-dict-items")
+ @utils.check_messages(
+ "consider-using-dict-items",
+ "use-sequence-for-iteration",
+ )
def visit_comprehension(self, node: astroid.Comprehension) -> None:
self._check_consider_using_dict_items_comprehension(node)
+ self._check_use_sequence_for_iteration(node)
def _check_consider_using_dict_items_comprehension(
self, node: astroid.Comprehension
@@ -291,3 +306,10 @@ class RecommendationChecker(checkers.BaseChecker):
self.add_message("consider-using-dict-items", node=node)
return
+
+ def _check_use_sequence_for_iteration(
+ self, node: Union[astroid.For, astroid.Comprehension]
+ ) -> None:
+ """Check if code iterates over an in-place defined set."""
+ if isinstance(node.iter, astroid.Set):
+ self.add_message("use-sequence-for-iteration", node=node.iter)
diff --git a/tests/functional/u/use/use_sequence_for_iteration.py b/tests/functional/u/use/use_sequence_for_iteration.py
new file mode 100644
index 000000000..2dd1feb18
--- /dev/null
+++ b/tests/functional/u/use/use_sequence_for_iteration.py
@@ -0,0 +1,16 @@
+# pylint: disable=missing-docstring,pointless-statement,unnecessary-comprehension
+
+var = {1, 2, 3}
+
+for x in var:
+ pass
+for x in {1, 2, 3}: # [use-sequence-for-iteration]
+ pass
+
+(x for x in var)
+(x for x in {1, 2, 3}) # [use-sequence-for-iteration]
+
+[x for x in var]
+[x for x in {1, 2, 3}] # [use-sequence-for-iteration]
+
+[x for x in {*var, 4}] # [use-sequence-for-iteration]
diff --git a/tests/functional/u/use/use_sequence_for_iteration.txt b/tests/functional/u/use/use_sequence_for_iteration.txt
new file mode 100644
index 000000000..615df8a30
--- /dev/null
+++ b/tests/functional/u/use/use_sequence_for_iteration.txt
@@ -0,0 +1,4 @@
+use-sequence-for-iteration:7:9::Use a sequence type when iterating over values:HIGH
+use-sequence-for-iteration:11:12::Use a sequence type when iterating over values:HIGH
+use-sequence-for-iteration:14:12::Use a sequence type when iterating over values:HIGH
+use-sequence-for-iteration:16:12::Use a sequence type when iterating over values:HIGH