summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Sassoulas <pierre.sassoulas@gmail.com>2021-06-17 18:43:03 +0200
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2021-10-16 17:34:16 +0200
commitf1333e28bf9ab8a6584ca13aacf244a1a1165f87 (patch)
treecc0ea97299f83289ea9c259fac4771079f7120de
parent9098c6078551e2d3028fe65537d3b0e407c85724 (diff)
downloadpylint-git-refactor-variable-checker-visit_name.tar.gz
Refactor Variable checker to use less argument in functionrefactor-variable-checker-visit_name
We only need the node because we can get the name from the node.
-rw-r--r--pylint/checkers/variables.py97
1 files changed, 50 insertions, 47 deletions
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 44044f76b..ef53f19cb 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -979,7 +979,6 @@ class VariablesChecker(BaseChecker):
assert not stmt.root().file.endswith(".py")
return
- name = node.name
frame = stmt.scope()
start_index = len(self._to_consume) - 1
@@ -1035,7 +1034,7 @@ class VariablesChecker(BaseChecker):
# variable used outside the loop
# avoid the case where there are homonyms inside function scope and
# comprehension current scope (avoid bug #1731)
- if name in current_consumer.consumed and (
+ if node.name in current_consumer.consumed and (
utils.is_func_decorator(current_consumer.node)
or not (
current_consumer.scope_type == "comprehension"
@@ -1043,7 +1042,7 @@ class VariablesChecker(BaseChecker):
)
):
self._check_late_binding_closure(node)
- self._loopvar_name(node, name)
+ self._loopvar_name(node)
break
found_nodes = current_consumer.get_next_to_consume(node)
@@ -1056,7 +1055,9 @@ class VariablesChecker(BaseChecker):
else:
defnode = None
if used_before_assignment_is_enabled:
- self.add_message("used-before-assignment", args=name, node=node)
+ self.add_message(
+ "used-before-assignment", args=node.name, node=node
+ )
self._check_late_binding_closure(node)
@@ -1106,7 +1107,6 @@ class VariablesChecker(BaseChecker):
use_outer_definition,
) = self._is_variable_violation(
node,
- name,
defnode,
stmt,
defstmt,
@@ -1148,10 +1148,10 @@ class VariablesChecker(BaseChecker):
nodes.Arguments,
),
)
- and name in node.root().locals
+ and node.name in node.root().locals
):
self.add_message(
- "undefined-variable", args=name, node=node
+ "undefined-variable", args=node.name, node=node
)
elif base_scope_type != "lambda":
# E0601 may *not* occurs in lambda scope.
@@ -1162,7 +1162,7 @@ class VariablesChecker(BaseChecker):
and isinstance(stmt, (nodes.AnnAssign, nodes.FunctionDef))
):
self.add_message(
- "used-before-assignment", args=name, node=node
+ "used-before-assignment", args=node.name, node=node
)
elif base_scope_type == "lambda":
# E0601 can occur in class-level scope in lambdas, as in
@@ -1170,7 +1170,10 @@ class VariablesChecker(BaseChecker):
# class A:
# x = lambda attr: f + attr
# f = 42
- if isinstance(frame, nodes.ClassDef) and name in frame.locals:
+ if (
+ isinstance(frame, nodes.ClassDef)
+ and node.name in frame.locals
+ ):
if isinstance(node.parent, nodes.Arguments):
if stmt.fromlineno <= defstmt.fromlineno:
# Doing the following is fine:
@@ -1178,36 +1181,40 @@ class VariablesChecker(BaseChecker):
# x = 42
# y = lambda attr=x: attr
self.add_message(
- "used-before-assignment", args=name, node=node
+ "used-before-assignment",
+ args=node.name,
+ node=node,
)
else:
self.add_message(
- "undefined-variable", args=name, node=node
+ "undefined-variable", args=node.name, node=node
)
elif current_consumer.scope_type == "lambda":
- self.add_message("undefined-variable", node=node, args=name)
- elif self._is_only_type_assignment(node, name, defstmt):
- self.add_message("undefined-variable", node=node, args=name)
+ self.add_message(
+ "undefined-variable", node=node, args=node.name
+ )
+ elif self._is_only_type_assignment(node, defstmt):
+ self.add_message("undefined-variable", node=node, args=node.name)
- current_consumer.mark_as_consumed(name, found_nodes)
+ current_consumer.mark_as_consumed(node.name, found_nodes)
# check it's not a loop variable used outside the loop
- self._loopvar_name(node, name)
+ self._loopvar_name(node)
break
else:
# we have not found the name, if it isn't a builtin, that's an
# undefined name !
if undefined_variable_is_enabled and not (
- name in nodes.Module.scope_attrs
- or utils.is_builtin(name)
- or name in self.config.additional_builtins
+ node.name in nodes.Module.scope_attrs
+ or utils.is_builtin(node.name)
+ or node.name in self.config.additional_builtins
or (
- name == "__class__"
+ node.name == "__class__"
and isinstance(frame, nodes.FunctionDef)
and frame.is_method()
)
):
if not utils.node_ignores_exception(node, NameError):
- self.add_message("undefined-variable", args=name, node=node)
+ self.add_message("undefined-variable", args=node.name, node=node)
@utils.check_messages("no-name-in-module")
def visit_import(self, node: nodes.Import) -> None:
@@ -1358,21 +1365,16 @@ class VariablesChecker(BaseChecker):
@staticmethod
def _is_variable_violation(
- node,
- name,
+ node: nodes.Name,
defnode,
stmt,
defstmt,
- frame,
+ frame, # scope of statement of node
defframe,
base_scope_type,
recursive_klass,
- ):
+ ) -> Tuple[bool, bool, bool]:
# pylint: disable=too-many-nested-blocks
- # node: Node to check for violation
- # name: name of node to check violation for
- # frame: Scope of statement of node
- # base_scope_type: local scope type
maybee0601 = True
annotation_return = False
use_outer_definition = False
@@ -1381,7 +1383,10 @@ class VariablesChecker(BaseChecker):
elif defframe.parent is None:
# we are at the module level, check the name is not
# defined in builtins
- if name in defframe.scope_attrs or astroid.builtin_lookup(name)[1]:
+ if (
+ node.name in defframe.scope_attrs
+ or astroid.builtin_lookup(node.name)[1]
+ ):
maybee0601 = False
else:
# we are in a local scope, check the name is not
@@ -1393,22 +1398,22 @@ class VariablesChecker(BaseChecker):
isinstance(frame, nodes.FunctionDef)
or isinstance(node.frame(), nodes.Lambda)
) and _assigned_locally(node)
- if not forbid_lookup and defframe.root().lookup(name)[1]:
+ if not forbid_lookup and defframe.root().lookup(node.name)[1]:
maybee0601 = False
use_outer_definition = stmt == defstmt and not isinstance(
defnode, nodes.Comprehension
)
# check if we have a nonlocal
- elif name in defframe.locals:
+ elif node.name in defframe.locals:
maybee0601 = not any(
- isinstance(child, nodes.Nonlocal) and name in child.names
+ isinstance(child, nodes.Nonlocal) and node.name in child.names
for child in defframe.get_children()
)
if (
base_scope_type == "lambda"
and isinstance(frame, nodes.ClassDef)
- and name in frame.locals
+ and node.name in frame.locals
):
# This rule verifies that if the definition node of the
@@ -1425,7 +1430,7 @@ class VariablesChecker(BaseChecker):
maybee0601 = not (
isinstance(defnode, nodes.Arguments)
and node in defnode.defaults
- and frame.locals[name][0].fromlineno < defstmt.fromlineno
+ and frame.locals[node.name][0].fromlineno < defstmt.fromlineno
)
elif isinstance(defframe, nodes.ClassDef) and isinstance(
frame, nodes.FunctionDef
@@ -1439,7 +1444,7 @@ class VariablesChecker(BaseChecker):
if (
maybee0601
and defframe.name in defframe.locals
- and defframe.locals[name][0].lineno < frame.lineno
+ and defframe.locals[node.name][0].lineno < frame.lineno
):
# Detect class assignments with the same
# name as the class. In this case, no warning
@@ -1538,7 +1543,7 @@ class VariablesChecker(BaseChecker):
for definition in defstmt_parent.orelse:
if isinstance(definition, nodes.Assign):
defined_in_or_else = any(
- target.name == name
+ target.name == node.name
for target in definition.targets
if isinstance(target, nodes.AssignName)
)
@@ -1551,13 +1556,11 @@ class VariablesChecker(BaseChecker):
return maybee0601, annotation_return, use_outer_definition
@staticmethod
- def _is_only_type_assignment(
- node: nodes.Name, name: str, defstmt: nodes.Statement
- ) -> bool:
+ def _is_only_type_assignment(node: nodes.Name, defstmt: nodes.Statement) -> bool:
"""Check if variable only gets assigned a type and never a value"""
if not isinstance(defstmt, nodes.AnnAssign) or defstmt.value:
return False
- for ref_node in node.scope().locals[name][1:]:
+ for ref_node in node.scope().locals[node.name][1:]:
if ref_node.lineno < node.lineno:
if not (
isinstance(ref_node.parent, nodes.AnnAssign)
@@ -1612,11 +1615,11 @@ class VariablesChecker(BaseChecker):
and name in frame_locals
)
- def _loopvar_name(self, node, name):
+ def _loopvar_name(self, node: astroid.Name) -> None:
# filter variables according to node's scope
if not self.linter.is_message_enabled("undefined-loop-variable"):
return
- astmts = [stmt for stmt in node.lookup(name)[1] if hasattr(stmt, "assign_type")]
+ astmts = [s for s in node.lookup(node.name)[1] if hasattr(s, "assign_type")]
# If this variable usage exists inside a function definition
# that exists in the same loop,
# the usage is safe because the function will not be defined either if
@@ -1661,13 +1664,13 @@ class VariablesChecker(BaseChecker):
# For functions we can do more by inferring the length of the itered object
if not isinstance(assign, nodes.For):
- self.add_message("undefined-loop-variable", args=name, node=node)
+ self.add_message("undefined-loop-variable", args=node.name, node=node)
return
try:
inferred = next(assign.iter.infer())
except astroid.InferenceError:
- self.add_message("undefined-loop-variable", args=name, node=node)
+ self.add_message("undefined-loop-variable", args=node.name, node=node)
else:
if (
isinstance(inferred, astroid.Instance)
@@ -1685,12 +1688,12 @@ class VariablesChecker(BaseChecker):
astroid.objects.FrozenSet,
)
if not isinstance(inferred, sequences):
- self.add_message("undefined-loop-variable", args=name, node=node)
+ self.add_message("undefined-loop-variable", args=node.name, node=node)
return
elements = getattr(inferred, "elts", getattr(inferred, "items", []))
if not elements:
- self.add_message("undefined-loop-variable", args=name, node=node)
+ self.add_message("undefined-loop-variable", args=node.name, node=node)
def _check_is_unused(self, name, node, stmt, global_names, nonlocal_names):
# pylint: disable=too-many-branches