summaryrefslogtreecommitdiff
path: root/pylint/checkers/variables.py
diff options
context:
space:
mode:
Diffstat (limited to 'pylint/checkers/variables.py')
-rw-r--r--pylint/checkers/variables.py51
1 files changed, 29 insertions, 22 deletions
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 86b7eb669..a1cee36a0 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -1110,7 +1110,7 @@ class VariablesChecker(BaseChecker):
It's important that all 'Name' nodes are visited, otherwise the
'NamesConsumers' won't be correct.
"""
- stmt = node.statement()
+ stmt = node.statement(future=True)
if stmt.fromlineno is None:
# name node from an astroid built from live code, skip
assert not stmt.root().file.endswith(".py")
@@ -1261,7 +1261,7 @@ class VariablesChecker(BaseChecker):
return (VariableVisitConsumerAction.CONSUME, found_nodes)
defnode = utils.assign_parent(found_nodes[0])
- defstmt = defnode.statement()
+ defstmt = defnode.statement(future=True)
defframe = defstmt.frame()
# The class reuses itself in the class scope.
@@ -1515,7 +1515,10 @@ class VariablesChecker(BaseChecker):
@staticmethod
def _defined_in_function_definition(node, frame):
in_annotation_or_default_or_decorator = False
- if isinstance(frame, nodes.FunctionDef) and node.statement() is frame:
+ if (
+ isinstance(frame, nodes.FunctionDef)
+ and node.statement(future=True) is frame
+ ):
in_annotation_or_default_or_decorator = (
(
node in frame.args.annotations
@@ -1563,8 +1566,8 @@ class VariablesChecker(BaseChecker):
def _is_variable_violation(
node: nodes.Name,
defnode,
- stmt,
- defstmt,
+ stmt: nodes.Statement,
+ defstmt: nodes.Statement,
frame, # scope of statement of node
defframe,
base_scope_type,
@@ -1753,12 +1756,8 @@ class VariablesChecker(BaseChecker):
return maybe_before_assign, annotation_return, use_outer_definition
- # pylint: disable-next=fixme
- # TODO: The typing of `NodeNG.statement()` in astroid is non-specific
- # After this has been updated the typing of `defstmt` should reflect this
- # See: https://github.com/PyCQA/astroid/pull/1217
@staticmethod
- def _is_only_type_assignment(node: nodes.Name, defstmt: nodes.NodeNG) -> 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
@@ -1866,7 +1865,7 @@ class VariablesChecker(BaseChecker):
# ...
name = node.name
- frame = node.statement().scope()
+ frame = node.statement(future=True).scope()
in_annotation_or_default_or_decorator = self._defined_in_function_definition(
node, frame
)
@@ -1890,29 +1889,36 @@ class VariablesChecker(BaseChecker):
# the variable is not defined.
scope = node.scope()
if isinstance(scope, nodes.FunctionDef) and any(
- asmt.statement().parent_of(scope) for asmt in astmts
+ asmt.scope().parent_of(scope) for asmt in astmts
):
return
-
- # filter variables according their respective scope test is_statement
- # and parent to avoid #74747. This is not a total fix, which would
+ # Filter variables according to their respective scope. Test parent
+ # and statement to avoid #74747. This is not a total fix, which would
# introduce a mechanism similar to special attribute lookup in
# modules. Also, in order to get correct inference in this case, the
# scope lookup rules would need to be changed to return the initial
# assignment (which does not exist in code per se) as well as any later
# modifications.
+ # pylint: disable-next=too-many-boolean-expressions
if (
not astmts
- or (astmts[0].is_statement or astmts[0].parent)
- and astmts[0].statement().parent_of(node)
+ or (
+ astmts[0].parent == astmts[0].root()
+ and astmts[0].parent.parent_of(node)
+ )
+ or (
+ astmts[0].is_statement
+ or not isinstance(astmts[0].parent, nodes.Module)
+ and astmts[0].statement(future=True).parent_of(node)
+ )
):
_astmts = []
else:
_astmts = astmts[:1]
for i, stmt in enumerate(astmts[1:]):
- if astmts[i].statement().parent_of(stmt) and not in_for_else_branch(
- astmts[i].statement(), stmt
- ):
+ if astmts[i].statement(future=True).parent_of(
+ stmt
+ ) and not in_for_else_branch(astmts[i].statement(future=True), stmt):
continue
_astmts.append(stmt)
astmts = _astmts
@@ -1922,7 +1928,7 @@ class VariablesChecker(BaseChecker):
assign = astmts[0].assign_type()
if not (
isinstance(assign, (nodes.For, nodes.Comprehension, nodes.GeneratorExp))
- and assign.statement() is not node.statement()
+ and assign.statement(future=True) is not node.statement(future=True)
):
return
@@ -2136,7 +2142,8 @@ class VariablesChecker(BaseChecker):
maybe_for
and maybe_for.parent_of(node_scope)
and not utils.is_being_called(node_scope)
- and not isinstance(node_scope.statement(), nodes.Return)
+ and node_scope.parent
+ and not isinstance(node_scope.statement(future=True), nodes.Return)
):
self.add_message("cell-var-from-loop", node=node, args=node.name)