summaryrefslogtreecommitdiff
path: root/pylint
diff options
context:
space:
mode:
authorNick Drozd <nicholasdrozd@gmail.com>2021-08-18 10:28:49 -0500
committerGitHub <noreply@github.com>2021-08-18 17:28:49 +0200
commit53da6541dbe621b55f2c7f1bfcf821541dc823e8 (patch)
tree3f6f98aa51b609a177f975992baab14ef6839cd8 /pylint
parentf78a35afb76c38f4141714130bbd1a35ee430ea1 (diff)
downloadpylint-git-53da6541dbe621b55f2c7f1bfcf821541dc823e8.tar.gz
Add extension check against use of while loops (#4860)
* Move stray functional tests * Clean up some while loops * Add extension check against use of while loops
Diffstat (limited to 'pylint')
-rw-r--r--pylint/checkers/utils.py6
-rw-r--r--pylint/config/option_manager_mixin.py5
-rw-r--r--pylint/extensions/typing.py6
-rw-r--r--pylint/extensions/while_used.py30
-rw-r--r--pylint/lint/utils.py6
-rw-r--r--pylint/reporters/ureports/__init__.py3
-rw-r--r--pylint/utils/utils.py2
7 files changed, 41 insertions, 17 deletions
diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index 47de79d25..aa445a708 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -671,9 +671,9 @@ def node_frame_class(node: astroid.node_classes.NodeNG) -> Optional[astroid.Clas
and not isinstance(klass, astroid.ClassDef)
):
if klass.parent is None:
- klass = None
- else:
- klass = klass.parent.frame()
+ return None
+
+ klass = klass.parent.frame()
return klass
diff --git a/pylint/config/option_manager_mixin.py b/pylint/config/option_manager_mixin.py
index 02c6997af..84a2158ad 100644
--- a/pylint/config/option_manager_mixin.py
+++ b/pylint/config/option_manager_mixin.py
@@ -240,8 +240,7 @@ class OptionsManagerMixIn:
"""Read the configuration file but do not load it (i.e. dispatching
values to each options provider)
"""
- help_level = 1
- while help_level <= self._maxlevel:
+ for help_level in range(1, self._maxlevel + 1):
opt = "-".join(["long"] * help_level) + "-help"
if opt in self._all_options:
break # already processed
@@ -255,7 +254,7 @@ class OptionsManagerMixIn:
provider = self.options_providers[0]
self.add_optik_option(provider, self.cmdline_parser, opt, optdict)
provider.options += ((opt, optdict),)
- help_level += 1
+
if config_file is None:
config_file = self.config_file
if config_file is not None:
diff --git a/pylint/extensions/typing.py b/pylint/extensions/typing.py
index c2ba28de4..c931ea020 100644
--- a/pylint/extensions/typing.py
+++ b/pylint/extensions/typing.py
@@ -293,11 +293,7 @@ class TypingChecker(BaseChecker):
"""
if self._py37_plus() and not self._py39_plus():
msg_future_import = self._msg_postponed_eval_hint(node)
- while True:
- try:
- msg = self._consider_using_alias_msgs.pop(0)
- except IndexError:
- break
+ for msg in self._consider_using_alias_msgs:
if msg.qname in self._alias_name_collisions:
continue
self.add_message(
diff --git a/pylint/extensions/while_used.py b/pylint/extensions/while_used.py
new file mode 100644
index 000000000..9476478c3
--- /dev/null
+++ b/pylint/extensions/while_used.py
@@ -0,0 +1,30 @@
+"""Check for use of while loops."""
+from pylint.checkers import BaseChecker
+from pylint.checkers.utils import check_messages
+from pylint.interfaces import IAstroidChecker
+
+
+class WhileChecker(BaseChecker):
+
+ __implements__ = (IAstroidChecker,)
+ name = "while_used"
+ msgs = {
+ "W0149": (
+ "Used `while` loop",
+ "while-used",
+ "Unbounded `while` loops can often be rewritten as bounded `for` loops.",
+ )
+ }
+
+ @check_messages("while-used")
+ def visit_while(self, node):
+ self.add_message("while-used", node=node)
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ linter.register_checker(WhileChecker(linter))
diff --git a/pylint/lint/utils.py b/pylint/lint/utils.py
index 6c5390cb7..de24de988 100644
--- a/pylint/lint/utils.py
+++ b/pylint/lint/utils.py
@@ -78,7 +78,9 @@ def preprocess_options(args, search_for):
i = 0
while i < len(args):
arg = args[i]
- if arg.startswith("--"):
+ if not arg.startswith("--"):
+ i += 1
+ else:
try:
option, val = arg[2:].split("=", 1)
except ValueError:
@@ -99,8 +101,6 @@ def preprocess_options(args, search_for):
msg = "Option %s doesn't expects a value" % option
raise ArgumentPreprocessingError(msg)
cb(option, val)
- else:
- i += 1
def _patch_sys_path(args):
diff --git a/pylint/reporters/ureports/__init__.py b/pylint/reporters/ureports/__init__.py
index 9b47bf378..2b0a52c50 100644
--- a/pylint/reporters/ureports/__init__.py
+++ b/pylint/reporters/ureports/__init__.py
@@ -75,8 +75,7 @@ class BaseWriter:
cols -= 1
result[-1].append(cell)
# fill missing cells
- while len(result[-1]) < cols:
- result[-1].append("")
+ result[-1] += [""] * (cols - len(result[-1]))
return result
def compute_content(self, layout):
diff --git a/pylint/utils/utils.py b/pylint/utils/utils.py
index b6c81284b..1a8f7957d 100644
--- a/pylint/utils/utils.py
+++ b/pylint/utils/utils.py
@@ -63,7 +63,7 @@ def get_module_and_frameid(node):
try:
frame = frame.parent.frame()
except AttributeError:
- frame = None
+ break
obj.reverse()
return module, ".".join(obj)