From 314cb9ffd369b5ab99688c885eb537c901e861eb Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Sat, 18 Sep 2021 10:42:49 -0500 Subject: Use node_ancestors to get rid of some while-loops (#5005) * Use node_ancestors method * Rename loop variables --- .gitignore | 1 + pylint/checkers/base.py | 19 +++++++------------ pylint/checkers/refactoring/refactoring_checker.py | 6 +++--- pylint/checkers/utils.py | 18 +++++------------- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 3d96061c6..046061c9b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ build-stamp .eggs/ .pytest_cache/ .mypy_cache/ +.benchmarks/ diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py index 68f6bd59d..4578fbc5b 100644 --- a/pylint/checkers/base.py +++ b/pylint/checkers/base.py @@ -238,8 +238,7 @@ def _redefines_import(node): def in_loop(node): """return True if the node is inside a kind of for loop""" - parent = node.parent - while parent is not None: + for parent in node.node_ancestors(): if isinstance( parent, ( @@ -251,7 +250,6 @@ def in_loop(node): ), ): return True - parent = parent.parent return False @@ -847,23 +845,20 @@ class BasicErrorChecker(_BasicChecker): def _check_in_loop(self, node, node_name): """check that a node is inside a for or while loop""" - _node = node.parent - while _node: - if isinstance(_node, (nodes.For, nodes.While)): - if node not in _node.orelse: + for parent in node.node_ancestors(): + if isinstance(parent, (nodes.For, nodes.While)): + if node not in parent.orelse: return - if isinstance(_node, (nodes.ClassDef, nodes.FunctionDef)): + if isinstance(parent, (nodes.ClassDef, nodes.FunctionDef)): break if ( - isinstance(_node, nodes.TryFinally) - and node in _node.finalbody + isinstance(parent, nodes.TryFinally) + and node in parent.finalbody and isinstance(node, nodes.Continue) ): self.add_message("continue-in-finally", node=node) - _node = _node.parent - self.add_message("not-in-loop", node=node, args=node_name) def _check_redefinition(self, redeftype, node): diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py index 02b28eb52..c90e550d2 100644 --- a/pylint/checkers/refactoring/refactoring_checker.py +++ b/pylint/checkers/refactoring/refactoring_checker.py @@ -116,11 +116,11 @@ def _is_inside_context_manager(node: nodes.Call) -> bool: def _is_a_return_statement(node: nodes.Call) -> bool: frame = node.frame() - parent = node.parent - while parent is not frame: + for parent in node.node_ancestors(): + if parent is frame: + break if isinstance(parent, nodes.Return): return True - parent = parent.parent return False diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index e6e91c2c1..305a4fc94 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -275,11 +275,9 @@ class InferredTypeError(Exception): def is_inside_lambda(node: nodes.NodeNG) -> bool: """Return true if given node is inside lambda""" - parent = node.parent - while parent is not None: + for parent in node.node_ancestors(): if isinstance(parent, nodes.Lambda): return True - parent = parent.parent return False @@ -377,11 +375,9 @@ def is_defined_before(var_node: nodes.Name) -> bool: (statement_defining ; statement_using). """ varname = var_node.name - _node = var_node.parent - while _node: - if is_defined_in_scope(var_node, varname, _node): + for parent in var_node.node_ancestors(): + if is_defined_in_scope(var_node, varname, parent): return True - _node = _node.parent # possibly multiple statements on the same line using semi colon separator stmt = var_node.statement() _node = stmt.previous_sibling() @@ -415,8 +411,7 @@ def is_default_argument( def is_func_decorator(node: nodes.NodeNG) -> bool: """return true if the name is used in function decorator""" - parent = node.parent - while parent is not None: + for parent in node.node_ancestors(): if isinstance(parent, nodes.Decorators): return True if parent.is_statement or isinstance( @@ -428,7 +423,6 @@ def is_func_decorator(node: nodes.NodeNG) -> bool: ), ): break - parent = parent.parent return False @@ -909,9 +903,7 @@ def find_except_wrapper_node_in_scope( node: nodes.NodeNG, ) -> Optional[Union[nodes.ExceptHandler, nodes.TryExcept]]: """Return the ExceptHandler in which the node is, without going out of scope.""" - current = node - while current.parent is not None: - current = current.parent + for current in node.node_ancestors(): if isinstance(current, astroid.scoped_nodes.LocalsDictNodeNG): # If we're inside a function/class definition, we don't want to keep checking # higher ancestors for `except` clauses, because if these exist, it means our -- cgit v1.2.1