summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Mueller <30130371+cdce8p@users.noreply.github.com>2021-08-18 22:10:56 +0200
committerGitHub <noreply@github.com>2021-08-18 22:10:56 +0200
commit9cc3ffae26b049e91737fdff8dbcadb3c15b9825 (patch)
tree858b529a3a9c93f7802191785cca6604fcacf59e
parente135dc813ea5d60afea5d2931e233d873ded6f4e (diff)
downloadpylint-git-9cc3ffae26b049e91737fdff8dbcadb3c15b9825.tar.gz
Use alias for astroid.nodes 03 (#4866)
* Use alias for astroid nodes 03 * Resolve name conflicts * Apply suggestions from code review Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
-rw-r--r--pylint/checkers/refactoring/len_checker.py17
-rw-r--r--pylint/checkers/refactoring/not_checker.py7
-rw-r--r--pylint/checkers/refactoring/recommendation_checker.py94
-rw-r--r--pylint/checkers/utils.py367
-rw-r--r--pylint/checkers/variables.py283
-rw-r--r--pylint/extensions/_check_docs_utils.py29
6 files changed, 387 insertions, 410 deletions
diff --git a/pylint/checkers/refactoring/len_checker.py b/pylint/checkers/refactoring/len_checker.py
index 24cbd546f..6bfe2fdf5 100644
--- a/pylint/checkers/refactoring/len_checker.py
+++ b/pylint/checkers/refactoring/len_checker.py
@@ -3,6 +3,7 @@
from typing import List
import astroid
+from astroid import nodes
from pylint import checkers, interfaces
from pylint.checkers import utils
@@ -60,7 +61,7 @@ class LenChecker(checkers.BaseChecker):
# the len() call could also be nested together with other
# boolean operations, e.g. `if z or len(x):`
parent = node.parent
- while isinstance(parent, astroid.BoolOp):
+ while isinstance(parent, nodes.BoolOp):
parent = parent.parent
# we're finally out of any nested boolean operations so check if
# this len() call is part of a test condition
@@ -68,10 +69,10 @@ class LenChecker(checkers.BaseChecker):
return
len_arg = node.args[0]
generator_or_comprehension = (
- astroid.ListComp,
- astroid.SetComp,
- astroid.DictComp,
- astroid.GeneratorExp,
+ nodes.ListComp,
+ nodes.SetComp,
+ nodes.DictComp,
+ nodes.GeneratorExp,
)
if isinstance(len_arg, generator_or_comprehension):
# The node is a generator or comprehension as in len([x for x in ...])
@@ -92,7 +93,7 @@ class LenChecker(checkers.BaseChecker):
self.add_message("len-as-condition", node=node)
@staticmethod
- def instance_has_bool(class_def: astroid.ClassDef) -> bool:
+ def instance_has_bool(class_def: nodes.ClassDef) -> bool:
try:
class_def.getattr("__bool__")
return True
@@ -106,14 +107,14 @@ class LenChecker(checkers.BaseChecker):
is a test condition or something else (boolean expression)
e.g. `if not len(S):`"""
if (
- isinstance(node, astroid.UnaryOp)
+ isinstance(node, nodes.UnaryOp)
and node.op == "not"
and utils.is_call_of_name(node.operand, "len")
):
self.add_message("len-as-condition", node=node)
@staticmethod
- def base_classes_of_node(instance: astroid.nodes.ClassDef) -> List[astroid.Name]:
+ def base_classes_of_node(instance: nodes.ClassDef) -> List[nodes.Name]:
"""Return all the classes names that a ClassDef inherit from including 'object'."""
try:
return [instance.name] + [x.name for x in instance.ancestors()]
diff --git a/pylint/checkers/refactoring/not_checker.py b/pylint/checkers/refactoring/not_checker.py
index 5ea8066d5..4a778be5f 100644
--- a/pylint/checkers/refactoring/not_checker.py
+++ b/pylint/checkers/refactoring/not_checker.py
@@ -3,6 +3,7 @@
import astroid
+from astroid import nodes
from pylint import checkers, interfaces
from pylint.checkers import utils
@@ -37,7 +38,7 @@ class NotChecker(checkers.BaseChecker):
}
# sets are not ordered, so for example "not set(LEFT_VALS) <= set(RIGHT_VALS)" is
# not equivalent to "set(LEFT_VALS) > set(RIGHT_VALS)"
- skipped_nodes = (astroid.Set,)
+ skipped_nodes = (nodes.Set,)
# 'builtins' py3, '__builtin__' py2
skipped_classnames = [f"{BUILTINS}.{qname}" for qname in ("set", "frozenset")]
@@ -47,13 +48,13 @@ class NotChecker(checkers.BaseChecker):
return
operand = node.operand
- if isinstance(operand, astroid.UnaryOp) and operand.op == "not":
+ if isinstance(operand, nodes.UnaryOp) and operand.op == "not":
self.add_message(
"unneeded-not",
node=node,
args=(node.as_string(), operand.operand.as_string()),
)
- elif isinstance(operand, astroid.Compare):
+ elif isinstance(operand, nodes.Compare):
left = operand.left
# ignore multiple comparisons
if len(operand.ops) > 1:
diff --git a/pylint/checkers/refactoring/recommendation_checker.py b/pylint/checkers/refactoring/recommendation_checker.py
index b7bda5754..7893f9578 100644
--- a/pylint/checkers/refactoring/recommendation_checker.py
+++ b/pylint/checkers/refactoring/recommendation_checker.py
@@ -3,6 +3,7 @@
from typing import Union, cast
import astroid
+from astroid import nodes
from pylint import checkers, interfaces
from pylint.checkers import utils
@@ -59,33 +60,33 @@ class RecommendationChecker(checkers.BaseChecker):
return utils.is_builtin_object(inferred) and inferred.name == function
@utils.check_messages("consider-iterating-dictionary", "use-maxsplit-arg")
- def visit_call(self, node: astroid.Call) -> None:
+ def visit_call(self, node: nodes.Call) -> None:
self._check_consider_iterating_dictionary(node)
self._check_use_maxsplit_arg(node)
- def _check_consider_iterating_dictionary(self, node: astroid.Call) -> None:
- if not isinstance(node.func, astroid.Attribute):
+ def _check_consider_iterating_dictionary(self, node: nodes.Call) -> None:
+ if not isinstance(node.func, nodes.Attribute):
return
if node.func.attrname != "keys":
return
- if not isinstance(node.parent, (astroid.For, astroid.Comprehension)):
+ if not isinstance(node.parent, (nodes.For, nodes.Comprehension)):
return
inferred = utils.safe_infer(node.func)
if not isinstance(inferred, astroid.BoundMethod) or not isinstance(
- inferred.bound, astroid.Dict
+ inferred.bound, nodes.Dict
):
return
- if isinstance(node.parent, (astroid.For, astroid.Comprehension)):
+ if isinstance(node.parent, (nodes.For, nodes.Comprehension)):
self.add_message("consider-iterating-dictionary", node=node)
- def _check_use_maxsplit_arg(self, node: astroid.Call) -> None:
+ def _check_use_maxsplit_arg(self, node: nodes.Call) -> None:
"""Add message when accessing first or last elements of a str.split() or str.rsplit()."""
# Check if call is split() or rsplit()
if not (
- isinstance(node.func, astroid.Attribute)
+ isinstance(node.func, nodes.Attribute)
and node.func.attrname in ("split", "rsplit")
and isinstance(utils.safe_infer(node.func), astroid.BoundMethod)
):
@@ -103,28 +104,28 @@ class RecommendationChecker(checkers.BaseChecker):
except utils.NoSuchArgumentError:
pass
- if isinstance(node.parent, astroid.Subscript):
+ if isinstance(node.parent, nodes.Subscript):
try:
subscript_value = utils.get_subscript_const_value(node.parent).value
except utils.InferredTypeError:
return
# Check for cases where variable (Name) subscripts may be mutated within a loop
- if isinstance(node.parent.slice, astroid.Name):
+ if isinstance(node.parent.slice, nodes.Name):
# Check if loop present within the scope of the node
scope = node.scope()
- for loop_node in scope.nodes_of_class((astroid.For, astroid.While)):
- loop_node = cast(astroid.node_classes.NodeNG, loop_node)
+ for loop_node in scope.nodes_of_class((nodes.For, nodes.While)):
+ loop_node = cast(nodes.NodeNG, loop_node)
if not loop_node.parent_of(node):
continue
# Check if var is mutated within loop (Assign/AugAssign)
- for assignment_node in loop_node.nodes_of_class(astroid.AugAssign):
- assignment_node = cast(astroid.AugAssign, assignment_node)
+ for assignment_node in loop_node.nodes_of_class(nodes.AugAssign):
+ assignment_node = cast(nodes.AugAssign, assignment_node)
if node.parent.slice.name == assignment_node.target.name:
return
- for assignment_node in loop_node.nodes_of_class(astroid.Assign):
- assignment_node = cast(astroid.Assign, assignment_node)
+ for assignment_node in loop_node.nodes_of_class(nodes.Assign):
+ assignment_node = cast(nodes.Assign, assignment_node)
if node.parent.slice.name in [
n.name for n in assignment_node.targets
]:
@@ -145,27 +146,26 @@ class RecommendationChecker(checkers.BaseChecker):
"consider-using-dict-items",
"use-sequence-for-iteration",
)
- def visit_for(self, node: astroid.For) -> None:
+ def visit_for(self, node: nodes.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:
+ def _check_consider_using_enumerate(self, node: nodes.For) -> None:
"""Emit a convention whenever range and len are used for indexing."""
# Verify that we have a `range([start], len(...), [stop])` call and
# that the object which is iterated is used as a subscript in the
# body of the for.
# Is it a proper range call?
- if not isinstance(node.iter, astroid.Call):
+ if not isinstance(node.iter, nodes.Call):
return
if not self._is_builtin(node.iter.func, "range"):
return
if not node.iter.args:
return
is_constant_zero = (
- isinstance(node.iter.args[0], astroid.Const)
- and node.iter.args[0].value == 0
+ isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
)
if len(node.iter.args) == 2 and not is_constant_zero:
return
@@ -173,7 +173,7 @@ class RecommendationChecker(checkers.BaseChecker):
return
# Is it a proper len call?
- if not isinstance(node.iter.args[-1], astroid.Call):
+ if not isinstance(node.iter.args[-1], nodes.Call):
return
second_func = node.iter.args[-1].func
if not self._is_builtin(second_func, "len"):
@@ -182,16 +182,16 @@ class RecommendationChecker(checkers.BaseChecker):
if not len_args or len(len_args) != 1:
return
iterating_object = len_args[0]
- if isinstance(iterating_object, astroid.Name):
- expected_subscript_val_type = astroid.Name
- elif isinstance(iterating_object, astroid.Attribute):
- expected_subscript_val_type = astroid.Attribute
+ if isinstance(iterating_object, nodes.Name):
+ expected_subscript_val_type = nodes.Name
+ elif isinstance(iterating_object, nodes.Attribute):
+ expected_subscript_val_type = nodes.Attribute
else:
return
# If we're defining __iter__ on self, enumerate won't work
scope = node.scope()
if (
- isinstance(iterating_object, astroid.Name)
+ isinstance(iterating_object, nodes.Name)
and iterating_object.name == "self"
and scope.name == "__iter__"
):
@@ -202,13 +202,13 @@ class RecommendationChecker(checkers.BaseChecker):
# in order to make sure that the same object is used in the
# for body.
for child in node.body:
- for subscript in child.nodes_of_class(astroid.Subscript):
- subscript = cast(astroid.Subscript, subscript)
+ for subscript in child.nodes_of_class(nodes.Subscript):
+ subscript = cast(nodes.Subscript, subscript)
if not isinstance(subscript.value, expected_subscript_val_type):
continue
value = subscript.slice
- if not isinstance(value, astroid.Name):
+ if not isinstance(value, nodes.Name):
continue
if subscript.value.scope() != node.scope():
# Ignore this subscript if it's not in the same
@@ -217,15 +217,15 @@ class RecommendationChecker(checkers.BaseChecker):
# name for the iterating object was used.
continue
if value.name == node.target.name and (
- isinstance(subscript.value, astroid.Name)
+ isinstance(subscript.value, nodes.Name)
and iterating_object.name == subscript.value.name
- or isinstance(subscript.value, astroid.Attribute)
+ or isinstance(subscript.value, nodes.Attribute)
and iterating_object.attrname == subscript.value.attrname
):
self.add_message("consider-using-enumerate", node=node)
return
- def _check_consider_using_dict_items(self, node: astroid.For) -> None:
+ def _check_consider_using_dict_items(self, node: nodes.For) -> None:
"""Add message when accessing dict values by index lookup."""
# Verify that we have a .keys() call and
# that the object which is iterated is used as a subscript in the
@@ -240,15 +240,15 @@ class RecommendationChecker(checkers.BaseChecker):
# in order to make sure that the same object is used in the
# for body.
for child in node.body:
- for subscript in child.nodes_of_class(astroid.Subscript):
- subscript = cast(astroid.Subscript, subscript)
+ for subscript in child.nodes_of_class(nodes.Subscript):
+ subscript = cast(nodes.Subscript, subscript)
- if not isinstance(subscript.value, (astroid.Name, astroid.Attribute)):
+ if not isinstance(subscript.value, (nodes.Name, nodes.Attribute)):
continue
value = subscript.slice
if (
- not isinstance(value, astroid.Name)
+ not isinstance(value, nodes.Name)
or value.name != node.target.name
or iterating_object_name != subscript.value.as_string()
):
@@ -261,9 +261,9 @@ class RecommendationChecker(checkers.BaseChecker):
# defined and compare that to the for loop's line number
continue
if (
- isinstance(subscript.parent, astroid.Assign)
+ isinstance(subscript.parent, nodes.Assign)
and subscript in subscript.parent.targets
- or isinstance(subscript.parent, astroid.AugAssign)
+ or isinstance(subscript.parent, nodes.AugAssign)
and subscript == subscript.parent.target
):
# Ignore this subscript if it is the target of an assignment
@@ -277,12 +277,12 @@ class RecommendationChecker(checkers.BaseChecker):
"consider-using-dict-items",
"use-sequence-for-iteration",
)
- def visit_comprehension(self, node: astroid.Comprehension) -> None:
+ def visit_comprehension(self, node: nodes.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
+ self, node: nodes.Comprehension
) -> None:
"""Add message when accessing dict values by index lookup."""
iterating_object_name = utils.get_iterating_dictionary_name(node)
@@ -290,15 +290,15 @@ class RecommendationChecker(checkers.BaseChecker):
return
for child in node.parent.get_children():
- for subscript in child.nodes_of_class(astroid.Subscript):
- subscript = cast(astroid.Subscript, subscript)
+ for subscript in child.nodes_of_class(nodes.Subscript):
+ subscript = cast(nodes.Subscript, subscript)
- if not isinstance(subscript.value, (astroid.Name, astroid.Attribute)):
+ if not isinstance(subscript.value, (nodes.Name, nodes.Attribute)):
continue
value = subscript.slice
if (
- not isinstance(value, astroid.Name)
+ not isinstance(value, nodes.Name)
or value.name != node.target.name
or iterating_object_name != subscript.value.as_string()
):
@@ -308,8 +308,8 @@ class RecommendationChecker(checkers.BaseChecker):
return
def _check_use_sequence_for_iteration(
- self, node: Union[astroid.For, astroid.Comprehension]
+ self, node: Union[nodes.For, nodes.Comprehension]
) -> None:
"""Check if code iterates over an in-place defined set."""
- if isinstance(node.iter, astroid.Set):
+ if isinstance(node.iter, nodes.Set):
self.add_message("use-sequence-for-iteration", node=node.iter)
diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index aa445a708..58e950ce2 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -73,15 +73,15 @@ from typing import (
import _string
import astroid
import astroid.objects
-from astroid import TooManyLevelsError
+from astroid import TooManyLevelsError, nodes
from pylint.constants import BUILTINS
COMP_NODE_TYPES = (
- astroid.ListComp,
- astroid.SetComp,
- astroid.DictComp,
- astroid.GeneratorExp,
+ nodes.ListComp,
+ nodes.SetComp,
+ nodes.DictComp,
+ nodes.GeneratorExp,
)
EXCEPTIONS_MODULE = "builtins"
ABC_MODULES = {"abc", "_py_abc"}
@@ -282,44 +282,44 @@ class InferredTypeError(Exception):
pass
-def is_inside_lambda(node: astroid.node_classes.NodeNG) -> bool:
+def is_inside_lambda(node: nodes.NodeNG) -> bool:
"""Return true if given node is inside lambda"""
parent = node.parent
while parent is not None:
- if isinstance(parent, astroid.Lambda):
+ if isinstance(parent, nodes.Lambda):
return True
parent = parent.parent
return False
def get_all_elements(
- node: astroid.node_classes.NodeNG,
-) -> Iterable[astroid.node_classes.NodeNG]:
+ node: nodes.NodeNG,
+) -> Iterable[nodes.NodeNG]:
"""Recursively returns all atoms in nested lists and tuples."""
- if isinstance(node, (astroid.Tuple, astroid.List)):
+ if isinstance(node, (nodes.Tuple, nodes.List)):
for child in node.elts:
yield from get_all_elements(child)
else:
yield node
-def is_super(node: astroid.node_classes.NodeNG) -> bool:
+def is_super(node: nodes.NodeNG) -> bool:
"""return True if the node is referencing the "super" builtin function"""
if getattr(node, "name", None) == "super" and node.root().name == BUILTINS:
return True
return False
-def is_error(node: astroid.scoped_nodes.FunctionDef) -> bool:
+def is_error(node: nodes.FunctionDef) -> bool:
"""Return true if the given function node only raises an exception"""
- return len(node.body) == 1 and isinstance(node.body[0], astroid.Raise)
+ return len(node.body) == 1 and isinstance(node.body[0], nodes.Raise)
builtins = builtins.__dict__.copy() # type: ignore
SPECIAL_BUILTINS = ("__builtins__",) # '__path__', '__file__')
-def is_builtin_object(node: astroid.node_classes.NodeNG) -> bool:
+def is_builtin_object(node: nodes.NodeNG) -> bool:
"""Returns True if the given node is an object from the __builtin__ module."""
return node and node.root().name == BUILTINS
@@ -330,31 +330,31 @@ def is_builtin(name: str) -> bool:
def is_defined_in_scope(
- var_node: astroid.node_classes.NodeNG,
+ var_node: nodes.NodeNG,
varname: str,
- scope: astroid.node_classes.NodeNG,
+ scope: nodes.NodeNG,
) -> bool:
- if isinstance(scope, astroid.If):
+ if isinstance(scope, nodes.If):
for node in scope.body:
if (
- isinstance(node, astroid.Assign)
+ isinstance(node, nodes.Assign)
and any(
- isinstance(target, astroid.AssignName) and target.name == varname
+ isinstance(target, nodes.AssignName) and target.name == varname
for target in node.targets
)
- ) or (isinstance(node, astroid.Nonlocal) and varname in node.names):
+ ) or (isinstance(node, nodes.Nonlocal) and varname in node.names):
return True
- elif isinstance(scope, (COMP_NODE_TYPES, astroid.For)):
- for ass_node in scope.nodes_of_class(astroid.AssignName):
+ elif isinstance(scope, (COMP_NODE_TYPES, nodes.For)):
+ for ass_node in scope.nodes_of_class(nodes.AssignName):
if ass_node.name == varname:
return True
- elif isinstance(scope, astroid.With):
+ elif isinstance(scope, nodes.With):
for expr, ids in scope.items:
if expr.parent_of(var_node):
break
- if ids and isinstance(ids, astroid.AssignName) and ids.name == varname:
+ if ids and isinstance(ids, nodes.AssignName) and ids.name == varname:
return True
- elif isinstance(scope, (astroid.Lambda, astroid.FunctionDef)):
+ elif isinstance(scope, (nodes.Lambda, nodes.FunctionDef)):
if scope.args.is_argument(varname):
# If the name is found inside a default value
# of a function, then let the search continue
@@ -369,15 +369,15 @@ def is_defined_in_scope(
return True
if getattr(scope, "name", None) == varname:
return True
- elif isinstance(scope, astroid.ExceptHandler):
- if isinstance(scope.name, astroid.AssignName):
+ elif isinstance(scope, nodes.ExceptHandler):
+ if isinstance(scope.name, nodes.AssignName):
ass_node = scope.name
if ass_node.name == varname:
return True
return False
-def is_defined_before(var_node: astroid.Name) -> bool:
+def is_defined_before(var_node: nodes.Name) -> bool:
"""Check if the given variable node is defined before
Verify that the variable node is defined by a parent node
@@ -396,10 +396,10 @@ def is_defined_before(var_node: astroid.Name) -> bool:
_node = stmt.previous_sibling()
lineno = stmt.fromlineno
while _node and _node.fromlineno == lineno:
- for assign_node in _node.nodes_of_class(astroid.AssignName):
+ for assign_node in _node.nodes_of_class(nodes.AssignName):
if assign_node.name == varname:
return True
- for imp_node in _node.nodes_of_class((astroid.ImportFrom, astroid.Import)):
+ for imp_node in _node.nodes_of_class((nodes.ImportFrom, nodes.Import)):
if varname in [name[1] or name[0] for name in imp_node.names]:
return True
_node = _node.previous_sibling()
@@ -407,34 +407,33 @@ def is_defined_before(var_node: astroid.Name) -> bool:
def is_default_argument(
- node: astroid.node_classes.NodeNG,
- scope: Optional[astroid.node_classes.NodeNG] = None,
+ node: nodes.NodeNG, scope: Optional[nodes.NodeNG] = None
) -> bool:
"""return true if the given Name node is used in function or lambda
default argument's value
"""
if not scope:
scope = node.scope()
- if isinstance(scope, (astroid.FunctionDef, astroid.Lambda)):
+ if isinstance(scope, (nodes.FunctionDef, nodes.Lambda)):
for default_node in scope.args.defaults:
- for default_name_node in default_node.nodes_of_class(astroid.Name):
+ for default_name_node in default_node.nodes_of_class(nodes.Name):
if default_name_node is node:
return True
return False
-def is_func_decorator(node: astroid.node_classes.NodeNG) -> bool:
+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:
- if isinstance(parent, astroid.Decorators):
+ if isinstance(parent, nodes.Decorators):
return True
if parent.is_statement or isinstance(
parent,
(
- astroid.Lambda,
- astroid.scoped_nodes.ComprehensionScope,
- astroid.scoped_nodes.ListComp,
+ nodes.Lambda,
+ nodes.ComprehensionScope,
+ nodes.ListComp,
),
):
break
@@ -442,36 +441,34 @@ def is_func_decorator(node: astroid.node_classes.NodeNG) -> bool:
return False
-def is_ancestor_name(
- frame: astroid.ClassDef, node: astroid.node_classes.NodeNG
-) -> bool:
+def is_ancestor_name(frame: nodes.ClassDef, node: nodes.NodeNG) -> bool:
"""return True if `frame` is an astroid.Class node with `node` in the
subtree of its bases attribute
"""
- if not isinstance(frame, astroid.ClassDef):
+ if not isinstance(frame, nodes.ClassDef):
return False
for base in frame.bases:
- if node in base.nodes_of_class(astroid.Name):
+ if node in base.nodes_of_class(nodes.Name):
return True
return False
-def is_being_called(node: astroid.node_classes.NodeNG) -> bool:
+def is_being_called(node: nodes.NodeNG) -> bool:
"""return True if node is the function being called in a Call node"""
- return isinstance(node.parent, astroid.Call) and node.parent.func is node
+ return isinstance(node.parent, nodes.Call) and node.parent.func is node
-def assign_parent(node: astroid.node_classes.NodeNG) -> astroid.node_classes.NodeNG:
+def assign_parent(node: nodes.NodeNG) -> nodes.NodeNG:
"""return the higher parent which is not an AssignName, Tuple or List node"""
- while node and isinstance(node, (astroid.AssignName, astroid.Tuple, astroid.List)):
+ while node and isinstance(node, (nodes.AssignName, nodes.Tuple, nodes.List)):
node = node.parent
return node
-def overrides_a_method(class_node: astroid.ClassDef, name: str) -> bool:
+def overrides_a_method(class_node: nodes.ClassDef, name: str) -> bool:
"""return True if <name> is a method overridden from an ancestor"""
for ancestor in class_node.ancestors():
- if name in ancestor and isinstance(ancestor[name], astroid.FunctionDef):
+ if name in ancestor and isinstance(ancestor[name], nodes.FunctionDef):
return True
return False
@@ -653,7 +650,7 @@ def is_attr_protected(attrname: str) -> bool:
)
-def node_frame_class(node: astroid.node_classes.NodeNG) -> Optional[astroid.ClassDef]:
+def node_frame_class(node: nodes.NodeNG) -> Optional[nodes.ClassDef]:
"""Return the class that is wrapping the given node
The function returns a class for a method node (or a staticmethod or a
@@ -661,14 +658,14 @@ def node_frame_class(node: astroid.node_classes.NodeNG) -> Optional[astroid.Clas
"""
klass = node.frame()
nodes_to_check = (
- astroid.node_classes.NodeNG,
+ nodes.NodeNG,
astroid.UnboundMethod,
astroid.BaseInstance,
)
while (
klass
and isinstance(klass, nodes_to_check)
- and not isinstance(klass, astroid.ClassDef)
+ and not isinstance(klass, nodes.ClassDef)
):
if klass.parent is None:
return None
@@ -687,16 +684,16 @@ def is_attr_private(attrname: str) -> Optional[Match[str]]:
def get_argument_from_call(
- call_node: astroid.Call, position: int = None, keyword: str = None
-) -> astroid.Name:
+ call_node: nodes.Call, position: int = None, keyword: str = None
+) -> nodes.Name:
"""Returns the specified argument from a function call.
- :param astroid.Call call_node: Node representing a function call to check.
+ :param nodes.Call call_node: Node representing a function call to check.
:param int position: position of the argument.
:param str keyword: the keyword of the argument.
:returns: The node representing the argument, None if the argument is not found.
- :rtype: astroid.Name
+ :rtype: nodes.Name
:raises ValueError: if both position and keyword are None.
:raises NoSuchArgumentError: if no argument at the provided position or with
the provided keyword.
@@ -716,7 +713,7 @@ def get_argument_from_call(
raise NoSuchArgumentError
-def inherit_from_std_ex(node: astroid.node_classes.NodeNG) -> bool:
+def inherit_from_std_ex(node: nodes.NodeNG) -> bool:
"""
Return true if the given class node is subclass of
exceptions.Exception.
@@ -731,7 +728,7 @@ def inherit_from_std_ex(node: astroid.node_classes.NodeNG) -> bool:
return False
-def error_of_type(handler: astroid.ExceptHandler, error_type) -> bool:
+def error_of_type(handler: nodes.ExceptHandler, error_type) -> bool:
"""
Check if the given exception handler catches
the given error_type.
@@ -756,7 +753,7 @@ def error_of_type(handler: astroid.ExceptHandler, error_type) -> bool:
return handler.catch(expected_errors)
-def decorated_with_property(node: astroid.FunctionDef) -> bool:
+def decorated_with_property(node: nodes.FunctionDef) -> bool:
"""Detect if the given function node is decorated with a property."""
if not node.decorators:
return False
@@ -770,65 +767,65 @@ def decorated_with_property(node: astroid.FunctionDef) -> bool:
def _is_property_kind(node, *kinds):
- if not isinstance(node, (astroid.UnboundMethod, astroid.FunctionDef)):
+ if not isinstance(node, (astroid.UnboundMethod, nodes.FunctionDef)):
return False
if node.decorators:
for decorator in node.decorators.nodes:
- if isinstance(decorator, astroid.Attribute) and decorator.attrname in kinds:
+ if isinstance(decorator, nodes.Attribute) and decorator.attrname in kinds:
return True
return False
-def is_property_setter(node: astroid.FunctionDef) -> bool:
+def is_property_setter(node: nodes.FunctionDef) -> bool:
"""Check if the given node is a property setter"""
return _is_property_kind(node, "setter")
-def is_property_deleter(node: astroid.FunctionDef) -> bool:
+def is_property_deleter(node: nodes.FunctionDef) -> bool:
"""Check if the given node is a property deleter"""
return _is_property_kind(node, "deleter")
-def is_property_setter_or_deleter(node: astroid.FunctionDef) -> bool:
+def is_property_setter_or_deleter(node: nodes.FunctionDef) -> bool:
"""Check if the given node is either a property setter or a deleter"""
return _is_property_kind(node, "setter", "deleter")
-def _is_property_decorator(decorator: astroid.Name) -> bool:
+def _is_property_decorator(decorator: nodes.Name) -> bool:
for inferred in decorator.infer():
- if isinstance(inferred, astroid.ClassDef):
+ if isinstance(inferred, nodes.ClassDef):
if inferred.qname() in ("builtins.property", "functools.cached_property"):
return True
for ancestor in inferred.ancestors():
if ancestor.name == "property" and ancestor.root().name == BUILTINS:
return True
- elif isinstance(inferred, astroid.FunctionDef):
+ elif isinstance(inferred, nodes.FunctionDef):
# If decorator is function, check if it has exactly one return
# and the return is itself a function decorated with property
- returns: List[astroid.Return] = list(
+ returns: List[nodes.Return] = list(
inferred._get_return_nodes_skip_functions()
)
if len(returns) == 1 and isinstance(
- returns[0].value, (astroid.Name, astroid.Attribute)
+ returns[0].value, (nodes.Name, nodes.Attribute)
):
inferred = safe_infer(returns[0].value)
if (
inferred
and isinstance(inferred, astroid.objects.Property)
- and isinstance(inferred.function, astroid.FunctionDef)
+ and isinstance(inferred.function, nodes.FunctionDef)
):
return decorated_with_property(inferred.function)
return False
def decorated_with(
- func: Union[astroid.FunctionDef, astroid.BoundMethod, astroid.UnboundMethod],
+ func: Union[nodes.FunctionDef, astroid.BoundMethod, astroid.UnboundMethod],
qnames: Iterable[str],
) -> bool:
"""Determine if the `func` node has a decorator with the qualified name `qname`."""
decorators = func.decorators.nodes if func.decorators else []
for decorator_node in decorators:
- if isinstance(decorator_node, astroid.Call):
+ if isinstance(decorator_node, nodes.Call):
# We only want to infer the function name
decorator_node = decorator_node.func
try:
@@ -845,8 +842,8 @@ def decorated_with(
@lru_cache(maxsize=1024)
def unimplemented_abstract_methods(
- node: astroid.ClassDef, is_abstract_cb: astroid.FunctionDef = None
-) -> Dict[str, astroid.node_classes.NodeNG]:
+ node: nodes.ClassDef, is_abstract_cb: nodes.FunctionDef = None
+) -> Dict[str, nodes.NodeNG]:
"""
Get the unimplemented abstract methods for the given *node*.
@@ -860,7 +857,7 @@ def unimplemented_abstract_methods(
"""
if is_abstract_cb is None:
is_abstract_cb = partial(decorated_with, qnames=ABC_METHODS)
- visited: Dict[str, astroid.node_classes.NodeNG] = {}
+ visited: Dict[str, nodes.NodeNG] = {}
try:
mro = reversed(node.mro())
except NotImplementedError:
@@ -873,7 +870,7 @@ def unimplemented_abstract_methods(
for ancestor in mro:
for obj in ancestor.values():
inferred = obj
- if isinstance(obj, astroid.AssignName):
+ if isinstance(obj, nodes.AssignName):
inferred = safe_infer(obj)
if not inferred:
# Might be an abstract function,
@@ -883,10 +880,10 @@ def unimplemented_abstract_methods(
if obj.name in visited:
del visited[obj.name]
continue
- if not isinstance(inferred, astroid.FunctionDef):
+ if not isinstance(inferred, nodes.FunctionDef):
if obj.name in visited:
del visited[obj.name]
- if isinstance(inferred, astroid.FunctionDef):
+ if isinstance(inferred, nodes.FunctionDef):
# It's critical to use the original name,
# since after inferring, an object can be something
# else than expected, as in the case of the
@@ -904,11 +901,11 @@ def unimplemented_abstract_methods(
def find_try_except_wrapper_node(
- node: astroid.node_classes.NodeNG,
-) -> Optional[Union[astroid.ExceptHandler, astroid.TryExcept]]:
+ node: nodes.NodeNG,
+) -> Optional[Union[nodes.ExceptHandler, nodes.TryExcept]]:
"""Return the ExceptHandler or the TryExcept node in which the node is."""
current = node
- ignores = (astroid.ExceptHandler, astroid.TryExcept)
+ ignores = (nodes.ExceptHandler, nodes.TryExcept)
while current and not isinstance(current.parent, ignores):
current = current.parent
@@ -918,8 +915,8 @@ def find_try_except_wrapper_node(
def find_except_wrapper_node_in_scope(
- node: astroid.node_classes.NodeNG,
-) -> Optional[Union[astroid.ExceptHandler, astroid.TryExcept]]:
+ 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:
@@ -930,18 +927,18 @@ def find_except_wrapper_node_in_scope(
# function/class was defined in an `except` clause, rather than the current code
# actually running in an `except` clause.
return None
- if isinstance(current, astroid.ExceptHandler):
+ if isinstance(current, nodes.ExceptHandler):
return current
return None
-def is_from_fallback_block(node: astroid.node_classes.NodeNG) -> bool:
+def is_from_fallback_block(node: nodes.NodeNG) -> bool:
"""Check if the given node is from a fallback import block."""
context = find_try_except_wrapper_node(node)
if not context:
return False
- if isinstance(context, astroid.ExceptHandler):
+ if isinstance(context, nodes.ExceptHandler):
other_body = context.parent.body
handlers = context.parent.handlers
else:
@@ -951,7 +948,7 @@ def is_from_fallback_block(node: astroid.node_classes.NodeNG) -> bool:
handlers = context.handlers
has_fallback_imports = any(
- isinstance(import_node, (astroid.ImportFrom, astroid.Import))
+ isinstance(import_node, (nodes.ImportFrom, nodes.Import))
for import_node in other_body
)
ignores_import_error = _except_handlers_ignores_exception(handlers, ImportError)
@@ -959,19 +956,19 @@ def is_from_fallback_block(node: astroid.node_classes.NodeNG) -> bool:
def _except_handlers_ignores_exception(
- handlers: astroid.ExceptHandler, exception
+ handlers: nodes.ExceptHandler, exception
) -> bool:
func = partial(error_of_type, error_type=(exception,))
return any(func(handler) for handler in handlers)
def get_exception_handlers(
- node: astroid.node_classes.NodeNG, exception=Exception
-) -> Optional[List[astroid.ExceptHandler]]:
+ node: nodes.NodeNG, exception=Exception
+) -> Optional[List[nodes.ExceptHandler]]:
"""Return the collections of handlers handling the exception in arguments.
Args:
- node (astroid.NodeNG): A node that is potentially wrapped in a try except.
+ node (nodes.NodeNG): A node that is potentially wrapped in a try except.
exception (builtin.Exception or str): exception or name of the exception.
Returns:
@@ -979,30 +976,28 @@ def get_exception_handlers(
"""
context = find_try_except_wrapper_node(node)
- if isinstance(context, astroid.TryExcept):
+ if isinstance(context, nodes.TryExcept):
return [
handler for handler in context.handlers if error_of_type(handler, exception)
]
return []
-def is_node_inside_try_except(node: astroid.Raise) -> bool:
+def is_node_inside_try_except(node: nodes.Raise) -> bool:
"""Check if the node is directly under a Try/Except statement.
(but not under an ExceptHandler!)
Args:
- node (astroid.Raise): the node raising the exception.
+ node (nodes.Raise): the node raising the exception.
Returns:
bool: True if the node is inside a try/except statement, False otherwise.
"""
context = find_try_except_wrapper_node(node)
- return isinstance(context, astroid.TryExcept)
+ return isinstance(context, nodes.TryExcept)
-def node_ignores_exception(
- node: astroid.node_classes.NodeNG, exception=Exception
-) -> bool:
+def node_ignores_exception(node: nodes.NodeNG, exception=Exception) -> bool:
"""Check if the node is in a TryExcept which handles the given exception.
If the exception is not given, the function is going to look for bare
@@ -1014,7 +1009,7 @@ def node_ignores_exception(
return any(managing_handlers)
-def class_is_abstract(node: astroid.ClassDef) -> bool:
+def class_is_abstract(node: nodes.ClassDef) -> bool:
"""return true if the given class node should be considered as an abstract
class
"""
@@ -1036,58 +1031,58 @@ def class_is_abstract(node: astroid.ClassDef) -> bool:
return False
-def _supports_protocol_method(value: astroid.node_classes.NodeNG, attr: str) -> bool:
+def _supports_protocol_method(value: nodes.NodeNG, attr: str) -> bool:
try:
attributes = value.getattr(attr)
except astroid.NotFoundError:
return False
first = attributes[0]
- if isinstance(first, astroid.AssignName):
- if isinstance(first.parent.value, astroid.Const):
+ if isinstance(first, nodes.AssignName):
+ if isinstance(first.parent.value, nodes.Const):
return False
return True
-def is_comprehension(node: astroid.node_classes.NodeNG) -> bool:
+def is_comprehension(node: nodes.NodeNG) -> bool:
comprehensions = (
- astroid.ListComp,
- astroid.SetComp,
- astroid.DictComp,
- astroid.GeneratorExp,
+ nodes.ListComp,
+ nodes.SetComp,
+ nodes.DictComp,
+ nodes.GeneratorExp,
)
return isinstance(node, comprehensions)
-def _supports_mapping_protocol(value: astroid.node_classes.NodeNG) -> bool:
+def _supports_mapping_protocol(value: nodes.NodeNG) -> bool:
return _supports_protocol_method(
value, GETITEM_METHOD
) and _supports_protocol_method(value, KEYS_METHOD)
-def _supports_membership_test_protocol(value: astroid.node_classes.NodeNG) -> bool:
+def _supports_membership_test_protocol(value: nodes.NodeNG) -> bool:
return _supports_protocol_method(value, CONTAINS_METHOD)
-def _supports_iteration_protocol(value: astroid.node_classes.NodeNG) -> bool:
+def _supports_iteration_protocol(value: nodes.NodeNG) -> bool:
return _supports_protocol_method(value, ITER_METHOD) or _supports_protocol_method(
value, GETITEM_METHOD
)
-def _supports_async_iteration_protocol(value: astroid.node_classes.NodeNG) -> bool:
+def _supports_async_iteration_protocol(value: nodes.NodeNG) -> bool:
return _supports_protocol_method(value, AITER_METHOD)
-def _supports_getitem_protocol(value: astroid.node_classes.NodeNG) -> bool:
+def _supports_getitem_protocol(value: nodes.NodeNG) -> bool:
return _supports_protocol_method(value, GETITEM_METHOD)
-def _supports_setitem_protocol(value: astroid.node_classes.NodeNG) -> bool:
+def _supports_setitem_protocol(value: nodes.NodeNG) -> bool:
return _supports_protocol_method(value, SETITEM_METHOD)
-def _supports_delitem_protocol(value: astroid.node_classes.NodeNG) -> bool:
+def _supports_delitem_protocol(value: nodes.NodeNG) -> bool:
return _supports_protocol_method(value, DELITEM_METHOD)
@@ -1099,9 +1094,9 @@ def _is_abstract_class_name(name: str) -> bool:
return is_mixin or is_abstract or is_base
-def is_inside_abstract_class(node: astroid.node_classes.NodeNG) -> bool:
+def is_inside_abstract_class(node: nodes.NodeNG) -> bool:
while node is not None:
- if isinstance(node, astroid.ClassDef):
+ if isinstance(node, nodes.ClassDef):
if class_is_abstract(node):
return True
name = getattr(node, "name", None)
@@ -1112,9 +1107,9 @@ def is_inside_abstract_class(node: astroid.node_classes.NodeNG) -> bool:
def _supports_protocol(
- value: astroid.node_classes.NodeNG, protocol_callback: astroid.FunctionDef
+ value: nodes.NodeNG, protocol_callback: nodes.FunctionDef
) -> bool:
- if isinstance(value, astroid.ClassDef):
+ if isinstance(value, nodes.ClassDef):
if not has_known_bases(value):
return True
# classobj can only be iterable if it has an iterable metaclass
@@ -1141,7 +1136,7 @@ def _supports_protocol(
return False
-def is_iterable(value: astroid.node_classes.NodeNG, check_async: bool = False) -> bool:
+def is_iterable(value: nodes.NodeNG, check_async: bool = False) -> bool:
if check_async:
protocol_check = _supports_async_iteration_protocol
else:
@@ -1149,19 +1144,17 @@ def is_iterable(value: astroid.node_classes.NodeNG, check_async: bool = False) -
return _supports_protocol(value, protocol_check)
-def is_mapping(value: astroid.node_classes.NodeNG) -> bool:
+def is_mapping(value: nodes.NodeNG) -> bool:
return _supports_protocol(value, _supports_mapping_protocol)
-def supports_membership_test(value: astroid.node_classes.NodeNG) -> bool:
+def supports_membership_test(value: nodes.NodeNG) -> bool:
supported = _supports_protocol(value, _supports_membership_test_protocol)
return supported or is_iterable(value)
-def supports_getitem(
- value: astroid.node_classes.NodeNG, node: astroid.node_classes.NodeNG
-) -> bool:
- if isinstance(value, astroid.ClassDef):
+def supports_getitem(value: nodes.NodeNG, node: nodes.NodeNG) -> bool:
+ if isinstance(value, nodes.ClassDef):
if _supports_protocol_method(value, CLASS_GETITEM_METHOD):
return True
if is_class_subscriptable_pep585_with_postponed_evaluation_enabled(value, node):
@@ -1169,11 +1162,11 @@ def supports_getitem(
return _supports_protocol(value, _supports_getitem_protocol)
-def supports_setitem(value: astroid.node_classes.NodeNG, *_: Any) -> bool:
+def supports_setitem(value: nodes.NodeNG, *_: Any) -> bool:
return _supports_protocol(value, _supports_setitem_protocol)
-def supports_delitem(value: astroid.node_classes.NodeNG, *_: Any) -> bool:
+def supports_delitem(value: nodes.NodeNG, *_: Any) -> bool:
return _supports_protocol(value, _supports_delitem_protocol)
@@ -1185,9 +1178,7 @@ def _get_python_type_of_node(node):
@lru_cache(maxsize=1024)
-def safe_infer(
- node: astroid.node_classes.NodeNG, context=None
-) -> Optional[astroid.node_classes.NodeNG]:
+def safe_infer(node: nodes.NodeNG, context=None) -> Optional[nodes.NodeNG]:
"""Return the inferred value for the given node.
Return None if inference failed or if there is some ambiguity (more than
@@ -1215,7 +1206,7 @@ def safe_infer(
return value if len(inferred_types) <= 1 else None
-def has_known_bases(klass: astroid.ClassDef, context=None) -> bool:
+def has_known_bases(klass: nodes.ClassDef, context=None) -> bool:
"""Return true if all base classes of a class could be inferred."""
try:
return klass._all_bases_known
@@ -1224,7 +1215,7 @@ def has_known_bases(klass: astroid.ClassDef, context=None) -> bool:
for base in klass.bases:
result = safe_infer(base, context=context)
if (
- not isinstance(result, astroid.ClassDef)
+ not isinstance(result, nodes.ClassDef)
or result is klass
or not has_known_bases(result, context=context)
):
@@ -1234,15 +1225,15 @@ def has_known_bases(klass: astroid.ClassDef, context=None) -> bool:
return True
-def is_none(node: astroid.node_classes.NodeNG) -> bool:
+def is_none(node: nodes.NodeNG) -> bool:
return (
node is None
- or (isinstance(node, astroid.Const) and node.value is None)
- or (isinstance(node, astroid.Name) and node.name == "None")
+ or (isinstance(node, nodes.Const) and node.value is None)
+ or (isinstance(node, nodes.Name) and node.name == "None")
)
-def node_type(node: astroid.node_classes.NodeNG) -> Optional[type]:
+def node_type(node: nodes.NodeNG) -> Optional[type]:
"""Return the inferred type for `node`
If there is more than one possible type, or if inferred type is Uninferable or None,
@@ -1263,7 +1254,7 @@ def node_type(node: astroid.node_classes.NodeNG) -> Optional[type]:
return types.pop() if types else None
-def is_registered_in_singledispatch_function(node: astroid.FunctionDef) -> bool:
+def is_registered_in_singledispatch_function(node: nodes.FunctionDef) -> bool:
"""Check if the given function node is a singledispatch function."""
singledispatch_qnames = (
@@ -1271,17 +1262,17 @@ def is_registered_in_singledispatch_function(node: astroid.FunctionDef) -> bool:
"singledispatch.singledispatch",
)
- if not isinstance(node, astroid.FunctionDef):
+ if not isinstance(node, nodes.FunctionDef):
return False
decorators = node.decorators.nodes if node.decorators else []
for decorator in decorators:
# func.register are function calls
- if not isinstance(decorator, astroid.Call):
+ if not isinstance(decorator, nodes.Call):
continue
func = decorator.func
- if not isinstance(func, astroid.Attribute) or func.attrname != "register":
+ if not isinstance(func, nodes.Attribute) or func.attrname != "register":
continue
try:
@@ -1289,14 +1280,14 @@ def is_registered_in_singledispatch_function(node: astroid.FunctionDef) -> bool:
except astroid.InferenceError:
continue
- if isinstance(func_def, astroid.FunctionDef):
+ if isinstance(func_def, nodes.FunctionDef):
# pylint: disable=redundant-keyword-arg; some flow inference goes wrong here
return decorated_with(func_def, singledispatch_qnames)
return False
-def get_node_last_lineno(node: astroid.node_classes.NodeNG) -> int:
+def get_node_last_lineno(node: nodes.NodeNG) -> int:
"""
Get the last lineno of the given node. For a simple statement this will just be node.lineno,
but for a node that has child statements (e.g. a method) this will be the lineno of the last
@@ -1319,14 +1310,14 @@ def get_node_last_lineno(node: astroid.node_classes.NodeNG) -> int:
return node.lineno
-def is_postponed_evaluation_enabled(node: astroid.node_classes.NodeNG) -> bool:
+def is_postponed_evaluation_enabled(node: nodes.NodeNG) -> bool:
"""Check if the postponed evaluation of annotations is enabled"""
module = node.root()
return "annotations" in module.future_imports
def is_class_subscriptable_pep585_with_postponed_evaluation_enabled(
- value: astroid.ClassDef, node: astroid.node_classes.NodeNG
+ value: nodes.ClassDef, node: nodes.NodeNG
) -> bool:
"""Check if class is subscriptable with PEP 585 and
postponed evaluation enabled.
@@ -1338,7 +1329,7 @@ def is_class_subscriptable_pep585_with_postponed_evaluation_enabled(
)
-def is_node_in_type_annotation_context(node: astroid.node_classes.NodeNG) -> bool:
+def is_node_in_type_annotation_context(node: nodes.NodeNG) -> bool:
"""Check if node is in type annotation context.
Check for 'AnnAssign', function 'Arguments',
@@ -1348,9 +1339,9 @@ def is_node_in_type_annotation_context(node: astroid.node_classes.NodeNG) -> boo
current_node, parent_node = node, node.parent
while True:
if (
- isinstance(parent_node, astroid.AnnAssign)
+ isinstance(parent_node, nodes.AnnAssign)
and parent_node.annotation == current_node
- or isinstance(parent_node, astroid.Arguments)
+ or isinstance(parent_node, nodes.Arguments)
and current_node
in (
*parent_node.annotations,
@@ -1359,23 +1350,23 @@ def is_node_in_type_annotation_context(node: astroid.node_classes.NodeNG) -> boo
parent_node.varargannotation,
parent_node.kwargannotation,
)
- or isinstance(parent_node, astroid.FunctionDef)
+ or isinstance(parent_node, nodes.FunctionDef)
and parent_node.returns == current_node
):
return True
current_node, parent_node = parent_node, parent_node.parent
- if isinstance(parent_node, astroid.Module):
+ if isinstance(parent_node, nodes.Module):
return False
-def is_subclass_of(child: astroid.ClassDef, parent: astroid.ClassDef) -> bool:
+def is_subclass_of(child: nodes.ClassDef, parent: nodes.ClassDef) -> bool:
"""
Check if first node is a subclass of second node.
:param child: Node to check for subclass.
:param parent: Node to check for superclass.
:returns: True if child is derived from parent. False otherwise.
"""
- if not all(isinstance(node, astroid.ClassDef) for node in (child, parent)):
+ if not all(isinstance(node, nodes.ClassDef) for node in (child, parent)):
return False
for ancestor in child.ancestors():
@@ -1388,7 +1379,7 @@ def is_subclass_of(child: astroid.ClassDef, parent: astroid.ClassDef) -> bool:
@lru_cache(maxsize=1024)
-def is_overload_stub(node: astroid.node_classes.NodeNG) -> bool:
+def is_overload_stub(node: nodes.NodeNG) -> bool:
"""Check if a node if is a function stub decorated with typing.overload.
:param node: Node to check.
@@ -1398,13 +1389,13 @@ def is_overload_stub(node: astroid.node_classes.NodeNG) -> bool:
return bool(decorators and decorated_with(node, ["typing.overload", "overload"]))
-def is_protocol_class(cls: astroid.node_classes.NodeNG) -> bool:
+def is_protocol_class(cls: nodes.NodeNG) -> bool:
"""Check if the given node represents a protocol class
:param cls: The node to check
:returns: True if the node is a typing protocol class, false otherwise.
"""
- if not isinstance(cls, astroid.ClassDef):
+ if not isinstance(cls, nodes.ClassDef):
return False
# Use .ancestors() since not all protocol classes can have
@@ -1412,40 +1403,40 @@ def is_protocol_class(cls: astroid.node_classes.NodeNG) -> bool:
return any(parent.qname() in TYPING_PROTOCOLS for parent in cls.ancestors())
-def is_call_of_name(node: astroid.node_classes.NodeNG, name: str) -> bool:
+def is_call_of_name(node: nodes.NodeNG, name: str) -> bool:
"""Checks if node is a function call with the given name"""
return (
- isinstance(node, astroid.Call)
- and isinstance(node.func, astroid.Name)
+ isinstance(node, nodes.Call)
+ and isinstance(node.func, nodes.Name)
and node.func.name == name
)
def is_test_condition(
- node: astroid.node_classes.NodeNG,
- parent: Optional[astroid.node_classes.NodeNG] = None,
+ node: nodes.NodeNG,
+ parent: Optional[nodes.NodeNG] = None,
) -> bool:
"""Returns true if the given node is being tested for truthiness"""
parent = parent or node.parent
- if isinstance(parent, (astroid.While, astroid.If, astroid.IfExp, astroid.Assert)):
+ if isinstance(parent, (nodes.While, nodes.If, nodes.IfExp, nodes.Assert)):
return node is parent.test or parent.test.parent_of(node)
- if isinstance(parent, astroid.Comprehension):
+ if isinstance(parent, nodes.Comprehension):
return node in parent.ifs
return is_call_of_name(parent, "bool") and parent.parent_of(node)
-def is_classdef_type(node: astroid.ClassDef) -> bool:
+def is_classdef_type(node: nodes.ClassDef) -> bool:
"""Test if ClassDef node is Type."""
if node.name == "type":
return True
for base in node.bases:
- if isinstance(base, astroid.Name) and base.name == "type":
+ if isinstance(base, nodes.Name) and base.name == "type":
return True
return False
def is_attribute_typed_annotation(
- node: Union[astroid.ClassDef, astroid.Instance], attr_name: str
+ node: Union[nodes.ClassDef, astroid.Instance], attr_name: str
) -> bool:
"""Test if attribute is typed annotation in current node
or any base nodes.
@@ -1453,36 +1444,36 @@ def is_attribute_typed_annotation(
attribute = node.locals.get(attr_name, [None])[0]
if (
attribute
- and isinstance(attribute, astroid.AssignName)
- and isinstance(attribute.parent, astroid.AnnAssign)
+ and isinstance(attribute, nodes.AssignName)
+ and isinstance(attribute.parent, nodes.AnnAssign)
):
return True
for base in node.bases:
inferred = safe_infer(base)
if (
inferred
- and isinstance(inferred, astroid.ClassDef)
+ and isinstance(inferred, nodes.ClassDef)
and is_attribute_typed_annotation(inferred, attr_name)
):
return True
return False
-def is_assign_name_annotated_with(node: astroid.AssignName, typing_name: str) -> bool:
+def is_assign_name_annotated_with(node: nodes.AssignName, typing_name: str) -> bool:
"""Test if AssignName node has `typing_name` annotation.
Especially useful to check for `typing._SpecialForm` instances
like: `Union`, `Optional`, `Literal`, `ClassVar`, `Final`.
"""
- if not isinstance(node.parent, astroid.AnnAssign):
+ if not isinstance(node.parent, nodes.AnnAssign):
return False
annotation = node.parent.annotation
- if isinstance(annotation, astroid.Subscript):
+ if isinstance(annotation, nodes.Subscript):
annotation = annotation.value
if (
- isinstance(annotation, astroid.Name)
+ isinstance(annotation, nodes.Name)
and annotation.name == typing_name
- or isinstance(annotation, astroid.Attribute)
+ or isinstance(annotation, nodes.Attribute)
and annotation.attrname == typing_name
):
return True
@@ -1490,18 +1481,18 @@ def is_assign_name_annotated_with(node: astroid.AssignName, typing_name: str) ->
def get_iterating_dictionary_name(
- node: Union[astroid.For, astroid.Comprehension]
+ node: Union[nodes.For, nodes.Comprehension]
) -> Optional[str]:
"""Get the name of the dictionary which keys are being iterated over on
- a `astroid.For` or `astroid.Comprehension` node.
+ a ``nodes.For`` or ``nodes.Comprehension`` node.
If the iterating object is not either the keys method of a dictionary
or a dictionary itself, this returns None.
"""
# Is it a proper keys call?
if (
- isinstance(node.iter, astroid.Call)
- and isinstance(node.iter.func, astroid.Attribute)
+ isinstance(node.iter, nodes.Call)
+ and isinstance(node.iter.func, nodes.Attribute)
and node.iter.func.attrname == "keys"
):
inferred = safe_infer(node.iter.func)
@@ -1510,16 +1501,16 @@ def get_iterating_dictionary_name(
return node.iter.as_string().rpartition(".keys")[0]
# Is it a dictionary?
- if isinstance(node.iter, (astroid.Name, astroid.Attribute)):
+ if isinstance(node.iter, (nodes.Name, nodes.Attribute)):
inferred = safe_infer(node.iter)
- if not isinstance(inferred, astroid.Dict):
+ if not isinstance(inferred, nodes.Dict):
return None
return node.iter.as_string()
return None
-def get_subscript_const_value(node: astroid.Subscript) -> astroid.Const:
+def get_subscript_const_value(node: nodes.Subscript) -> nodes.Const:
"""
Returns the value 'subscript.slice' of a Subscript node.
@@ -1528,16 +1519,14 @@ def get_subscript_const_value(node: astroid.Subscript) -> astroid.Const:
:raises InferredTypeError: if the subscript node cannot be inferred as a Const
"""
inferred = safe_infer(node.slice)
- if not isinstance(inferred, astroid.Const):
- raise InferredTypeError(
- "Subscript.slice cannot be inferred as an astroid.Const"
- )
+ if not isinstance(inferred, nodes.Const):
+ raise InferredTypeError("Subscript.slice cannot be inferred as a nodes.Const")
return inferred
def get_import_name(
- importnode: Union[astroid.Import, astroid.ImportFrom], modname: str
+ importnode: Union[nodes.Import, nodes.ImportFrom], modname: str
) -> str:
"""Get a prepared module name from the given import node
@@ -1551,9 +1540,9 @@ def get_import_name(
:returns: absolute qualified module name of the module
used in import.
"""
- if isinstance(importnode, astroid.ImportFrom) and importnode.level:
+ if isinstance(importnode, nodes.ImportFrom) and importnode.level:
root = importnode.root()
- if isinstance(root, astroid.Module):
+ if isinstance(root, nodes.Module):
try:
return root.relative_to_absolute_name(modname, level=importnode.level)
except TooManyLevelsError:
@@ -1561,10 +1550,10 @@ def get_import_name(
return modname
-def is_node_in_guarded_import_block(node: astroid.NodeNG) -> bool:
+def is_node_in_guarded_import_block(node: nodes.NodeNG) -> bool:
"""Return True if node is part for guarded if block.
I.e. `sys.version_info` or `typing.TYPE_CHECKING`
"""
- return isinstance(node.parent, astroid.If) and (
+ return isinstance(node.parent, nodes.If) and (
node.parent.is_sys_guard() or node.parent.is_typing_guard()
)
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 89d98067b..b51fd5ce5 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -59,6 +59,7 @@ import re
from functools import lru_cache
import astroid
+from astroid import nodes
from pylint.checkers import BaseChecker, utils
from pylint.checkers.utils import is_postponed_evaluation_enabled
@@ -144,14 +145,14 @@ def _is_from_future_import(stmt, name):
return None
for local_node in module.locals.get(name, []):
- if isinstance(local_node, astroid.ImportFrom) and local_node.modname == FUTURE:
+ if isinstance(local_node, nodes.ImportFrom) and local_node.modname == FUTURE:
return True
return None
def in_for_else_branch(parent, stmt):
"""Returns True if stmt in inside the else branch for a parent For stmt."""
- return isinstance(parent, astroid.For) and any(
+ return isinstance(parent, nodes.For) and any(
else_stmt.parent_of(stmt) or else_stmt == stmt for else_stmt in parent.orelse
)
@@ -169,7 +170,7 @@ def overridden_method(klass, name):
# We have found an ancestor defining <name> but it's not in the local
# dictionary. This may happen with astroid built from living objects.
return None
- if isinstance(meth_node, astroid.FunctionDef):
+ if isinstance(meth_node, nodes.FunctionDef):
return meth_node
return None
@@ -212,17 +213,17 @@ def _detect_global_scope(node, frame, defframe):
scope = frame.parent.scope()
if defframe and defframe.parent:
def_scope = defframe.parent.scope()
- if isinstance(frame, astroid.FunctionDef):
+ if isinstance(frame, nodes.FunctionDef):
# If the parent of the current node is a
# function, then it can be under its scope
# (defined in, which doesn't concern us) or
# the `->` part of annotations. The same goes
# for annotations of function arguments, they'll have
# their parent the Arguments node.
- if not isinstance(node.parent, (astroid.FunctionDef, astroid.Arguments)):
+ if not isinstance(node.parent, (nodes.FunctionDef, nodes.Arguments)):
return False
elif any(
- not isinstance(f, (astroid.ClassDef, astroid.Module)) for f in (frame, defframe)
+ not isinstance(f, (nodes.ClassDef, nodes.Module)) for f in (frame, defframe)
):
# Not interested in other frames, since they are already
# not in a global scope.
@@ -235,7 +236,7 @@ def _detect_global_scope(node, frame, defframe):
# share a global scope.
parent_scope = current_scope
while parent_scope:
- if not isinstance(parent_scope, (astroid.ClassDef, astroid.Module)):
+ if not isinstance(parent_scope, (nodes.ClassDef, nodes.Module)):
break_scopes.append(parent_scope)
break
if parent_scope.parent:
@@ -270,13 +271,13 @@ def _fix_dot_imports(not_consumed):
names = {}
for name, stmts in not_consumed.items():
if any(
- isinstance(stmt, astroid.AssignName)
- and isinstance(stmt.assign_type(), astroid.AugAssign)
+ isinstance(stmt, nodes.AssignName)
+ and isinstance(stmt.assign_type(), nodes.AugAssign)
for stmt in stmts
):
continue
for stmt in stmts:
- if not isinstance(stmt, (astroid.ImportFrom, astroid.Import)):
+ if not isinstance(stmt, (nodes.ImportFrom, nodes.Import)):
continue
for imports in stmt.names:
second_name = None
@@ -309,7 +310,7 @@ def _find_frame_imports(name, frame):
*name*. Such imports can be considered assignments.
Returns True if an import for the given name was found.
"""
- imports = frame.nodes_of_class((astroid.Import, astroid.ImportFrom))
+ imports = frame.nodes_of_class((nodes.Import, nodes.ImportFrom))
for import_node in imports:
for import_name, import_alias in import_node.names:
# If the import uses an alias, check only that.
@@ -343,13 +344,13 @@ def _assigned_locally(name_node):
"""
Checks if name_node has corresponding assign statement in same scope
"""
- assign_stmts = name_node.scope().nodes_of_class(astroid.AssignName)
+ assign_stmts = name_node.scope().nodes_of_class(nodes.AssignName)
return any(a.name == name_node.name for a in assign_stmts)
def _is_type_checking_import(node):
parent = node.parent
- if not isinstance(parent, astroid.If):
+ if not isinstance(parent, nodes.If):
return False
test = parent.test
return test.as_string() in TYPING_TYPE_CHECKS_GUARDS
@@ -357,12 +358,12 @@ def _is_type_checking_import(node):
def _has_locals_call_after_node(stmt, scope):
skip_nodes = (
- astroid.FunctionDef,
- astroid.ClassDef,
- astroid.Import,
- astroid.ImportFrom,
+ nodes.FunctionDef,
+ nodes.ClassDef,
+ nodes.Import,
+ nodes.ImportFrom,
)
- for call in scope.nodes_of_class(astroid.Call, skip_klass=skip_nodes):
+ for call in scope.nodes_of_class(nodes.Call, skip_klass=skip_nodes):
inferred = utils.safe_infer(call.func)
if (
utils.is_builtin_object(inferred)
@@ -569,7 +570,7 @@ scope_type : {self._atomic.scope_type}
found_nodes = self.to_consume.get(name)
if (
found_nodes
- and isinstance(parent_node, astroid.Assign)
+ and isinstance(parent_node, nodes.Assign)
and parent_node == found_nodes[0].parent
):
lhs = found_nodes[0].parent.targets[0]
@@ -578,7 +579,7 @@ scope_type : {self._atomic.scope_type}
if (
found_nodes
- and isinstance(parent_node, astroid.For)
+ and isinstance(parent_node, nodes.For)
and parent_node.iter == node
and parent_node.target in found_nodes
):
@@ -589,7 +590,7 @@ scope_type : {self._atomic.scope_type}
found_nodes = [
n
for n in found_nodes
- if not isinstance(n.statement(), astroid.ExceptHandler)
+ if not isinstance(n.statement(), nodes.ExceptHandler)
or n.statement().parent_of(node)
]
@@ -713,9 +714,7 @@ class VariablesChecker(BaseChecker):
@utils.check_messages("redefined-outer-name")
def visit_for(self, node):
- assigned_to = [
- var.name for var in node.target.nodes_of_class(astroid.AssignName)
- ]
+ assigned_to = [a.name for a in node.target.nodes_of_class(nodes.AssignName)]
# Only check variables that are used
dummy_rgx = self.config.dummy_variables_rgx
@@ -836,10 +835,10 @@ class VariablesChecker(BaseChecker):
return
globs = node.root().globals
for name, stmt in node.items():
- if name in globs and not isinstance(stmt, astroid.Global):
+ if name in globs and not isinstance(stmt, nodes.Global):
definition = globs[name][0]
if (
- isinstance(definition, astroid.ImportFrom)
+ isinstance(definition, nodes.ImportFrom)
and definition.modname == FUTURE
):
# It is a __future__ directive, not a symbol.
@@ -848,7 +847,7 @@ class VariablesChecker(BaseChecker):
# Do not take in account redefined names for the purpose
# of type checking.:
if any(
- isinstance(definition.parent, astroid.If)
+ isinstance(definition.parent, nodes.If)
and definition.parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS
for definition in globs[name]
):
@@ -895,8 +894,8 @@ class VariablesChecker(BaseChecker):
if is_method and node.is_abstract():
return
- global_names = _flattened_scope_names(node.nodes_of_class(astroid.Global))
- nonlocal_names = _flattened_scope_names(node.nodes_of_class(astroid.Nonlocal))
+ global_names = _flattened_scope_names(node.nodes_of_class(nodes.Global))
+ nonlocal_names = _flattened_scope_names(node.nodes_of_class(nodes.Nonlocal))
for name, stmts in not_consumed.items():
self._check_is_unused(name, node, stmts[0], global_names, nonlocal_names)
@@ -913,7 +912,7 @@ class VariablesChecker(BaseChecker):
def visit_global(self, node):
"""check names imported exists in the global scope"""
frame = node.frame()
- if isinstance(frame, astroid.Module):
+ if isinstance(frame, nodes.Module):
self.add_message("global-at-module-level", node=node)
return
@@ -928,8 +927,7 @@ class VariablesChecker(BaseChecker):
assign_nodes = []
not_defined_locally_by_import = not any(
- isinstance(local, astroid.node_classes.Import)
- for local in locals_.get(name, ())
+ isinstance(local, nodes.Import) for local in locals_.get(name, ())
)
if not assign_nodes and not_defined_locally_by_import:
self.add_message("global-variable-not-assigned", args=name, node=node)
@@ -938,7 +936,7 @@ class VariablesChecker(BaseChecker):
for anode in assign_nodes:
if (
- isinstance(anode, astroid.AssignName)
+ isinstance(anode, nodes.AssignName)
and anode.name in module.special_attributes
):
self.add_message("redefined-builtin", args=name, node=node)
@@ -956,7 +954,7 @@ class VariablesChecker(BaseChecker):
self.add_message("global-statement", node=node)
def visit_assignname(self, node):
- if isinstance(node.assign_type(), astroid.AugAssign):
+ if isinstance(node.assign_type(), nodes.AugAssign):
self.visit_name(node)
def visit_delname(self, node):
@@ -1003,8 +1001,8 @@ class VariablesChecker(BaseChecker):
# Ignore inner class scope for keywords in class definition
if (
current_consumer.scope_type == "class"
- and isinstance(node.parent, astroid.Keyword)
- and isinstance(node.parent.parent, astroid.ClassDef)
+ and isinstance(node.parent, nodes.Keyword)
+ and isinstance(node.parent.parent, nodes.ClassDef)
):
continue
@@ -1061,7 +1059,7 @@ class VariablesChecker(BaseChecker):
recursive_klass = (
frame is defframe
and defframe.parent_of(node)
- and isinstance(defframe, astroid.ClassDef)
+ and isinstance(defframe, nodes.ClassDef)
and node.name == defframe.name
)
@@ -1119,13 +1117,13 @@ class VariablesChecker(BaseChecker):
# Used and defined in the same place, e.g `x += 1` and `del x`
defined_by_stmt = defstmt is stmt and isinstance(
- node, (astroid.DelName, astroid.AssignName)
+ node, (nodes.DelName, nodes.AssignName)
)
if (
recursive_klass
or defined_by_stmt
or annotation_return
- or isinstance(defstmt, astroid.Delete)
+ or isinstance(defstmt, nodes.Delete)
):
if not utils.node_ignores_exception(node, NameError):
@@ -1135,9 +1133,9 @@ class VariablesChecker(BaseChecker):
and isinstance(
stmt,
(
- astroid.AnnAssign,
- astroid.FunctionDef,
- astroid.Arguments,
+ nodes.AnnAssign,
+ nodes.FunctionDef,
+ nodes.Arguments,
),
)
and name in node.root().locals
@@ -1151,9 +1149,7 @@ class VariablesChecker(BaseChecker):
# Handle postponed evaluation of annotations
if not (
self._postponed_evaluation_enabled
- and isinstance(
- stmt, (astroid.AnnAssign, astroid.FunctionDef)
- )
+ and isinstance(stmt, (nodes.AnnAssign, nodes.FunctionDef))
):
self.add_message(
"used-before-assignment", args=name, node=node
@@ -1164,8 +1160,8 @@ class VariablesChecker(BaseChecker):
# class A:
# x = lambda attr: f + attr
# f = 42
- if isinstance(frame, astroid.ClassDef) and name in frame.locals:
- if isinstance(node.parent, astroid.Arguments):
+ if isinstance(frame, nodes.ClassDef) and name in frame.locals:
+ if isinstance(node.parent, nodes.Arguments):
if stmt.fromlineno <= defstmt.fromlineno:
# Doing the following is fine:
# class A:
@@ -1189,12 +1185,12 @@ class VariablesChecker(BaseChecker):
# 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 astroid.Module.scope_attrs
+ name in nodes.Module.scope_attrs
or utils.is_builtin(name)
or name in self.config.additional_builtins
or (
name == "__class__"
- and isinstance(frame, astroid.FunctionDef)
+ and isinstance(frame, nodes.FunctionDef)
and frame.is_method()
)
):
@@ -1202,7 +1198,7 @@ class VariablesChecker(BaseChecker):
self.add_message("undefined-variable", args=name, node=node)
@utils.check_messages("no-name-in-module")
- def visit_import(self, node: astroid.Import) -> None:
+ def visit_import(self, node: nodes.Import) -> None:
"""check modules attribute accesses"""
if not self._analyse_fallback_blocks and utils.is_from_fallback_block(node):
# No need to verify this, since ImportError is already
@@ -1219,12 +1215,12 @@ class VariablesChecker(BaseChecker):
module = next(_infer_name_module(node, parts[0]))
except astroid.ResolveError:
continue
- if not isinstance(module, astroid.Module):
+ if not isinstance(module, nodes.Module):
continue
self._check_module_attrs(node, module, parts[1:])
@utils.check_messages("no-name-in-module")
- def visit_importfrom(self, node: astroid.ImportFrom) -> None:
+ def visit_importfrom(self, node: nodes.ImportFrom) -> None:
"""check modules attribute accesses"""
if not self._analyse_fallback_blocks and utils.is_from_fallback_block(node):
# No need to verify this, since ImportError is already
@@ -1257,7 +1253,7 @@ class VariablesChecker(BaseChecker):
get assigned.
"""
self._check_self_cls_assign(node)
- if not isinstance(node.targets[0], (astroid.Tuple, astroid.List)):
+ if not isinstance(node.targets[0], (nodes.Tuple, nodes.List)):
return
targets = node.targets[0].itered()
@@ -1304,7 +1300,7 @@ class VariablesChecker(BaseChecker):
@staticmethod
def _defined_in_function_definition(node, frame):
in_annotation_or_default_or_decorator = False
- if isinstance(frame, astroid.FunctionDef) and node.statement() is frame:
+ if isinstance(frame, nodes.FunctionDef) and node.statement() is frame:
in_annotation_or_default_or_decorator = (
(
node in frame.args.annotations
@@ -1324,7 +1320,7 @@ class VariablesChecker(BaseChecker):
@staticmethod
def _in_lambda_or_comprehension_body(
- node: astroid.node_classes.NodeNG, frame: astroid.node_classes.NodeNG
+ node: nodes.NodeNG, frame: nodes.NodeNG
) -> bool:
"""return True if node within a lambda/comprehension body (or similar) and thus should not have access to class attributes in frame"""
child = node
@@ -1332,16 +1328,13 @@ class VariablesChecker(BaseChecker):
while parent is not None:
if parent is frame:
return False
- if isinstance(parent, astroid.Lambda) and child is not parent.args:
+ if isinstance(parent, nodes.Lambda) and child is not parent.args:
# Body of lambda should not have access to class attributes.
return True
- if (
- isinstance(parent, astroid.node_classes.Comprehension)
- and child is not parent.iter
- ):
+ if isinstance(parent, nodes.Comprehension) and child is not parent.iter:
# Only iter of list/set/dict/generator comprehension should have access.
return True
- if isinstance(parent, astroid.scoped_nodes.ComprehensionScope) and not (
+ if isinstance(parent, nodes.ComprehensionScope) and not (
parent.generators and child is parent.generators[0]
):
# Body of list/set/dict/generator comprehension should not have access to class attributes.
@@ -1385,24 +1378,24 @@ class VariablesChecker(BaseChecker):
# Note: the node.frame() is not the same as the `frame` argument which is
# equivalent to frame.statement().scope()
forbid_lookup = (
- isinstance(frame, astroid.FunctionDef)
- or isinstance(node.frame(), astroid.Lambda)
+ isinstance(frame, nodes.FunctionDef)
+ or isinstance(node.frame(), nodes.Lambda)
) and _assigned_locally(node)
if not forbid_lookup and defframe.root().lookup(name)[1]:
maybee0601 = False
use_outer_definition = stmt == defstmt and not isinstance(
- defnode, astroid.node_classes.Comprehension
+ defnode, nodes.Comprehension
)
# check if we have a nonlocal
elif name in defframe.locals:
maybee0601 = not any(
- isinstance(child, astroid.Nonlocal) and name in child.names
+ isinstance(child, nodes.Nonlocal) and name in child.names
for child in defframe.get_children()
)
if (
base_scope_type == "lambda"
- and isinstance(frame, astroid.ClassDef)
+ and isinstance(frame, nodes.ClassDef)
and name in frame.locals
):
@@ -1418,12 +1411,12 @@ class VariablesChecker(BaseChecker):
# In this case, maybee0601 should be False, otherwise
# it should be True.
maybee0601 = not (
- isinstance(defnode, astroid.Arguments)
+ isinstance(defnode, nodes.Arguments)
and node in defnode.defaults
and frame.locals[name][0].fromlineno < defstmt.fromlineno
)
- elif isinstance(defframe, astroid.ClassDef) and isinstance(
- frame, astroid.FunctionDef
+ elif isinstance(defframe, nodes.ClassDef) and isinstance(
+ frame, nodes.FunctionDef
):
# Special rule for function return annotations,
# which uses the same name as the class where
@@ -1440,7 +1433,7 @@ class VariablesChecker(BaseChecker):
# name as the class. In this case, no warning
# should be raised.
maybee0601 = False
- if isinstance(node.parent, astroid.Arguments):
+ if isinstance(node.parent, nodes.Arguments):
maybee0601 = stmt.fromlineno <= defstmt.fromlineno
elif recursive_klass:
maybee0601 = True
@@ -1448,7 +1441,7 @@ class VariablesChecker(BaseChecker):
maybee0601 = maybee0601 and stmt.fromlineno <= defstmt.fromlineno
if maybee0601 and stmt.fromlineno == defstmt.fromlineno:
if (
- isinstance(defframe, astroid.FunctionDef)
+ isinstance(defframe, nodes.FunctionDef)
and frame is defframe
and defframe.parent_of(node)
and stmt is not defstmt
@@ -1460,14 +1453,14 @@ class VariablesChecker(BaseChecker):
isinstance(
defstmt,
(
- astroid.Assign,
- astroid.AnnAssign,
- astroid.AugAssign,
- astroid.Expr,
- astroid.Return,
+ nodes.Assign,
+ nodes.AnnAssign,
+ nodes.AugAssign,
+ nodes.Expr,
+ nodes.Return,
),
)
- and isinstance(defstmt.value, astroid.IfExp)
+ and isinstance(defstmt.value, nodes.IfExp)
and frame is defframe
and defframe.parent_of(node)
and stmt is defstmt
@@ -1478,7 +1471,7 @@ class VariablesChecker(BaseChecker):
maybee0601 = False
elif (
isinstance( # pylint: disable=too-many-boolean-expressions
- defnode, astroid.NamedExpr
+ defnode, nodes.NamedExpr
)
and frame is defframe
and defframe.parent_of(stmt)
@@ -1498,13 +1491,13 @@ class VariablesChecker(BaseChecker):
and isinstance(
defstmt,
(
- astroid.Assign,
- astroid.AnnAssign,
- astroid.AugAssign,
- astroid.Return,
+ nodes.Assign,
+ nodes.AnnAssign,
+ nodes.AugAssign,
+ nodes.Return,
),
)
- and isinstance(defstmt.value, astroid.JoinedStr)
+ and isinstance(defstmt.value, nodes.JoinedStr)
)
)
):
@@ -1514,11 +1507,11 @@ class VariablesChecker(BaseChecker):
maybee0601 = False
# Look for type checking definitions inside a type checking guard.
- if isinstance(defstmt, (astroid.Import, astroid.ImportFrom)):
+ if isinstance(defstmt, (nodes.Import, nodes.ImportFrom)):
defstmt_parent = defstmt.parent
if (
- isinstance(defstmt_parent, astroid.If)
+ isinstance(defstmt_parent, nodes.If)
and defstmt_parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS
):
# Exempt those definitions that are used inside the type checking
@@ -1527,7 +1520,7 @@ class VariablesChecker(BaseChecker):
defined_in_or_else = False
for definition in defstmt_parent.orelse:
- if isinstance(definition, astroid.Assign):
+ if isinstance(definition, nodes.Assign):
defined_in_or_else = any(
target.name == name for target in definition.targets
)
@@ -1580,10 +1573,7 @@ class VariablesChecker(BaseChecker):
else:
frame_locals = frame.locals
return not (
- (
- isinstance(frame, astroid.ClassDef)
- or in_annotation_or_default_or_decorator
- )
+ (isinstance(frame, nodes.ClassDef) or in_annotation_or_default_or_decorator)
and not self._in_lambda_or_comprehension_body(node, frame)
and name in frame_locals
)
@@ -1598,7 +1588,7 @@ class VariablesChecker(BaseChecker):
# the usage is safe because the function will not be defined either if
# the variable is not defined.
scope = node.scope()
- if isinstance(scope, astroid.FunctionDef) and any(
+ if isinstance(scope, nodes.FunctionDef) and any(
asmt.statement().parent_of(scope) for asmt in astmts
):
return
@@ -1630,15 +1620,13 @@ class VariablesChecker(BaseChecker):
assign = astmts[0].assign_type()
if not (
- isinstance(
- assign, (astroid.For, astroid.Comprehension, astroid.GeneratorExp)
- )
+ isinstance(assign, (nodes.For, nodes.Comprehension, nodes.GeneratorExp))
and assign.statement() is not node.statement()
):
return
# For functions we can do more by inferring the length of the itered object
- if not isinstance(assign, astroid.For):
+ if not isinstance(assign, nodes.For):
self.add_message("undefined-loop-variable", args=name, node=node)
return
@@ -1656,10 +1644,10 @@ class VariablesChecker(BaseChecker):
# Consider sequences.
sequences = (
- astroid.List,
- astroid.Tuple,
- astroid.Dict,
- astroid.Set,
+ nodes.List,
+ nodes.Tuple,
+ nodes.Dict,
+ nodes.Set,
astroid.objects.FrozenSet,
)
if not isinstance(inferred, sequences):
@@ -1677,15 +1665,15 @@ class VariablesChecker(BaseChecker):
return
# Ignore names that were added dynamically to the Function scope
if (
- isinstance(node, astroid.FunctionDef)
+ isinstance(node, nodes.FunctionDef)
and name == "__class__"
and len(node.locals["__class__"]) == 1
- and isinstance(node.locals["__class__"][0], astroid.ClassDef)
+ and isinstance(node.locals["__class__"][0], nodes.ClassDef)
):
return
# Ignore names imported by the global statement.
- if isinstance(stmt, (astroid.Global, astroid.Import, astroid.ImportFrom)):
+ if isinstance(stmt, (nodes.Global, nodes.Import, nodes.ImportFrom)):
# Detect imports, assigned to global statements.
if global_names and _import_name_is_global(stmt, global_names):
return
@@ -1697,14 +1685,12 @@ class VariablesChecker(BaseChecker):
if name in argnames:
self._check_unused_arguments(name, node, stmt, argnames)
else:
- if stmt.parent and isinstance(
- stmt.parent, (astroid.Assign, astroid.AnnAssign)
- ):
+ if stmt.parent and isinstance(stmt.parent, (nodes.Assign, nodes.AnnAssign)):
if name in nonlocal_names:
return
qname = asname = None
- if isinstance(stmt, (astroid.Import, astroid.ImportFrom)):
+ if isinstance(stmt, (nodes.Import, nodes.ImportFrom)):
# Need the complete name, which we don't have in .locals.
if len(stmt.names) > 1:
import_names = next(
@@ -1719,14 +1705,14 @@ class VariablesChecker(BaseChecker):
if _has_locals_call_after_node(stmt, node.scope()):
message_name = "possibly-unused-variable"
else:
- if isinstance(stmt, astroid.Import):
+ if isinstance(stmt, nodes.Import):
if asname is not None:
msg = f"{qname} imported as {asname}"
else:
msg = "import %s" % name
self.add_message("unused-import", args=msg, node=stmt)
return
- if isinstance(stmt, astroid.ImportFrom):
+ if isinstance(stmt, nodes.ImportFrom):
if asname is not None:
msg = f"{qname} imported from {stmt.modname} as {asname}"
else:
@@ -1735,7 +1721,7 @@ class VariablesChecker(BaseChecker):
return
message_name = "unused-variable"
- if isinstance(stmt, astroid.FunctionDef) and stmt.decorators:
+ if isinstance(stmt, nodes.FunctionDef) and stmt.decorators:
return
# Don't check function stubs created only for type information
@@ -1743,8 +1729,8 @@ class VariablesChecker(BaseChecker):
return
# Special case for exception variable
- if isinstance(stmt.parent, astroid.ExceptHandler) and any(
- n.name == name for n in stmt.parent.nodes_of_class(astroid.Name)
+ if isinstance(stmt.parent, nodes.ExceptHandler) and any(
+ n.name == name for n in stmt.parent.nodes_of_class(nodes.Name)
):
return
@@ -1753,9 +1739,9 @@ class VariablesChecker(BaseChecker):
def _is_name_ignored(self, stmt, name):
authorized_rgx = self.config.dummy_variables_rgx
if (
- isinstance(stmt, astroid.AssignName)
- and isinstance(stmt.parent, astroid.Arguments)
- or isinstance(stmt, astroid.Arguments)
+ isinstance(stmt, nodes.AssignName)
+ and isinstance(stmt.parent, nodes.Arguments)
+ or isinstance(stmt, nodes.Arguments)
):
regex = self.config.ignored_argument_names
else:
@@ -1765,7 +1751,7 @@ class VariablesChecker(BaseChecker):
def _check_unused_arguments(self, name, node, stmt, argnames):
is_method = node.is_method()
klass = node.parent.frame()
- if is_method and isinstance(klass, astroid.ClassDef):
+ if is_method and isinstance(klass, nodes.ClassDef):
confidence = (
INFERENCE if utils.has_known_bases(klass) else INFERENCE_FAILURE
)
@@ -1805,7 +1791,7 @@ class VariablesChecker(BaseChecker):
self.add_message("unused-argument", args=name, node=stmt, confidence=confidence)
- def _check_late_binding_closure(self, node: astroid.Name) -> None:
+ def _check_late_binding_closure(self, node: nodes.Name) -> None:
"""Check whether node is a cell var that is assigned within a containing loop.
Special cases where we don't care about the error:
@@ -1824,7 +1810,7 @@ class VariablesChecker(BaseChecker):
# Check if node is a cell var
if (
- not isinstance(node_scope, (astroid.Lambda, astroid.FunctionDef))
+ not isinstance(node_scope, (nodes.Lambda, nodes.FunctionDef))
or node.name in node_scope.locals
):
return
@@ -1841,7 +1827,7 @@ class VariablesChecker(BaseChecker):
assignment_node = stmts[0]
maybe_for = assignment_node
- while maybe_for and not isinstance(maybe_for, astroid.For):
+ while maybe_for and not isinstance(maybe_for, nodes.For):
if maybe_for is assign_scope:
break
maybe_for = maybe_for.parent
@@ -1850,12 +1836,12 @@ 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(), astroid.Return)
+ and not isinstance(node_scope.statement(), nodes.Return)
):
self.add_message("cell-var-from-loop", node=node, args=node.name)
def _should_ignore_redefined_builtin(self, stmt):
- if not isinstance(stmt, astroid.ImportFrom):
+ if not isinstance(stmt, nodes.ImportFrom):
return False
return stmt.modname in self.config.redefining_builtins_modules
@@ -1882,28 +1868,27 @@ class VariablesChecker(BaseChecker):
def _store_type_annotation_node(self, type_annotation):
"""Given a type annotation, store all the name nodes it refers to"""
- if isinstance(type_annotation, astroid.Name):
+ if isinstance(type_annotation, nodes.Name):
self._type_annotation_names.append(type_annotation.name)
return
- if isinstance(type_annotation, astroid.Attribute):
+ if isinstance(type_annotation, nodes.Attribute):
self._store_type_annotation_node(type_annotation.expr)
return
- if not isinstance(type_annotation, astroid.Subscript):
+ if not isinstance(type_annotation, nodes.Subscript):
return
if (
- isinstance(type_annotation.value, astroid.Attribute)
- and isinstance(type_annotation.value.expr, astroid.Name)
+ isinstance(type_annotation.value, nodes.Attribute)
+ and isinstance(type_annotation.value.expr, nodes.Name)
and type_annotation.value.expr.name == TYPING_MODULE
):
self._type_annotation_names.append(TYPING_MODULE)
return
self._type_annotation_names.extend(
- annotation.name
- for annotation in type_annotation.nodes_of_class(astroid.Name)
+ annotation.name for annotation in type_annotation.nodes_of_class(nodes.Name)
)
def _store_type_annotation_names(self, node):
@@ -1917,19 +1902,19 @@ class VariablesChecker(BaseChecker):
assign_names = {
target.name
for target in node.targets
- if isinstance(target, astroid.AssignName)
+ if isinstance(target, nodes.AssignName)
}
scope = node.scope()
nonlocals_with_same_name = any(
child
for child in scope.body
- if isinstance(child, astroid.Nonlocal) and assign_names & set(child.names)
+ if isinstance(child, nodes.Nonlocal) and assign_names & set(child.names)
)
if nonlocals_with_same_name:
scope = node.scope().parent.scope()
if not (
- isinstance(scope, astroid.scoped_nodes.FunctionDef)
+ isinstance(scope, nodes.FunctionDef)
and scope.is_method()
and "builtins.staticmethod" not in scope.decoratornames()
):
@@ -1941,7 +1926,7 @@ class VariablesChecker(BaseChecker):
target_assign_names = (
target.name
for target in node.targets
- if isinstance(target, astroid.node_classes.AssignName)
+ if isinstance(target, nodes.AssignName)
)
if self_cls_name in target_assign_names:
self.add_message("self-cls-assignment", node=node, args=(self_cls_name,))
@@ -1957,18 +1942,18 @@ class VariablesChecker(BaseChecker):
if inferred is astroid.Uninferable:
return
if (
- isinstance(inferred.parent, astroid.Arguments)
- and isinstance(node.value, astroid.Name)
+ isinstance(inferred.parent, nodes.Arguments)
+ and isinstance(node.value, nodes.Name)
and node.value.name == inferred.parent.vararg
):
# Variable-length argument, we can't determine the length.
return
- if isinstance(inferred, (astroid.Tuple, astroid.List)):
+ if isinstance(inferred, (nodes.Tuple, nodes.List)):
# attempt to check unpacking is properly balanced
values = inferred.itered()
if len(targets) != len(values):
# Check if we have starred nodes.
- if any(isinstance(target, astroid.Starred) for target in targets):
+ if any(isinstance(target, nodes.Starred) for target in targets):
return
self.add_message(
"unbalanced-tuple-unpacking",
@@ -2016,7 +2001,7 @@ class VariablesChecker(BaseChecker):
"no-name-in-module", node=node, args=(".".join(module_names), modname)
)
return None
- if isinstance(module, astroid.Module):
+ if isinstance(module, nodes.Module):
return module
return None
@@ -2025,7 +2010,7 @@ class VariablesChecker(BaseChecker):
if assigned is astroid.Uninferable:
return
- if not isinstance(assigned, (astroid.Tuple, astroid.List, list, tuple)):
+ if not isinstance(assigned, (nodes.Tuple, nodes.List, list, tuple)):
self.add_message("invalid-all-format", node=assigned)
return
@@ -2039,7 +2024,7 @@ class VariablesChecker(BaseChecker):
if not elt_name.parent:
continue
- if not isinstance(elt_name, astroid.Const) or not isinstance(
+ if not isinstance(elt_name, nodes.Const) or not isinstance(
elt_name.value, str
):
self.add_message("invalid-all-object", args=elt.as_string(), node=elt)
@@ -2075,8 +2060,8 @@ class VariablesChecker(BaseChecker):
def _check_globals(self, not_consumed):
if self._allow_global_unused_variables:
return
- for name, nodes in not_consumed.items():
- for node in nodes:
+ for name, node_lst in not_consumed.items():
+ for node in node_lst:
self.add_message("unused-variable", args=(name,), node=node)
def _check_imports(self, not_consumed):
@@ -2098,10 +2083,10 @@ class VariablesChecker(BaseChecker):
imported_name in self._type_annotation_names
or as_name in self._type_annotation_names
)
- if isinstance(stmt, astroid.Import) or (
- isinstance(stmt, astroid.ImportFrom) and not stmt.modname
+ if isinstance(stmt, nodes.Import) or (
+ isinstance(stmt, nodes.ImportFrom) and not stmt.modname
):
- if isinstance(stmt, astroid.ImportFrom) and SPECIAL_OBJ.search(
+ if isinstance(stmt, nodes.ImportFrom) and SPECIAL_OBJ.search(
imported_name
):
# Filter special objects (__doc__, __all__) etc.,
@@ -2120,7 +2105,7 @@ class VariablesChecker(BaseChecker):
msg = f"{imported_name} imported as {as_name}"
if not _is_type_checking_import(stmt):
self.add_message("unused-import", args=msg, node=stmt)
- elif isinstance(stmt, astroid.ImportFrom) and stmt.modname != FUTURE:
+ elif isinstance(stmt, nodes.ImportFrom) and stmt.modname != FUTURE:
if SPECIAL_OBJ.search(imported_name):
# Filter special objects (__doc__, __all__) etc.,
# because they can be imported for exporting.
@@ -2152,7 +2137,7 @@ class VariablesChecker(BaseChecker):
consumed = [] # [(scope_locals, consumed_key)]
for child_node in node.get_children():
- if isinstance(child_node, astroid.ClassDef):
+ if isinstance(child_node, nodes.ClassDef):
consumed.extend(self._check_classdef_metaclasses(child_node, node))
# Pop the consumed items, in order to avoid having
@@ -2168,11 +2153,11 @@ class VariablesChecker(BaseChecker):
consumed = [] # [(scope_locals, consumed_key)]
metaclass = klass.metaclass()
name = None
- if isinstance(klass._metaclass, astroid.Name):
+ if isinstance(klass._metaclass, nodes.Name):
name = klass._metaclass.name
- elif isinstance(klass._metaclass, astroid.Attribute) and klass._metaclass.expr:
+ elif isinstance(klass._metaclass, nodes.Attribute) and klass._metaclass.expr:
attr = klass._metaclass.expr
- while not isinstance(attr, astroid.Name):
+ while not isinstance(attr, nodes.Name):
attr = attr.expr
name = attr.name
elif metaclass:
@@ -2191,7 +2176,7 @@ class VariablesChecker(BaseChecker):
found is None
and not metaclass
and not (
- name in astroid.Module.scope_attrs
+ name in nodes.Module.scope_attrs
or utils.is_builtin(name)
or name in self.config.additional_builtins
or name in parent_node.locals
diff --git a/pylint/extensions/_check_docs_utils.py b/pylint/extensions/_check_docs_utils.py
index db615edbd..d41988414 100644
--- a/pylint/extensions/_check_docs_utils.py
+++ b/pylint/extensions/_check_docs_utils.py
@@ -25,6 +25,7 @@ import re
from typing import List
import astroid
+from astroid import nodes
from pylint.checkers import utils
@@ -53,9 +54,9 @@ def get_setters_property_name(node):
decorators = node.decorators.nodes if node.decorators else []
for decorator in decorators:
if (
- isinstance(decorator, astroid.Attribute)
+ isinstance(decorator, nodes.Attribute)
and decorator.attrname == "setter"
- and isinstance(decorator.expr, astroid.Name)
+ and isinstance(decorator.expr, nodes.Name)
):
return decorator.expr.name
return None
@@ -65,9 +66,9 @@ def get_setters_property(node):
"""Get the property node for the given setter node.
:param node: The node to get the property for.
- :type node: astroid.FunctionDef
+ :type node: nodes.FunctionDef
- :rtype: astroid.FunctionDef or None
+ :rtype: nodes.FunctionDef or None
:returns: The node relating to the property of the given setter node,
or None if one could not be found.
"""
@@ -100,13 +101,13 @@ def returns_something(return_node):
if returns is None:
return False
- return not (isinstance(returns, astroid.Const) and returns.value is None)
+ return not (isinstance(returns, nodes.Const) and returns.value is None)
def _get_raise_target(node):
- if isinstance(node.exc, astroid.Call):
+ if isinstance(node.exc, nodes.Call):
func = node.exc.func
- if isinstance(func, (astroid.Name, astroid.Attribute)):
+ if isinstance(func, (nodes.Name, nodes.Attribute)):
return utils.safe_infer(func)
return None
@@ -126,19 +127,19 @@ def possible_exc_types(node):
:param node: The raise node to find exception types for.
- :type node: astroid.node_classes.NodeNG
+ :type node: nodes.NodeNG
:returns: A list of exception types possibly raised by :param:`node`.
:rtype: set(str)
"""
excs = []
- if isinstance(node.exc, astroid.Name):
+ if isinstance(node.exc, nodes.Name):
inferred = utils.safe_infer(node.exc)
if inferred:
excs = [inferred.name]
elif node.exc is None:
handler = node.parent
- while handler and not isinstance(handler, astroid.ExceptHandler):
+ while handler and not isinstance(handler, nodes.ExceptHandler):
handler = handler.parent
if handler and handler.type:
@@ -146,10 +147,10 @@ def possible_exc_types(node):
excs = (exc.name for exc in inferred_excs if exc is not astroid.Uninferable)
else:
target = _get_raise_target(node)
- if isinstance(target, astroid.ClassDef):
+ if isinstance(target, nodes.ClassDef):
excs = [target.name]
- elif isinstance(target, astroid.FunctionDef):
- for ret in target.nodes_of_class(astroid.Return):
+ elif isinstance(target, nodes.FunctionDef):
+ for ret in target.nodes_of_class(nodes.Return):
if ret.frame() != target:
# return from inner function - ignore it
continue
@@ -157,7 +158,7 @@ def possible_exc_types(node):
val = utils.safe_infer(ret.value)
if (
val
- and isinstance(val, (astroid.Instance, astroid.ClassDef))
+ and isinstance(val, (astroid.Instance, nodes.ClassDef))
and utils.inherit_from_std_ex(val)
):
excs.append(val.name)