diff options
author | Marc Mueller <30130371+cdce8p@users.noreply.github.com> | 2021-08-17 22:19:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-17 22:19:04 +0200 |
commit | 6e2dbbf4630c97c2fa7dc36dcb29c7501221acd6 (patch) | |
tree | 4fbb8b6d843e095a34f89c40b993d50c6a61c2c3 /pylint | |
parent | ef72cdc6f9b96ea680d6a9d0f37861f80d6bc3db (diff) | |
download | pylint-git-6e2dbbf4630c97c2fa7dc36dcb29c7501221acd6.tar.gz |
Use alias for astroid.nodes 01 (#4855)
* Use from astroid import nodes
* Resolve name conflicts
Diffstat (limited to 'pylint')
-rw-r--r-- | pylint/checkers/async.py | 7 | ||||
-rw-r--r-- | pylint/checkers/base.py | 281 | ||||
-rw-r--r-- | pylint/checkers/classes.py | 229 | ||||
-rw-r--r-- | pylint/checkers/deprecated.py | 19 |
4 files changed, 267 insertions, 269 deletions
diff --git a/pylint/checkers/async.py b/pylint/checkers/async.py index 1f3771f0a..a6831b394 100644 --- a/pylint/checkers/async.py +++ b/pylint/checkers/async.py @@ -12,6 +12,7 @@ import sys import astroid +from astroid import nodes from pylint import checkers, interfaces, utils from pylint.checkers import utils as checker_utils @@ -46,9 +47,9 @@ class AsyncChecker(checkers.BaseChecker): @checker_utils.check_messages("yield-inside-async-function") def visit_asyncfunctiondef(self, node): - for child in node.nodes_of_class(astroid.Yield): + for child in node.nodes_of_class(nodes.Yield): if child.scope() is node and ( - sys.version_info[:2] == (3, 5) or isinstance(child, astroid.YieldFrom) + sys.version_info[:2] == (3, 5) or isinstance(child, nodes.YieldFrom) ): self.add_message("yield-inside-async-function", node=child) @@ -59,7 +60,7 @@ class AsyncChecker(checkers.BaseChecker): if inferred is None or inferred is astroid.Uninferable: continue - if isinstance(inferred, astroid.AsyncFunctionDef): + if isinstance(inferred, nodes.AsyncFunctionDef): # Check if we are dealing with a function decorated # with contextlib.asynccontextmanager. if decorated_with(inferred, self._async_generators): diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py index 9c8d49096..7d080ffd5 100644 --- a/pylint/checkers/base.py +++ b/pylint/checkers/base.py @@ -69,6 +69,7 @@ import sys from typing import Pattern import astroid +from astroid import nodes from pylint import checkers, exceptions, interfaces from pylint import utils as lint_utils @@ -176,7 +177,7 @@ REVERSED_PROTOCOL_METHOD = "__reversed__" SEQUENCE_PROTOCOL_METHODS = ("__getitem__", "__len__") REVERSED_METHODS = (SEQUENCE_PROTOCOL_METHODS, (REVERSED_PROTOCOL_METHOD,)) TYPECHECK_COMPARISON_OPERATORS = frozenset(("is", "is not", "==", "!=")) -LITERAL_NODE_TYPES = (astroid.Const, astroid.Dict, astroid.List, astroid.Set) +LITERAL_NODE_TYPES = (nodes.Const, nodes.Dict, nodes.List, nodes.Set) UNITTEST_CASE = "unittest.case" TYPE_QNAME = "%s.type" % BUILTINS ABC_METACLASSES = {"_py_abc.ABCMeta", "abc.ABCMeta"} # Python 3.7+, @@ -217,12 +218,12 @@ def _redefines_import(node): Returns True if the node redefines an import, False otherwise. """ current = node - while current and not isinstance(current.parent, astroid.ExceptHandler): + while current and not isinstance(current.parent, nodes.ExceptHandler): current = current.parent if not current or not utils.error_of_type(current.parent, ImportError): return False try_block = current.parent.parent - for import_node in try_block.nodes_of_class((astroid.ImportFrom, astroid.Import)): + for import_node in try_block.nodes_of_class((nodes.ImportFrom, nodes.Import)): for name, alias in import_node.names: if alias: if alias == node.name: @@ -239,11 +240,11 @@ def in_loop(node): if isinstance( parent, ( - astroid.For, - astroid.ListComp, - astroid.SetComp, - astroid.DictComp, - astroid.GeneratorExp, + nodes.For, + nodes.ListComp, + nodes.SetComp, + nodes.DictComp, + nodes.GeneratorExp, ), ): return True @@ -274,7 +275,7 @@ def _get_break_loop_node(break_node): Returns: astroid.For or astroid.While: the loop node holding the break node. """ - loop_nodes = (astroid.For, astroid.While) + loop_nodes = (nodes.For, nodes.While) parent = break_node.parent while not isinstance(parent, loop_nodes) or break_node in getattr( parent, "orelse", [] @@ -296,8 +297,8 @@ def _loop_exits_early(loop): Returns: bool: True if the loop may ends up in a break statement, False otherwise. """ - loop_nodes = (astroid.For, astroid.While) - definition_nodes = (astroid.FunctionDef, astroid.ClassDef) + loop_nodes = (nodes.For, nodes.While) + definition_nodes = (nodes.FunctionDef, nodes.ClassDef) inner_loop_nodes = [ _node for _node in loop.nodes_of_class(loop_nodes, skip_klass=definition_nodes) @@ -305,7 +306,7 @@ def _loop_exits_early(loop): ] return any( _node - for _node in loop.nodes_of_class(astroid.Break, skip_klass=definition_nodes) + for _node in loop.nodes_of_class(nodes.Break, skip_klass=definition_nodes) if _get_break_loop_node(_node) not in inner_loop_nodes ) @@ -338,7 +339,7 @@ def _get_properties(config): return property_classes, property_names -def _determine_function_name_type(node: astroid.FunctionDef, config=None): +def _determine_function_name_type(node: nodes.FunctionDef, config=None): """Determine the name type whose regex the a function's name should match. :param node: A function node. @@ -364,8 +365,8 @@ def _determine_function_name_type(node: astroid.FunctionDef, config=None): for decorator in decorators: # If the function is a property (decorated with @property # or @abc.abstractproperty), the name type is 'attr'. - if isinstance(decorator, astroid.Name) or ( - isinstance(decorator, astroid.Attribute) + if isinstance(decorator, nodes.Name) or ( + isinstance(decorator, nodes.Attribute) and decorator.attrname in property_names ): inferred = utils.safe_infer(decorator) @@ -445,7 +446,7 @@ def redefined_by_decorator(node): if node.decorators: for decorator in node.decorators.nodes: if ( - isinstance(decorator, astroid.Attribute) + isinstance(decorator, nodes.Attribute) and getattr(decorator.expr, "name", None) == node.name ): return True @@ -573,9 +574,9 @@ class BasicErrorChecker(_BasicChecker): def _too_many_starred_for_tuple(self, assign_tuple): starred_count = 0 for elem in assign_tuple.itered(): - if isinstance(elem, astroid.Tuple): + if isinstance(elem, nodes.Tuple): return self._too_many_starred_for_tuple(elem) - if isinstance(elem, astroid.Starred): + if isinstance(elem, nodes.Starred): starred_count += 1 return starred_count > 1 @@ -584,10 +585,10 @@ class BasicErrorChecker(_BasicChecker): # Check *a, *b = ... assign_target = node.targets[0] # Check *a = b - if isinstance(node.targets[0], astroid.Starred): + if isinstance(node.targets[0], nodes.Starred): self.add_message("invalid-star-assignment-target", node=node) - if not isinstance(assign_target, astroid.Tuple): + if not isinstance(assign_target, nodes.Tuple): return if self._too_many_starred_for_tuple(assign_target): self.add_message("too-many-star-expressions", node=node) @@ -595,18 +596,16 @@ class BasicErrorChecker(_BasicChecker): @utils.check_messages("star-needs-assignment-target") def visit_starred(self, node): """Check that a Starred expression is used in an assignment target.""" - if isinstance(node.parent, astroid.Call): + if isinstance(node.parent, nodes.Call): # f(*args) is converted to Call(args=[Starred]), so ignore # them for this check. return - if isinstance( - node.parent, (astroid.List, astroid.Tuple, astroid.Set, astroid.Dict) - ): + if isinstance(node.parent, (nodes.List, nodes.Tuple, nodes.Set, nodes.Dict)): # PEP 448 unpacking. return stmt = node.statement() - if not isinstance(stmt, astroid.Assign): + if not isinstance(stmt, nodes.Assign): return if stmt.value is node or stmt.value.parent_of(node): @@ -630,7 +629,7 @@ class BasicErrorChecker(_BasicChecker): self._check_redefinition(node.is_method() and "method" or "function", node) # checks for max returns, branch, return in __init__ returns = node.nodes_of_class( - astroid.Return, skip_klass=(astroid.FunctionDef, astroid.ClassDef) + nodes.Return, skip_klass=(nodes.FunctionDef, nodes.ClassDef) ) if node.is_method() and node.name == "__init__": if node.is_generator(): @@ -664,7 +663,7 @@ class BasicErrorChecker(_BasicChecker): scope_globals = { name: child - for child in node.nodes_of_class(astroid.Global) + for child in node.nodes_of_class(nodes.Global) for name in child.names if child.scope() is node } @@ -672,7 +671,7 @@ class BasicErrorChecker(_BasicChecker): if not scope_globals: return - for node_name in node.nodes_of_class(astroid.Name): + for node_name in node.nodes_of_class(nodes.Name): if node_name.scope() is not node: continue @@ -697,7 +696,7 @@ class BasicErrorChecker(_BasicChecker): nonlocals = set( from_iter( child.names - for child in node.nodes_of_class(astroid.Nonlocal) + for child in node.nodes_of_class(nodes.Nonlocal) if same_scope(child) ) ) @@ -708,7 +707,7 @@ class BasicErrorChecker(_BasicChecker): global_vars = set( from_iter( child.names - for child in node.nodes_of_class(astroid.Global) + for child in node.nodes_of_class(nodes.Global) if same_scope(child) ) ) @@ -717,7 +716,7 @@ class BasicErrorChecker(_BasicChecker): @utils.check_messages("return-outside-function") def visit_return(self, node): - if not isinstance(node.frame(), astroid.FunctionDef): + if not isinstance(node.frame(), nodes.FunctionDef): self.add_message("return-outside-function", node=node) @utils.check_messages("yield-outside-function") @@ -749,7 +748,7 @@ class BasicErrorChecker(_BasicChecker): """check use of the non-existent ++ and -- operator operator""" if ( (node.op in "+-") - and isinstance(node.operand, astroid.UnaryOp) + and isinstance(node.operand, nodes.UnaryOp) and (node.operand.op == node.op) ): self.add_message("nonexistent-operator", node=node, args=node.op * 2) @@ -760,7 +759,7 @@ class BasicErrorChecker(_BasicChecker): if current_scope.parent is None: break - if not isinstance(current_scope, (astroid.ClassDef, astroid.FunctionDef)): + if not isinstance(current_scope, (nodes.ClassDef, nodes.FunctionDef)): self.add_message("nonlocal-without-binding", args=(name,), node=node) return @@ -771,7 +770,7 @@ class BasicErrorChecker(_BasicChecker): # Okay, found it. return - if not isinstance(current_scope, astroid.FunctionDef): + if not isinstance(current_scope, nodes.FunctionDef): self.add_message("nonlocal-without-binding", args=(name,), node=node) @utils.check_messages("nonlocal-without-binding") @@ -791,7 +790,7 @@ class BasicErrorChecker(_BasicChecker): return def _check_inferred_class_is_abstract(self, inferred, node): - if not isinstance(inferred, astroid.ClassDef): + if not isinstance(inferred, nodes.ClassDef): return klass = utils.node_frame_class(node) @@ -828,7 +827,7 @@ class BasicErrorChecker(_BasicChecker): ) def _check_yield_outside_func(self, node): - if not isinstance(node.frame(), (astroid.FunctionDef, astroid.Lambda)): + if not isinstance(node.frame(), (nodes.FunctionDef, nodes.Lambda)): self.add_message("yield-outside-function", node=node) def _check_else_on_loop(self, node): @@ -847,16 +846,16 @@ class BasicErrorChecker(_BasicChecker): """check that a node is inside a for or while loop""" _node = node.parent while _node: - if isinstance(_node, (astroid.For, astroid.While)): + if isinstance(_node, (nodes.For, nodes.While)): if node not in _node.orelse: return - if isinstance(_node, (astroid.ClassDef, astroid.FunctionDef)): + if isinstance(_node, (nodes.ClassDef, nodes.FunctionDef)): break if ( - isinstance(_node, astroid.TryFinally) + isinstance(_node, nodes.TryFinally) and node in _node.finalbody - and isinstance(node, astroid.Continue) + and isinstance(node, nodes.Continue) ): self.add_message("continue-in-finally", node=node) @@ -878,7 +877,7 @@ class BasicErrorChecker(_BasicChecker): # Additional checks for methods which are not considered # redefined, since they are already part of the base API. if ( - isinstance(parent_frame, astroid.ClassDef) + isinstance(parent_frame, nodes.ClassDef) and node.name in REDEFINABLE_METHODS ): return @@ -888,12 +887,12 @@ class BasicErrorChecker(_BasicChecker): return # Exempt functions redefined on a condition. - if isinstance(node.parent, astroid.If): + if isinstance(node.parent, nodes.If): # Exempt "if not <func>" cases if ( - isinstance(node.parent.test, astroid.UnaryOp) + isinstance(node.parent.test, nodes.UnaryOp) and node.parent.test.op == "not" - and isinstance(node.parent.test.operand, astroid.Name) + and isinstance(node.parent.test.operand, nodes.Name) and node.parent.test.operand.name == node.name ): return @@ -901,11 +900,11 @@ class BasicErrorChecker(_BasicChecker): # Exempt "if <func> is not None" cases # pylint: disable=too-many-boolean-expressions if ( - isinstance(node.parent.test, astroid.Compare) - and isinstance(node.parent.test.left, astroid.Name) + isinstance(node.parent.test, nodes.Compare) + and isinstance(node.parent.test.left, nodes.Name) and node.parent.test.left.name == node.name and node.parent.test.ops[0][0] == "is" - and isinstance(node.parent.test.ops[0][1], astroid.Const) + and isinstance(node.parent.test.ops[0][1], nodes.Const) and node.parent.test.ops[0][1].value is None ): return @@ -1109,29 +1108,29 @@ class BasicChecker(_BasicChecker): def _check_using_constant_test(self, node, test): const_nodes = ( - astroid.Module, - astroid.scoped_nodes.GeneratorExp, - astroid.Lambda, - astroid.FunctionDef, - astroid.ClassDef, + nodes.Module, + nodes.GeneratorExp, + nodes.Lambda, + nodes.FunctionDef, + nodes.ClassDef, astroid.bases.Generator, astroid.UnboundMethod, astroid.BoundMethod, - astroid.Module, + nodes.Module, ) - structs = (astroid.Dict, astroid.Tuple, astroid.Set, astroid.List) + structs = (nodes.Dict, nodes.Tuple, nodes.Set, nodes.List) # These nodes are excepted, since they are not constant # values, requiring a computation to happen. except_nodes = ( - astroid.Call, - astroid.BinOp, - astroid.BoolOp, - astroid.UnaryOp, - astroid.Subscript, + nodes.Call, + nodes.BinOp, + nodes.BoolOp, + nodes.UnaryOp, + nodes.Subscript, ) inferred = None - emit = isinstance(test, (astroid.Const,) + structs + const_nodes) + emit = isinstance(test, (nodes.Const,) + structs + const_nodes) if not isinstance(test, except_nodes): inferred = utils.safe_infer(test) @@ -1142,9 +1141,9 @@ class BasicChecker(_BasicChecker): # it may be a illicit function call due to missing parentheses call_inferred = None try: - if isinstance(inferred, astroid.FunctionDef): + if isinstance(inferred, nodes.FunctionDef): call_inferred = inferred.infer_call_result() - elif isinstance(inferred, astroid.Lambda): + elif isinstance(inferred, nodes.Lambda): call_inferred = inferred.infer_call_result(node) except astroid.InferenceError: call_inferred = None @@ -1176,23 +1175,21 @@ class BasicChecker(_BasicChecker): def visit_expr(self, node): """Check for various kind of statements without effect""" expr = node.value - if isinstance(expr, astroid.Const) and isinstance(expr.value, str): + if isinstance(expr, nodes.Const) and isinstance(expr.value, str): # treat string statement in a separated message # Handle PEP-257 attribute docstrings. # An attribute docstring is defined as being a string right after # an assignment at the module level, class level or __init__ level. scope = expr.scope() - if isinstance( - scope, (astroid.ClassDef, astroid.Module, astroid.FunctionDef) - ): - if isinstance(scope, astroid.FunctionDef) and scope.name != "__init__": + if isinstance(scope, (nodes.ClassDef, nodes.Module, nodes.FunctionDef)): + if isinstance(scope, nodes.FunctionDef) and scope.name != "__init__": pass else: sibling = expr.previous_sibling() if ( sibling is not None and sibling.scope() is scope - and isinstance(sibling, (astroid.Assign, astroid.AnnAssign)) + and isinstance(sibling, (nodes.Assign, nodes.AnnAssign)) ): return self.add_message("pointless-string-statement", node=node) @@ -1206,15 +1203,12 @@ class BasicChecker(_BasicChecker): # warn W0106 if we have any underlying function call (we can't predict # side effects), else pointless-statement if ( - isinstance(expr, (astroid.Yield, astroid.Await, astroid.Call)) - or ( - isinstance(node.parent, astroid.TryExcept) - and node.parent.body == [node] - ) - or (isinstance(expr, astroid.Const) and expr.value is Ellipsis) + isinstance(expr, (nodes.Yield, nodes.Await, nodes.Call)) + or (isinstance(node.parent, nodes.TryExcept) and node.parent.body == [node]) + or (isinstance(expr, nodes.Const) and expr.value is Ellipsis) ): return - if any(expr.nodes_of_class(astroid.Call)): + if any(expr.nodes_of_class(nodes.Call)): self.add_message( "expression-not-assigned", node=node, args=expr.as_string() ) @@ -1226,9 +1220,9 @@ class BasicChecker(_BasicChecker): # Return the arguments for the given call which are # not passed as vararg. for arg in call_args: - if isinstance(arg, astroid.Starred): + if isinstance(arg, nodes.Starred): if ( - isinstance(arg.value, astroid.Name) + isinstance(arg.value, nodes.Name) and arg.value.name != node.args.vararg ): yield arg @@ -1240,7 +1234,7 @@ class BasicChecker(_BasicChecker): if not args: return True for arg in args: - if isinstance(arg.value, astroid.Name): + if isinstance(arg.value, nodes.Name): if arg.value.name != variadic_name: return True else: @@ -1261,12 +1255,12 @@ class BasicChecker(_BasicChecker): # of the lambda. return call = node.body - if not isinstance(call, astroid.Call): + if not isinstance(call, nodes.Call): # The body of the lambda must be a function call expression # for the lambda to be unnecessary. return - if isinstance(node.body.func, astroid.Attribute) and isinstance( - node.body.func.expr, astroid.Call + if isinstance(node.body.func, nodes.Attribute) and isinstance( + node.body.func.expr, nodes.Call ): # Chained call, the intermediate call might # return something else (but we don't check that, yet). @@ -1300,7 +1294,7 @@ class BasicChecker(_BasicChecker): if len(ordinary_args) != len(new_call_args): return for arg, passed_arg in zip(ordinary_args, new_call_args): - if not isinstance(passed_arg, astroid.Name): + if not isinstance(passed_arg, nodes.Name): return if arg.name != passed_arg.name: return @@ -1321,7 +1315,7 @@ class BasicChecker(_BasicChecker): """Check for dangerous default values as arguments.""" def is_iterable(internal_node): - return isinstance(internal_node, (astroid.List, astroid.Set, astroid.Dict)) + return isinstance(internal_node, (nodes.List, nodes.Set, nodes.Dict)) defaults = node.args.defaults or [] + node.args.kw_defaults or [] for default in defaults: @@ -1348,7 +1342,7 @@ class BasicChecker(_BasicChecker): # or a dict. if is_iterable(default): msg = value.pytype() - elif isinstance(default, astroid.Call): + elif isinstance(default, nodes.Call): msg = f"{value.name}() ({value.qname()})" else: msg = f"{default.as_string()} ({value.qname()})" @@ -1366,7 +1360,7 @@ class BasicChecker(_BasicChecker): """ self._check_unreachable(node) # Is it inside final body of a try...finally block ? - self._check_not_in_finally(node, "return", (astroid.FunctionDef,)) + self._check_not_in_finally(node, "return", (nodes.FunctionDef,)) @utils.check_messages("unreachable") def visit_continue(self, node): @@ -1385,7 +1379,7 @@ class BasicChecker(_BasicChecker): # 1 - Is it right sibling ? self._check_unreachable(node) # 2 - Is it inside final body of a try...finally block ? - self._check_not_in_finally(node, "break", (astroid.For, astroid.While)) + self._check_not_in_finally(node, "break", (nodes.For, nodes.While)) @utils.check_messages("unreachable") def visit_raise(self, node): @@ -1400,7 +1394,7 @@ class BasicChecker(_BasicChecker): self.add_message("exec-used", node=node) def _check_misplaced_format_function(self, call_node): - if not isinstance(call_node.func, astroid.Attribute): + if not isinstance(call_node.func, nodes.Attribute): return if call_node.func.attrname != "format": return @@ -1412,10 +1406,10 @@ class BasicChecker(_BasicChecker): # we are doubtful on inferred type of node, so here just check if format # was called on print() call_expr = call_node.func.expr - if not isinstance(call_expr, astroid.Call): + if not isinstance(call_expr, nodes.Call): return if ( - isinstance(call_expr.func, astroid.Name) + isinstance(call_expr.func, nodes.Name) and call_expr.func.name == "print" ): self.add_message("misplaced-format-function", node=call_node) @@ -1428,7 +1422,7 @@ class BasicChecker(_BasicChecker): call and check for * or ** use """ self._check_misplaced_format_function(node) - if isinstance(node.func, astroid.Name): + if isinstance(node.func, nodes.Name): name = node.func.name # ignore the name if it's not a builtin (i.e. not defined in the # locals nor globals scope) @@ -1445,12 +1439,12 @@ class BasicChecker(_BasicChecker): """check whether assert is used on a tuple or string literal.""" if ( node.fail is None - and isinstance(node.test, astroid.Tuple) + and isinstance(node.test, nodes.Tuple) and len(node.test.elts) == 2 ): self.add_message("assert-on-tuple", node=node) - if isinstance(node.test, astroid.Const) and isinstance(node.test.value, str): + if isinstance(node.test, nodes.Const) and isinstance(node.test.value, str): if node.test.value: when = "never" else: @@ -1462,7 +1456,7 @@ class BasicChecker(_BasicChecker): """check duplicate key in dictionary""" keys = set() for k, _ in node.items: - if isinstance(k, astroid.Const): + if isinstance(k, nodes.Const): key = k.value if key in keys: self.add_message("duplicate-key", node=node, args=key) @@ -1481,9 +1475,9 @@ class BasicChecker(_BasicChecker): unreach_stmt = node.next_sibling() if unreach_stmt is not None: if ( - isinstance(node, astroid.Return) - and isinstance(unreach_stmt, astroid.Expr) - and isinstance(unreach_stmt.value, astroid.Yield) + isinstance(node, nodes.Return) + and isinstance(unreach_stmt, nodes.Expr) + and isinstance(unreach_stmt.value, nodes.Yield) ): # Don't add 'unreachable' for empty generators. # Only add warning if 'yield' is followed by another node. @@ -1522,7 +1516,7 @@ class BasicChecker(_BasicChecker): if argument is None: # Nothing was inferred. # Try to see if we have iter(). - if isinstance(node.args[0], astroid.Call): + if isinstance(node.args[0], nodes.Call): try: func = next(node.args[0].func.infer()) except astroid.InferenceError: @@ -1533,7 +1527,7 @@ class BasicChecker(_BasicChecker): self.add_message("bad-reversed-sequence", node=node) return - if isinstance(argument, (astroid.List, astroid.Tuple)): + if isinstance(argument, (nodes.List, nodes.Tuple)): return if isinstance(argument, astroid.Instance): @@ -1573,8 +1567,8 @@ class BasicChecker(_BasicChecker): pairs = node.items if pairs: for prev_pair, pair in zip(pairs, pairs[1:]): - if isinstance(prev_pair[1], astroid.AssignName) and ( - pair[1] is None and not isinstance(pair[0], astroid.Call) + if isinstance(prev_pair[1], nodes.AssignName) and ( + pair[1] is None and not isinstance(pair[0], nodes.Call) ): # Don't emit a message if the second is a function call # there's no way that can be mistaken for a name assignment. @@ -1590,7 +1584,7 @@ class BasicChecker(_BasicChecker): rhs_names = [] targets = node.targets - if isinstance(targets[0], astroid.Tuple): + if isinstance(targets[0], nodes.Tuple): if len(targets) != 1: # A complex assignment, so bail out early. return @@ -1599,22 +1593,22 @@ class BasicChecker(_BasicChecker): # Unpacking a variable into the same name. return - if isinstance(node.value, astroid.Name): + if isinstance(node.value, nodes.Name): if len(targets) != 1: return rhs_names = [node.value] - elif isinstance(node.value, astroid.Tuple): + elif isinstance(node.value, nodes.Tuple): rhs_count = len(node.value.elts) if len(targets) != rhs_count or rhs_count == 1: return rhs_names = node.value.elts for target, lhs_name in zip(targets, rhs_names): - if not isinstance(lhs_name, astroid.Name): + if not isinstance(lhs_name, nodes.Name): continue - if not isinstance(target, astroid.AssignName): + if not isinstance(target, nodes.AssignName): continue - if isinstance(scope, astroid.ClassDef) and target.name in scope_locals: + if isinstance(scope, nodes.ClassDef) and target.name in scope_locals: # Check that the scope is different than a class level, which is usually # a pattern to expose module level attributes as class level ones. continue @@ -1629,14 +1623,14 @@ class BasicChecker(_BasicChecker): ) for target in targets: - if not isinstance(target, astroid.Tuple): + if not isinstance(target, nodes.Tuple): continue found_names = [] for element in target.elts: - if isinstance(element, astroid.Tuple): + if isinstance(element, nodes.Tuple): self._check_redeclared_assign_name([element]) - elif isinstance(element, astroid.AssignName) and element.name != "_": + elif isinstance(element, nodes.AssignName) and element.name != "_": if dummy_variables_rgx and dummy_variables_rgx.match(element.name): return found_names.append(element.name) @@ -1984,28 +1978,28 @@ class NameChecker(_BasicChecker): self._check_assign_to_new_keyword_violation(node.name, node) frame = node.frame() assign_type = node.assign_type() - if isinstance(assign_type, astroid.Comprehension): + if isinstance(assign_type, nodes.Comprehension): self._check_name("inlinevar", node.name, node) - elif isinstance(frame, astroid.Module): - if isinstance(assign_type, astroid.Assign): - if isinstance(utils.safe_infer(assign_type.value), astroid.ClassDef): + elif isinstance(frame, nodes.Module): + if isinstance(assign_type, nodes.Assign): + if isinstance(utils.safe_infer(assign_type.value), nodes.ClassDef): self._check_name("class", node.name, node) # Don't emit if the name redefines an import # in an ImportError except handler. elif not _redefines_import(node) and isinstance( - utils.safe_infer(assign_type.value), astroid.Const + utils.safe_infer(assign_type.value), nodes.Const ): self._check_name("const", node.name, node) elif isinstance( - assign_type, astroid.AnnAssign + assign_type, nodes.AnnAssign ) and utils.is_assign_name_annotated_with(node, "Final"): self._check_name("const", node.name, node) - elif isinstance(frame, astroid.FunctionDef): + elif isinstance(frame, nodes.FunctionDef): # global introduced variable aren't in the function locals if node.name in frame and node.name not in frame.argnames(): if not _redefines_import(node): self._check_name("variable", node.name, node) - elif isinstance(frame, astroid.ClassDef): + elif isinstance(frame, nodes.ClassDef): if not list(frame.local_attr_ancestors(node.name)): for ancestor in frame.ancestors(): if ( @@ -2021,7 +2015,7 @@ class NameChecker(_BasicChecker): def _recursive_check_names(self, args, node): """check names in a possibly recursive list <arg>""" for arg in args: - if isinstance(arg, astroid.AssignName): + if isinstance(arg, nodes.AssignName): self._check_name("argument", arg.name, node) else: self._recursive_check_names(arg.elts, node) @@ -2066,7 +2060,7 @@ class NameChecker(_BasicChecker): def _should_exempt_from_invalid_name(node): if node_type == "variable": inferred = utils.safe_infer(node) - if isinstance(inferred, astroid.ClassDef): + if isinstance(inferred, nodes.ClassDef): return True return False @@ -2194,7 +2188,7 @@ class DocStringChecker(_BasicChecker): ): return - if isinstance(node.parent.frame(), astroid.ClassDef): + if isinstance(node.parent.frame(), nodes.ClassDef): overridden = False confidence = ( interfaces.INFERENCE @@ -2204,14 +2198,14 @@ class DocStringChecker(_BasicChecker): # check if node is from a method overridden by its ancestor for ancestor in node.parent.frame().ancestors(): if node.name in ancestor and isinstance( - ancestor[node.name], astroid.FunctionDef + ancestor[node.name], nodes.FunctionDef ): overridden = True break self._check_docstring( ftype, node, report_missing=not overridden, confidence=confidence ) - elif isinstance(node.parent.frame(), astroid.Module): + elif isinstance(node.parent.frame(), nodes.Module): self._check_docstring(ftype, node) else: return @@ -2242,8 +2236,8 @@ class DocStringChecker(_BasicChecker): self.stats["undocumented_" + node_type] += 1 if ( node.body - and isinstance(node.body[0], astroid.Expr) - and isinstance(node.body[0].value, astroid.Call) + and isinstance(node.body[0], nodes.Expr) + and isinstance(node.body[0].value, nodes.Call) ): # Most likely a string with a format call. Let's see. func = utils.safe_infer(node.body[0].value.func) @@ -2281,7 +2275,7 @@ class PassChecker(_BasicChecker): @utils.check_messages("unnecessary-pass") def visit_pass(self, node): if len(node.parent.child_sequence(node)) > 1 or ( - isinstance(node.parent, (astroid.ClassDef, astroid.FunctionDef)) + isinstance(node.parent, (nodes.ClassDef, nodes.FunctionDef)) and (node.parent.doc is not None) ): self.add_message("unnecessary-pass", node=node) @@ -2291,7 +2285,7 @@ def _is_one_arg_pos_call(call): """Is this a call with exactly 1 argument, where that argument is positional? """ - return isinstance(call, astroid.Call) and len(call.args) == 1 and not call.keywords + return isinstance(call, nodes.Call) and len(call.args) == 1 and not call.keywords def _infer_dunder_doc_attribute(node): @@ -2304,7 +2298,7 @@ def _infer_dunder_doc_attribute(node): docstring = utils.safe_infer(docstring) if not docstring: return None - if not isinstance(docstring, astroid.Const): + if not isinstance(docstring, nodes.Const): return None return docstring.value @@ -2375,7 +2369,7 @@ class ComparisonChecker(_BasicChecker): singleton_values = (True, False, None) def _is_singleton_const(node) -> bool: - return isinstance(node, astroid.Const) and any( + return isinstance(node, nodes.Const) and any( node.value is value for value in singleton_values ) @@ -2431,7 +2425,7 @@ class ComparisonChecker(_BasicChecker): ): def _is_float_nan(node): try: - if isinstance(node, astroid.Call) and len(node.args) == 1: + if isinstance(node, nodes.Call) and len(node.args) == 1: if ( node.args[0].value.lower() == "nan" and node.inferred()[0].pytype() == "builtins.float" @@ -2442,8 +2436,8 @@ class ComparisonChecker(_BasicChecker): return False def _is_numpy_nan(node): - if isinstance(node, astroid.Attribute) and node.attrname == "NaN": - if isinstance(node.expr, astroid.Name): + if isinstance(node, nodes.Attribute) and node.attrname == "NaN": + if isinstance(node.expr, nodes.Name): return node.expr.name in ("numpy", "nmp", "np") return False @@ -2469,10 +2463,11 @@ class ComparisonChecker(_BasicChecker): def _check_literal_comparison(self, literal, node): """Check if we compare to a literal, which is usually what we do not want to do.""" - nodes = (astroid.List, astroid.Tuple, astroid.Dict, astroid.Set) - is_other_literal = isinstance(literal, nodes) + is_other_literal = isinstance( + literal, (nodes.List, nodes.Tuple, nodes.Dict, nodes.Set) + ) is_const = False - if isinstance(literal, astroid.Const): + if isinstance(literal, nodes.Const): if isinstance(literal.value, bool) or literal.value is None: # Not interested in this values. return @@ -2482,7 +2477,7 @@ class ComparisonChecker(_BasicChecker): self.add_message("literal-comparison", node=node) def _check_misplaced_constant(self, node, left, right, operator): - if isinstance(right, astroid.Const): + if isinstance(right, nodes.Const): return operator = REVERSED_COMPS.get(operator, operator) suggestion = f"{right.as_string()} {operator} {left.value!r}" @@ -2500,13 +2495,13 @@ class ComparisonChecker(_BasicChecker): left_operand = node.left right_operand = node.ops[0][1] operator = node.ops[0][0] - if isinstance(left_operand, astroid.Const) and isinstance( - right_operand, astroid.Const + if isinstance(left_operand, nodes.Const) and isinstance( + right_operand, nodes.Const ): left_operand = left_operand.value right_operand = right_operand.value - elif isinstance(left_operand, astroid.Name) and isinstance( - right_operand, astroid.Name + elif isinstance(left_operand, nodes.Name) and isinstance( + right_operand, nodes.Name ): left_operand = left_operand.name right_operand = right_operand.name @@ -2520,7 +2515,7 @@ class ComparisonChecker(_BasicChecker): if operator not in COMPARISON_OPERATORS: return - bare_callables = (astroid.FunctionDef, astroid.BoundMethod) + bare_callables = (nodes.FunctionDef, astroid.BoundMethod) left_operand, right_operand = node.left, node.ops[0][1] # this message should be emitted only when there is comparison of bare callable # with non bare callable. @@ -2553,7 +2548,7 @@ class ComparisonChecker(_BasicChecker): left = node.left operator, right = node.ops[0] - if operator in COMPARISON_OPERATORS and isinstance(left, astroid.Const): + if operator in COMPARISON_OPERATORS and isinstance(left, nodes.Const): self._check_misplaced_constant(node, left, right, operator) if operator in ("==", "!="): @@ -2579,14 +2574,14 @@ class ComparisonChecker(_BasicChecker): """Check for expressions like type(x) == Y.""" left_func = utils.safe_infer(left.func) if not ( - isinstance(left_func, astroid.ClassDef) and left_func.qname() == TYPE_QNAME + isinstance(left_func, nodes.ClassDef) and left_func.qname() == TYPE_QNAME ): return if operator in ("is", "is not") and _is_one_arg_pos_call(right): right_func = utils.safe_infer(right.func) if ( - isinstance(right_func, astroid.ClassDef) + isinstance(right_func, nodes.ClassDef) and right_func.qname() == TYPE_QNAME ): # type(x) == type(a) diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py index ec0312eba..3ecc738e5 100644 --- a/pylint/checkers/classes.py +++ b/pylint/checkers/classes.py @@ -50,6 +50,7 @@ from itertools import chain, zip_longest from typing import List, Pattern, cast import astroid +from astroid import nodes from pylint.checkers import BaseChecker from pylint.checkers.utils import ( @@ -99,21 +100,21 @@ def _signature_from_call(call): starred_args = [] for keyword in call.keywords or []: arg, value = keyword.arg, keyword.value - if arg is None and isinstance(value, astroid.Name): + if arg is None and isinstance(value, nodes.Name): # Starred node and we are interested only in names, # otherwise some transformation might occur for the parameter. starred_kws.append(value.name) - elif isinstance(value, astroid.Name): + elif isinstance(value, nodes.Name): kws[arg] = value.name else: kws[arg] = None for arg in call.args: - if isinstance(arg, astroid.Starred) and isinstance(arg.value, astroid.Name): + if isinstance(arg, nodes.Starred) and isinstance(arg.value, nodes.Name): # Positional variadic and a name, otherwise some transformation # might have occurred. starred_args.append(arg.value.name) - elif isinstance(arg, astroid.Name): + elif isinstance(arg, nodes.Name): args.append(arg.name) else: args.append(None) @@ -245,11 +246,11 @@ def _has_different_parameters_default_value(original, overridden): return True astroid_type_compared_attr = { - astroid.Const: "value", - astroid.ClassDef: "name", - astroid.Tuple: "elts", - astroid.List: "elts", - astroid.Dict: "items", + nodes.Const: "value", + nodes.ClassDef: "name", + nodes.Tuple: "elts", + nodes.List: "elts", + nodes.Dict: "items", } handled_types = tuple( astroid_type for astroid_type in astroid_type_compared_attr @@ -271,8 +272,8 @@ def _has_different_parameters_default_value(original, overridden): def _has_different_parameters( - original: List[astroid.AssignName], - overridden: List[astroid.AssignName], + original: List[nodes.AssignName], + overridden: List[nodes.AssignName], dummy_parameter_regex: Pattern, ) -> List[str]: result = [] @@ -296,8 +297,8 @@ def _has_different_parameters( def _different_parameters( - original: astroid.FunctionDef, - overridden: astroid.FunctionDef, + original: nodes.FunctionDef, + overridden: nodes.FunctionDef, dummy_parameter_regex: Pattern, ) -> List[str]: """Determine if the two methods have different parameters @@ -400,7 +401,7 @@ def _called_in_methods(func, klass, methods): """Check if the func was called in any of the given methods, belonging to the *klass*. Returns True if so, False otherwise. """ - if not isinstance(func, astroid.FunctionDef): + if not isinstance(func, nodes.FunctionDef): return False for method in methods: try: @@ -408,7 +409,7 @@ def _called_in_methods(func, klass, methods): except astroid.NotFoundError: continue for infer_method in inferred: - for call in infer_method.nodes_of_class(astroid.Call): + for call in infer_method.nodes_of_class(nodes.Call): try: bound = next(call.func.infer()) except (astroid.InferenceError, StopIteration): @@ -445,7 +446,7 @@ def _is_attribute_property(name, klass): inferred = next(attr.infer()) except astroid.InferenceError: continue - if isinstance(inferred, astroid.FunctionDef) and decorated_with_property( + if isinstance(inferred, nodes.FunctionDef) and decorated_with_property( inferred ): return True @@ -460,9 +461,9 @@ def _is_attribute_property(name, klass): def _has_bare_super_call(fundef_node): - for call in fundef_node.nodes_of_class(astroid.Call): + for call in fundef_node.nodes_of_class(nodes.Call): func = call.func - if isinstance(func, astroid.Name) and func.name == "super" and not call.args: + if isinstance(func, nodes.Name) and func.name == "super" and not call.args: return True return False @@ -492,7 +493,7 @@ def _safe_infer_call_result(node, caller, context=None): def _has_same_layout_slots(slots, assigned_value): inferred = next(assigned_value.infer()) - if isinstance(inferred, astroid.ClassDef): + if isinstance(inferred, nodes.ClassDef): other_slots = inferred.slots() if all( first_slot and second_slot and first_slot.value == second_slot.value @@ -883,7 +884,7 @@ a metaclass class method.", ): continue - if not isinstance(ancestor, astroid.ClassDef) or _is_invalid_base_class( + if not isinstance(ancestor, nodes.ClassDef) or _is_invalid_base_class( ancestor ): self.add_message("inherit-non-class", args=base.as_string(), node=node) @@ -894,7 +895,7 @@ a metaclass class method.", ) @check_messages("unused-private-member", "attribute-defined-outside-init") - def leave_classdef(self, node: astroid.ClassDef) -> None: + def leave_classdef(self, node: nodes.ClassDef) -> None: """close a class node: check that instance attributes are defined in __init__ and check access to existent members @@ -904,36 +905,36 @@ a metaclass class method.", self._check_unused_private_attributes(node) self._check_attribute_defined_outside_init(node) - def _check_unused_private_functions(self, node: astroid.ClassDef) -> None: - for function_def in node.nodes_of_class(astroid.FunctionDef): - function_def = cast(astroid.FunctionDef, function_def) + def _check_unused_private_functions(self, node: nodes.ClassDef) -> None: + for function_def in node.nodes_of_class(nodes.FunctionDef): + function_def = cast(nodes.FunctionDef, function_def) if not is_attr_private(function_def.name): continue parent_scope = function_def.parent.scope() - if isinstance(parent_scope, astroid.FunctionDef): + if isinstance(parent_scope, nodes.FunctionDef): # Handle nested functions if function_def.name in ( - n.name for n in parent_scope.nodes_of_class(astroid.Name) + n.name for n in parent_scope.nodes_of_class(nodes.Name) ): continue - for attribute in node.nodes_of_class(astroid.Attribute): - attribute = cast(astroid.Attribute, attribute) + for attribute in node.nodes_of_class(nodes.Attribute): + attribute = cast(nodes.Attribute, attribute) if ( attribute.attrname != function_def.name or attribute.scope() == function_def # We ignore recursive calls ): continue - if isinstance(attribute.expr, astroid.Name) and attribute.expr.name in ( + if isinstance(attribute.expr, nodes.Name) and attribute.expr.name in ( "self", node.name, ): # self.__attrname / node_name.__attrname break - if isinstance(attribute.expr, astroid.Call): + if isinstance(attribute.expr, nodes.Call): # type(self).__attrname inferred = safe_infer(attribute.expr) if ( - isinstance(inferred, astroid.ClassDef) + isinstance(inferred, nodes.ClassDef) and inferred.name == node.name ): break @@ -953,17 +954,17 @@ a metaclass class method.", args=(node.name, function_repr.lstrip(".")), ) - def _check_unused_private_variables(self, node: astroid.ClassDef) -> None: - for assign_name in node.nodes_of_class(astroid.AssignName): - if isinstance(assign_name.parent, astroid.Arguments): + def _check_unused_private_variables(self, node: nodes.ClassDef) -> None: + for assign_name in node.nodes_of_class(nodes.AssignName): + if isinstance(assign_name.parent, nodes.Arguments): continue # Ignore function arguments if not is_attr_private(assign_name.name): continue - for child in node.nodes_of_class((astroid.Name, astroid.Attribute)): - if isinstance(child, astroid.Name) and child.name == assign_name.name: + for child in node.nodes_of_class((nodes.Name, nodes.Attribute)): + if isinstance(child, nodes.Name) and child.name == assign_name.name: break if ( - isinstance(child, astroid.Attribute) + isinstance(child, nodes.Attribute) and child.attrname == assign_name.name and child.expr.name in ("self", "cls", node.name) ): @@ -972,11 +973,11 @@ a metaclass class method.", args = (node.name, assign_name.name) self.add_message("unused-private-member", node=assign_name, args=args) - def _check_unused_private_attributes(self, node: astroid.ClassDef) -> None: - for assign_attr in node.nodes_of_class(astroid.AssignAttr): - assign_attr = cast(astroid.AssignAttr, assign_attr) + def _check_unused_private_attributes(self, node: nodes.ClassDef) -> None: + for assign_attr in node.nodes_of_class(nodes.AssignAttr): + assign_attr = cast(nodes.AssignAttr, assign_attr) if not is_attr_private(assign_attr.attrname) or not isinstance( - assign_attr.expr, astroid.Name + assign_attr.expr, nodes.Name ): continue @@ -985,17 +986,17 @@ a metaclass class method.", # Then check if the attribute was consumed in other instance methods acceptable_obj_names: List[str] = ["self"] scope = assign_attr.scope() - if isinstance(scope, astroid.FunctionDef) and scope.name == "__new__": + if isinstance(scope, nodes.FunctionDef) and scope.name == "__new__": acceptable_obj_names.extend( [ return_node.value.name - for return_node in scope.nodes_of_class(astroid.Return) - if isinstance(return_node.value, astroid.Name) + for return_node in scope.nodes_of_class(nodes.Return) + if isinstance(return_node.value, nodes.Name) ] ) - for attribute in node.nodes_of_class(astroid.Attribute): - attribute = cast(astroid.Attribute, attribute) + for attribute in node.nodes_of_class(nodes.Attribute): + attribute = cast(nodes.Attribute, attribute) if attribute.attrname != assign_attr.attrname: continue @@ -1022,7 +1023,7 @@ a metaclass class method.", args = (node.name, assign_attr.attrname) self.add_message("unused-private-member", node=assign_attr, args=args) - def _check_attribute_defined_outside_init(self, cnode: astroid.ClassDef) -> None: + def _check_attribute_defined_outside_init(self, cnode: nodes.ClassDef) -> None: # check access to existent members on non metaclass classes if self._ignore_mixin and cnode.name[-5:].lower() == "mixin": # We are in a mixin class. No need to try to figure out if @@ -1038,25 +1039,25 @@ a metaclass class method.", return defining_methods = self.config.defining_attr_methods current_module = cnode.root() - for attr, nodes in cnode.instance_attrs.items(): + for attr, nodes_lst in cnode.instance_attrs.items(): # Exclude `__dict__` as it is already defined. if attr == "__dict__": continue # Skip nodes which are not in the current module and it may screw up # the output, while it's not worth it - nodes = [ + nodes_lst = [ n - for n in nodes - if not isinstance(n.statement(), (astroid.Delete, astroid.AugAssign)) + for n in nodes_lst + if not isinstance(n.statement(), (nodes.Delete, nodes.AugAssign)) and n.root() is current_module ] - if not nodes: + if not nodes_lst: continue # error detected by typechecking # Check if any method attr is defined in is a defining method # or if we have the attribute defined in a setter. - frames = (node.frame() for node in nodes) + frames = (node.frame() for node in nodes_lst) if any( frame.name in defining_methods or is_property_setter(frame) for frame in frames @@ -1078,7 +1079,7 @@ a metaclass class method.", try: cnode.local_attr(attr) except astroid.NotFoundError: - for node in nodes: + for node in nodes_lst: if node.frame().name not in defining_methods: # If the attribute was set by a call in any # of the defining methods, then don't emit @@ -1117,7 +1118,7 @@ a metaclass class method.", # dictionary. # This may happen with astroid build from living objects continue - if not isinstance(parent_function, astroid.FunctionDef): + if not isinstance(parent_function, nodes.FunctionDef): continue self._check_signature(node, parent_function, "overridden", klass) self._check_invalid_overridden_method(node, parent_function) @@ -1125,14 +1126,14 @@ a metaclass class method.", if node.decorators: for decorator in node.decorators.nodes: - if isinstance(decorator, astroid.Attribute) and decorator.attrname in ( + if isinstance(decorator, nodes.Attribute) and decorator.attrname in ( "getter", "setter", "deleter", ): # attribute affectation will call this method, not hiding it return - if isinstance(decorator, astroid.Name): + if isinstance(decorator, nodes.Name): if decorator.name == "property": # attribute affectation will either call a setter or raise # an attribute error, anyway not hiding the function @@ -1142,7 +1143,7 @@ a metaclass class method.", inferred = safe_infer(decorator) if not inferred: return - if isinstance(inferred, astroid.FunctionDef): + if isinstance(inferred, nodes.FunctionDef): # Okay, it's a decorator, let's see what it can infer. try: inferred = next(inferred.infer_call_result(inferred)) @@ -1150,7 +1151,7 @@ a metaclass class method.", return try: if ( - isinstance(inferred, (astroid.Instance, astroid.ClassDef)) + isinstance(inferred, (astroid.Instance, nodes.ClassDef)) and inferred.getattr("__get__") and inferred.getattr("__set__") ): @@ -1163,12 +1164,12 @@ a metaclass class method.", overridden = klass.instance_attr(node.name)[0] overridden_frame = overridden.frame() if ( - isinstance(overridden_frame, astroid.FunctionDef) + isinstance(overridden_frame, nodes.FunctionDef) and overridden_frame.type == "method" ): overridden_frame = overridden_frame.parent.frame() if not ( - isinstance(overridden_frame, astroid.ClassDef) + isinstance(overridden_frame, nodes.ClassDef) and klass.is_subtype_of(overridden_frame.qname()) ): return @@ -1178,7 +1179,7 @@ a metaclass class method.", if node.name in ancestor.instance_attrs and is_attr_private(node.name): return for obj in ancestor.lookup(node.name)[1]: - if isinstance(obj, astroid.FunctionDef): + if isinstance(obj, nodes.FunctionDef): return args = (overridden.root().name, overridden.fromlineno) self.add_message("method-hidden", args=args, node=node) @@ -1213,15 +1214,15 @@ a metaclass class method.", return statement = body[0] - if not isinstance(statement, (astroid.Expr, astroid.Return)): + if not isinstance(statement, (nodes.Expr, nodes.Return)): # Doing something else than what we are interested into. return call = statement.value if ( - not isinstance(call, astroid.Call) + not isinstance(call, nodes.Call) # Not a super() attribute access. - or not isinstance(call.func, astroid.Attribute) + or not isinstance(call.func, nodes.Attribute) ): return @@ -1261,7 +1262,7 @@ a metaclass class method.", # This may happen with astroid build from living objects continue if ( - not isinstance(meth_node, astroid.FunctionDef) + not isinstance(meth_node, nodes.FunctionDef) # If the method have an ancestor which is not a # function then it is legitimate to redefine it or _has_different_parameters_default_value( @@ -1323,8 +1324,8 @@ a metaclass class method.", node=function_node, ) - parent_is_async = isinstance(parent_function_node, astroid.AsyncFunctionDef) - current_is_async = isinstance(function_node, astroid.AsyncFunctionDef) + parent_is_async = isinstance(parent_function_node, nodes.AsyncFunctionDef) + current_is_async = isinstance(function_node, nodes.AsyncFunctionDef) if parent_is_async and not current_is_async: self.add_message( @@ -1351,7 +1352,7 @@ a metaclass class method.", self.add_message("invalid-slots", node=node) continue - if isinstance(slots, astroid.Const): + if isinstance(slots, nodes.Const): # a string, ignore the following checks self.add_message("single-string-used-for-slots", node=node) continue @@ -1359,7 +1360,7 @@ a metaclass class method.", # we can't obtain the values, maybe a .deque? continue - if isinstance(slots, astroid.Dict): + if isinstance(slots, nodes.Dict): values = [item[0] for item in slots.items] else: values = slots.itered() @@ -1375,7 +1376,7 @@ a metaclass class method.", for inferred in elt.infer(): if inferred is astroid.Uninferable: continue - if not isinstance(inferred, astroid.Const) or not isinstance( + if not isinstance(inferred, nodes.Const) or not isinstance( inferred.value, str ): self.add_message( @@ -1393,7 +1394,7 @@ a metaclass class method.", # Skip annotated assignments which don't conflict at all with slots. if len(class_variable) == 1: parent = class_variable[0].parent - if isinstance(parent, astroid.AnnAssign) and parent.value is None: + if isinstance(parent, nodes.AnnAssign) and parent.value is None: return self.add_message( "class-variable-slots-conflict", args=(inferred.value,), node=elt @@ -1442,19 +1443,19 @@ a metaclass class method.", self._check_protected_attribute_access(node) @check_messages("assigning-non-slot", "invalid-class-object") - def visit_assignattr(self, node: astroid.AssignAttr) -> None: + def visit_assignattr(self, node: nodes.AssignAttr) -> None: if isinstance( - node.assign_type(), astroid.AugAssign + node.assign_type(), nodes.AugAssign ) and self._uses_mandatory_method_param(node): self._accessed.set_accessed(node) self._check_in_slots(node) self._check_invalid_class_object(node) - def _check_invalid_class_object(self, node: astroid.AssignAttr) -> None: + def _check_invalid_class_object(self, node: nodes.AssignAttr) -> None: if not node.attrname == "__class__": return inferred = safe_infer(node.parent.value) - if isinstance(inferred, astroid.ClassDef) or inferred is astroid.Uninferable: + if isinstance(inferred, nodes.ClassDef) or inferred is astroid.Uninferable: # If is uninferrable, we allow it to prevent false positives return self.add_message("invalid-class-object", node=node) @@ -1516,7 +1517,7 @@ a metaclass class method.", def visit_assign(self, assign_node): self._check_classmethod_declaration(assign_node) node = assign_node.targets[0] - if not isinstance(node, astroid.AssignAttr): + if not isinstance(node, nodes.AssignAttr): return if self._uses_mandatory_method_param(node): @@ -1532,12 +1533,12 @@ a metaclass class method.", is defined. `node` is an assign node. """ - if not isinstance(node.value, astroid.Call): + if not isinstance(node.value, nodes.Call): return # check the function called is "classmethod" or "staticmethod" func = node.value.func - if not isinstance(func, astroid.Name) or func.name not in ( + if not isinstance(func, nodes.Name) or func.name not in ( "classmethod", "staticmethod", ): @@ -1550,12 +1551,12 @@ a metaclass class method.", ) # assignment must be at a class scope parent_class = node.scope() - if not isinstance(parent_class, astroid.ClassDef): + if not isinstance(parent_class, nodes.ClassDef): return # Check if the arg passed to classmethod is a class member classmeth_arg = node.value.args[0] - if not isinstance(classmeth_arg, astroid.Name): + if not isinstance(classmeth_arg, nodes.Name): return method_name = classmeth_arg.name @@ -1592,8 +1593,8 @@ a metaclass class method.", # If the expression begins with a call to super, that's ok. if ( - isinstance(node.expr, astroid.Call) - and isinstance(node.expr.func, astroid.Name) + isinstance(node.expr, nodes.Call) + and isinstance(node.expr.func, nodes.Name) and node.expr.func.name == "super" ): return @@ -1613,9 +1614,9 @@ a metaclass class method.", stmt = node.parent.statement() if ( - isinstance(stmt, astroid.Assign) + isinstance(stmt, nodes.Assign) and len(stmt.targets) == 1 - and isinstance(stmt.targets[0], astroid.AssignName) + and isinstance(stmt.targets[0], nodes.AssignName) ): name = stmt.targets[0].name if _is_attribute_property(name, klass): @@ -1639,7 +1640,7 @@ a metaclass class method.", self.add_message("protected-access", node=node, args=attrname) @staticmethod - def _is_called_inside_special_method(node: astroid.node_classes.NodeNG) -> bool: + def _is_called_inside_special_method(node: nodes.NodeNG) -> bool: """ Returns true if the node is located inside a special (aka dunder) method """ @@ -1651,8 +1652,8 @@ a metaclass class method.", def _is_type_self_call(self, expr): return ( - isinstance(expr, astroid.Call) - and isinstance(expr.func, astroid.Name) + isinstance(expr, nodes.Call) + and isinstance(expr.func, nodes.Name) and expr.func.name == "type" and len(expr.args) == 1 and self._is_mandatory_method_param(expr.args[0]) @@ -1662,7 +1663,7 @@ a metaclass class method.", def _is_classmethod(func): """Check if the given *func* node is a class method.""" - return isinstance(func, astroid.FunctionDef) and ( + return isinstance(func, nodes.FunctionDef) and ( func.type == "classmethod" or func.name == "__class_getitem__" ) @@ -1708,7 +1709,7 @@ a metaclass class method.", def _check_accessed_members(self, node, accessed): """check that accessed members are defined""" excs = ("AttributeError", "Exception", "BaseException") - for attr, nodes in accessed.items(): + for attr, nodes_lst in accessed.items(): try: # is it a class attribute ? node.local_attr(attr) @@ -1730,7 +1731,7 @@ a metaclass class method.", pass else: # filter out augment assignment nodes - defstmts = [stmt for stmt in defstmts if stmt not in nodes] + defstmts = [stmt for stmt in defstmts if stmt not in nodes_lst] if not defstmts: # only augment assignment for this node, no-member should be # triggered by the typecheck checker @@ -1751,7 +1752,7 @@ a metaclass class method.", # it's defined, it's accessed after the initial assignment frame = defstmt.frame() lno = defstmt.fromlineno - for _node in nodes: + for _node in nodes_lst: if ( _node.frame() is frame and _node.fromlineno < lno @@ -1881,14 +1882,14 @@ a metaclass class method.", klass_node = node.parent.frame() to_call = _ancestors_to_call(klass_node) not_called_yet = dict(to_call) - for stmt in node.nodes_of_class(astroid.Call): + for stmt in node.nodes_of_class(nodes.Call): expr = stmt.func - if not isinstance(expr, astroid.Attribute) or expr.attrname != "__init__": + if not isinstance(expr, nodes.Attribute) or expr.attrname != "__init__": continue # skip the test if using super if ( - isinstance(expr.expr, astroid.Call) - and isinstance(expr.expr.func, astroid.Name) + isinstance(expr.expr, nodes.Call) + and isinstance(expr.expr.func, nodes.Name) and expr.expr.func.name == "super" ): return @@ -1905,7 +1906,7 @@ a metaclass class method.", if ( isinstance(klass, astroid.Instance) - and isinstance(klass._proxied, astroid.ClassDef) + and isinstance(klass._proxied, nodes.ClassDef) and is_builtin_object(klass._proxied) and klass._proxied.name == "super" ): @@ -1932,8 +1933,8 @@ a metaclass class method.", def _check_signature(self, method1, refmethod, class_type, cls): """check that the signature of the two given methods match""" if not ( - isinstance(method1, astroid.FunctionDef) - and isinstance(refmethod, astroid.FunctionDef) + isinstance(method1, nodes.FunctionDef) + and isinstance(refmethod, nodes.FunctionDef) ): self.add_message( "method-check-failed", args=(method1, refmethod), node=method1 @@ -2015,13 +2016,13 @@ a metaclass class method.", return self._is_mandatory_method_param(node.expr) def _is_mandatory_method_param(self, node): - """Check if astroid.Name corresponds to first attribute variable name + """Check if nodes.Name corresponds to first attribute variable name Name is `self` for method, `cls` for classmethod and `mcs` for metaclass. """ return ( self._first_attrs - and isinstance(node, astroid.Name) + and isinstance(node, nodes.Name) and node.name == self._first_attrs[-1] ) @@ -2215,7 +2216,7 @@ class SpecialMethodsChecker(BaseChecker): return ( isinstance(node, astroid.Instance) and node.name == type_ - and not isinstance(node, astroid.Const) + and not isinstance(node, nodes.Const) ) @staticmethod @@ -2223,42 +2224,42 @@ class SpecialMethodsChecker(BaseChecker): if SpecialMethodsChecker._is_wrapped_type(node, "int"): return True - return isinstance(node, astroid.Const) and isinstance(node.value, int) + return isinstance(node, nodes.Const) and isinstance(node.value, int) @staticmethod def _is_str(node): if SpecialMethodsChecker._is_wrapped_type(node, "str"): return True - return isinstance(node, astroid.Const) and isinstance(node.value, str) + return isinstance(node, nodes.Const) and isinstance(node.value, str) @staticmethod def _is_bool(node): if SpecialMethodsChecker._is_wrapped_type(node, "bool"): return True - return isinstance(node, astroid.Const) and isinstance(node.value, bool) + return isinstance(node, nodes.Const) and isinstance(node.value, bool) @staticmethod def _is_bytes(node): if SpecialMethodsChecker._is_wrapped_type(node, "bytes"): return True - return isinstance(node, astroid.Const) and isinstance(node.value, bytes) + return isinstance(node, nodes.Const) and isinstance(node.value, bytes) @staticmethod def _is_tuple(node): if SpecialMethodsChecker._is_wrapped_type(node, "tuple"): return True - return isinstance(node, astroid.Const) and isinstance(node.value, tuple) + return isinstance(node, nodes.Const) and isinstance(node.value, tuple) @staticmethod def _is_dict(node): if SpecialMethodsChecker._is_wrapped_type(node, "dict"): return True - return isinstance(node, astroid.Const) and isinstance(node.value, dict) + return isinstance(node, nodes.Const) and isinstance(node.value, dict) @staticmethod def _is_iterator(node): @@ -2275,9 +2276,9 @@ class SpecialMethodsChecker(BaseChecker): return True except astroid.NotFoundError: pass - elif isinstance(node, astroid.ClassDef): + elif isinstance(node, nodes.ClassDef): metaclass = node.metaclass() - if metaclass and isinstance(metaclass, astroid.ClassDef): + if metaclass and isinstance(metaclass, nodes.ClassDef): try: metaclass.local_attr(NEXT_METHOD) return True @@ -2292,7 +2293,7 @@ class SpecialMethodsChecker(BaseChecker): def _check_len(self, node, inferred): if not self._is_int(inferred): self.add_message("invalid-length-returned", node=node) - elif isinstance(inferred, astroid.Const) and inferred.value < 0: + elif isinstance(inferred, nodes.Const) and inferred.value < 0: self.add_message("invalid-length-returned", node=node) def _check_bool(self, node, inferred): @@ -2322,7 +2323,7 @@ class SpecialMethodsChecker(BaseChecker): def _check_length_hint(self, node, inferred): if not self._is_int(inferred): self.add_message("invalid-length-hint-returned", node=node) - elif isinstance(inferred, astroid.Const) and inferred.value < 0: + elif isinstance(inferred, nodes.Const) and inferred.value < 0: self.add_message("invalid-length-hint-returned", node=node) def _check_format(self, node, inferred): @@ -2338,7 +2339,7 @@ class SpecialMethodsChecker(BaseChecker): self.add_message("invalid-getnewargs-ex-returned", node=node) return - if not isinstance(inferred, astroid.Tuple): + if not isinstance(inferred, nodes.Tuple): # If it's not an astroid.Tuple we can't analyze it further return @@ -2352,7 +2353,7 @@ class SpecialMethodsChecker(BaseChecker): (inferred.elts[1], self._is_dict), ): - if isinstance(arg, astroid.Call): + if isinstance(arg, nodes.Call): arg = safe_infer(arg) if arg and arg is not astroid.Uninferable: diff --git a/pylint/checkers/deprecated.py b/pylint/checkers/deprecated.py index fb2e6abfd..05d43902c 100644 --- a/pylint/checkers/deprecated.py +++ b/pylint/checkers/deprecated.py @@ -6,6 +6,7 @@ from itertools import chain from typing import Any, Container, Iterable, Tuple, Union import astroid +from astroid import nodes from pylint.checkers import utils from pylint.checkers.utils import get_import_name, safe_infer @@ -13,8 +14,8 @@ from pylint.checkers.utils import get_import_name, safe_infer ACCEPTABLE_NODES = ( astroid.BoundMethod, astroid.UnboundMethod, - astroid.FunctionDef, - astroid.ClassDef, + nodes.FunctionDef, + nodes.ClassDef, ) @@ -56,8 +57,8 @@ class DeprecatedMixin: "deprecated-argument", "deprecated-class", ) - def visit_call(self, node: astroid.Call) -> None: - """Called when a :class:`.astroid.node_classes.Call` node is visited.""" + def visit_call(self, node: nodes.Call) -> None: + """Called when a :class:`.astroid.Call` node is visited.""" try: self.check_deprecated_class_in_call(node) for inferred in node.func.infer(): @@ -94,7 +95,7 @@ class DeprecatedMixin: children = list(node.get_children()) if not children: return - if isinstance(children[0], astroid.Call): + if isinstance(children[0], nodes.Call): inf = safe_infer(children[0].func) else: inf = safe_infer(children[0]) @@ -189,9 +190,9 @@ class DeprecatedMixin: if not isinstance(inferred, ACCEPTABLE_NODES): return - if isinstance(node.func, astroid.Attribute): + if isinstance(node.func, nodes.Attribute): func_name = node.func.attrname - elif isinstance(node.func, astroid.Name): + elif isinstance(node.func, nodes.Name): func_name = node.func.name else: # Not interested in other nodes. @@ -237,8 +238,8 @@ class DeprecatedMixin: def check_deprecated_class_in_call(self, node): """Checks if call the deprecated class""" - if isinstance(node.func, astroid.Attribute) and isinstance( - node.func.expr, astroid.Name + if isinstance(node.func, nodes.Attribute) and isinstance( + node.func.expr, nodes.Name ): mod_name = node.func.expr.name class_name = node.func.attrname |