diff options
author | Marc Mueller <30130371+cdce8p@users.noreply.github.com> | 2021-08-18 09:48:25 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-18 09:48:25 +0200 |
commit | f78a35afb76c38f4141714130bbd1a35ee430ea1 (patch) | |
tree | 41293483b52050a67c084891bb6da9b11a639d80 | |
parent | 6e2dbbf4630c97c2fa7dc36dcb29c7501221acd6 (diff) | |
download | pylint-git-f78a35afb76c38f4141714130bbd1a35ee430ea1.tar.gz |
Use alias for astroid.nodes 02 (#4863)
* Use alias for astroid nodes
* Resolve name conflicts
-rw-r--r-- | pylint/checkers/exceptions.py | 56 | ||||
-rw-r--r-- | pylint/checkers/imports.py | 60 | ||||
-rw-r--r-- | pylint/checkers/logging.py | 25 | ||||
-rw-r--r-- | pylint/checkers/newstyle.py | 17 | ||||
-rw-r--r-- | pylint/checkers/python3.py | 79 | ||||
-rw-r--r-- | pylint/checkers/similar.py | 12 | ||||
-rw-r--r-- | pylint/checkers/stdlib.py | 24 | ||||
-rw-r--r-- | pylint/checkers/strings.py | 57 | ||||
-rw-r--r-- | pylint/checkers/typecheck.py | 224 |
9 files changed, 277 insertions, 277 deletions
diff --git a/pylint/checkers/exceptions.py b/pylint/checkers/exceptions.py index e4a8de99b..7c173a5ab 100644 --- a/pylint/checkers/exceptions.py +++ b/pylint/checkers/exceptions.py @@ -37,6 +37,7 @@ import inspect import typing import astroid +from astroid import nodes from pylint import checkers, interfaces from pylint.checkers import utils @@ -57,7 +58,7 @@ def _annotated_unpack_infer(stmt, context=None): Returns an iterator which yields tuples in the format ('original node', 'inferred node'). """ - if isinstance(stmt, (astroid.List, astroid.Tuple)): + if isinstance(stmt, (nodes.List, nodes.Tuple)): for elt in stmt.elts: inferred = utils.safe_infer(elt) if inferred and inferred is not astroid.Uninferable: @@ -72,7 +73,7 @@ def _annotated_unpack_infer(stmt, context=None): def _is_raising(body: typing.List) -> bool: """Return true if the given statement node raise an exception""" for node in body: - if isinstance(node, astroid.Raise): + if isinstance(node, nodes.Raise): return True return False @@ -212,11 +213,11 @@ class ExceptionRaiseRefVisitor(BaseVisitor): self._checker.add_message("notimplemented-raised", node=self._node) def visit_call(self, call): - if isinstance(call.func, astroid.Name): + if isinstance(call.func, nodes.Name): self.visit_name(call.func) if ( len(call.args) > 1 - and isinstance(call.args[0], astroid.Const) + and isinstance(call.args[0], nodes.Const) and isinstance(call.args[0].value, str) ): msg = call.args[0].value @@ -315,7 +316,7 @@ class ExceptionsChecker(checkers.BaseChecker): # Filter out if it's present in __exit__. scope = node.scope() if ( - isinstance(scope, astroid.FunctionDef) + isinstance(scope, nodes.FunctionDef) and scope.is_method() and scope.name == "__exit__" ): @@ -324,15 +325,15 @@ class ExceptionsChecker(checkers.BaseChecker): current = node # Stop when a new scope is generated or when the raise # statement is found inside a TryFinally. - ignores = (astroid.ExceptHandler, astroid.FunctionDef) + ignores = (nodes.ExceptHandler, nodes.FunctionDef) while current and not isinstance(current.parent, ignores): current = current.parent - expected = (astroid.ExceptHandler,) + expected = (nodes.ExceptHandler,) if not current or not isinstance(current.parent, expected): self.add_message("misplaced-bare-raise", node=node) - def _check_bad_exception_context(self, node: astroid.Raise) -> None: + def _check_bad_exception_context(self, node: nodes.Raise) -> None: """Verify that the exception context is properly set. An exception context can be only `None` or an exception. @@ -341,15 +342,15 @@ class ExceptionsChecker(checkers.BaseChecker): if cause in (astroid.Uninferable, None): return - if isinstance(cause, astroid.Const): + if isinstance(cause, nodes.Const): if cause.value is not None: self.add_message("bad-exception-context", node=node) - elif not isinstance(cause, astroid.ClassDef) and not utils.inherit_from_std_ex( + elif not isinstance(cause, nodes.ClassDef) and not utils.inherit_from_std_ex( cause ): self.add_message("bad-exception-context", node=node) - def _check_raise_missing_from(self, node: astroid.Raise) -> None: + def _check_raise_missing_from(self, node: nodes.Raise) -> None: if node.exc is None: # This is a plain `raise`, raising the previously-caught exception. No need for a # cause. @@ -368,20 +369,18 @@ class ExceptionsChecker(checkers.BaseChecker): # The `except` doesn't have an `as exception:` part, meaning there's no way that # the `raise` is raising the same exception. self.add_message("raise-missing-from", node=node) - elif isinstance(node.exc, astroid.Call) and isinstance( - node.exc.func, astroid.Name - ): + elif isinstance(node.exc, nodes.Call) and isinstance(node.exc.func, nodes.Name): # We have a `raise SomeException(whatever)`. self.add_message("raise-missing-from", node=node) elif ( - isinstance(node.exc, astroid.Name) + isinstance(node.exc, nodes.Name) and node.exc.name != containing_except_node.name.name ): # We have a `raise SomeException`. self.add_message("raise-missing-from", node=node) def _check_catching_non_exception(self, handler, exc, part): - if isinstance(exc, astroid.Tuple): + if isinstance(exc, nodes.Tuple): # Check if it is a tuple of exceptions. inferred = [utils.safe_infer(elt) for elt in exc.elts] if any(node is astroid.Uninferable for node in inferred): @@ -394,14 +393,13 @@ class ExceptionsChecker(checkers.BaseChecker): ): return - if not isinstance(exc, astroid.ClassDef): + if not isinstance(exc, nodes.ClassDef): # Don't emit the warning if the inferred stmt # is None, but the exception handler is something else, # maybe it was redefined. - if isinstance(exc, astroid.Const) and exc.value is None: + if isinstance(exc, nodes.Const) and exc.value is None: if ( - isinstance(handler.type, astroid.Const) - and handler.type.value is None + isinstance(handler.type, nodes.Const) and handler.type.value is None ) or handler.type.parent_of(exc): # If the exception handler catches None or # the exception component, which is None, is @@ -432,16 +430,16 @@ class ExceptionsChecker(checkers.BaseChecker): def _check_try_except_raise(self, node): def gather_exceptions_from_handler( handler, - ) -> typing.Optional[typing.List[astroid.node_classes.NodeNG]]: - exceptions: typing.List[astroid.node_classes.NodeNG] = [] + ) -> typing.Optional[typing.List[nodes.NodeNG]]: + exceptions: typing.List[nodes.NodeNG] = [] if handler.type: exceptions_in_handler = utils.safe_infer(handler.type) - if isinstance(exceptions_in_handler, astroid.Tuple): + if isinstance(exceptions_in_handler, nodes.Tuple): exceptions = list( { exception for exception in exceptions_in_handler.elts - if isinstance(exception, astroid.Name) + if isinstance(exception, nodes.Name) } ) elif exceptions_in_handler: @@ -488,7 +486,7 @@ class ExceptionsChecker(checkers.BaseChecker): @utils.check_messages("wrong-exception-operation") def visit_binop(self, node): - if isinstance(node.parent, astroid.ExceptHandler): + if isinstance(node.parent, nodes.ExceptHandler): # except (V | A) suggestion = "Did you mean '({}, {})' instead?".format( node.left.as_string(), @@ -498,7 +496,7 @@ class ExceptionsChecker(checkers.BaseChecker): @utils.check_messages("wrong-exception-operation") def visit_compare(self, node): - if isinstance(node.parent, astroid.ExceptHandler): + if isinstance(node.parent, nodes.ExceptHandler): # except (V < A) suggestion = "Did you mean '({}, {})' instead?".format( node.left.as_string(), @@ -531,7 +529,7 @@ class ExceptionsChecker(checkers.BaseChecker): msg = "empty except clause should always appear last" self.add_message("bad-except-order", node=node, args=msg) - elif isinstance(handler.type, astroid.BoolOp): + elif isinstance(handler.type, nodes.BoolOp): self.add_message( "binary-op-exception", node=handler, args=handler.type.op ) @@ -552,13 +550,13 @@ class ExceptionsChecker(checkers.BaseChecker): self._check_catching_non_exception(handler, exc, part) - if not isinstance(exc, astroid.ClassDef): + if not isinstance(exc, nodes.ClassDef): continue exc_ancestors = [ anc for anc in exc.ancestors() - if isinstance(anc, astroid.ClassDef) + if isinstance(anc, nodes.ClassDef) ] for previous_exc in exceptions_classes: diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index 0f926285a..3328960ec 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -53,6 +53,7 @@ from distutils import sysconfig from typing import Dict, List, Set, Union import astroid +from astroid import nodes from pylint.checkers import BaseChecker, DeprecatedMixin from pylint.checkers.utils import ( @@ -92,11 +93,11 @@ def _get_first_import(node, context, name, base, level, alias): continue if first.scope() is node.scope() and first.fromlineno > node.fromlineno: continue - if isinstance(first, astroid.Import): + if isinstance(first, nodes.Import): if any(fullname == iname[0] for iname in first.names): found = True break - elif isinstance(first, astroid.ImportFrom): + elif isinstance(first, nodes.ImportFrom): if level == first.level: for imported_name, imported_alias in first.names: if fullname == f"{first.modname}.{imported_name}": @@ -148,8 +149,8 @@ def _make_tree_defs(mod_files_list): def _repr_tree_defs(data, indent_str=None): """return a string which represents imports as a tree""" lines = [] - nodes = data.items() - for i, (mod, (sub, files)) in enumerate(sorted(nodes, key=lambda x: x[0])): + nodes_items = data.items() + for i, (mod, (sub, files)) in enumerate(sorted(nodes_items, key=lambda x: x[0])): if not files: files = "" else: @@ -159,7 +160,7 @@ def _repr_tree_defs(data, indent_str=None): sub_indent_str = " " else: lines.append(fr"{indent_str}\-{mod} {files}") - if i == len(nodes) - 1: + if i == len(nodes_items) - 1: sub_indent_str = "%s " % indent_str else: sub_indent_str = "%s| " % indent_str @@ -510,10 +511,10 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): self.check_deprecated_module(node, name) self._check_preferred_module(node, name) imported_module = self._get_imported_module(node, name) - if isinstance(node.parent, astroid.Module): + if isinstance(node.parent, nodes.Module): # Allow imports nested self._check_position(node) - if isinstance(node.scope(), astroid.Module): + if isinstance(node.scope(), nodes.Module): self._record_import(node, imported_module) if imported_module is None: @@ -536,10 +537,10 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): self._check_reimport(node, basename=basename, level=node.level) self._check_toplevel(node) - if isinstance(node.parent, astroid.Module): + if isinstance(node.parent, nodes.Module): # Allow imports nested self._check_position(node) - if isinstance(node.scope(), astroid.Module): + if isinstance(node.scope(), nodes.Module): self._record_import(node, imported_module) if imported_module is None: return @@ -550,7 +551,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): self._add_imported_module(node, imported_module.name) @check_messages(*MSGS) - def leave_module(self, node: astroid.Module) -> None: + def leave_module(self, node: nodes.Module) -> None: # Check imports are grouped by category (standard, 3rd party, local) std_imports, ext_imports, loc_imports = self._check_imports_order(node) @@ -563,7 +564,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): "ungrouped-imports", import_node.fromlineno ): continue - if isinstance(import_node, astroid.ImportFrom): + if isinstance(import_node, nodes.ImportFrom): met = met_from else: met = met_import @@ -590,21 +591,21 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): # instruction) if self._first_non_import_node: return - if not isinstance(node.parent, astroid.Module): + if not isinstance(node.parent, nodes.Module): return - nested_allowed = [astroid.TryExcept, astroid.TryFinally] + nested_allowed = [nodes.TryExcept, nodes.TryFinally] is_nested_allowed = [ allowed for allowed in nested_allowed if isinstance(node, allowed) ] if is_nested_allowed and any( - node.nodes_of_class((astroid.Import, astroid.ImportFrom)) + node.nodes_of_class((nodes.Import, nodes.ImportFrom)) ): return - if isinstance(node, astroid.Assign): + if isinstance(node, nodes.Assign): # Add compatibility for module level dunder names # https://www.python.org/dev/peps/pep-0008/#module-level-dunder-names valid_targets = [ - isinstance(target, astroid.AssignName) + isinstance(target, nodes.AssignName) and target.name.startswith("__") and target.name.endswith("__") for target in node.targets @@ -632,15 +633,15 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): # Check if the node belongs to an `If` or a `Try` block. If they # contain imports, skip recording this node. - if not isinstance(node.parent.scope(), astroid.Module): + if not isinstance(node.parent.scope(), nodes.Module): return root = node - while not isinstance(root.parent, astroid.Module): + while not isinstance(root.parent, nodes.Module): root = root.parent - if isinstance(root, (astroid.If, astroid.TryFinally, astroid.TryExcept)): - if any(root.nodes_of_class((astroid.Import, astroid.ImportFrom))): + if isinstance(root, (nodes.If, nodes.TryFinally, nodes.TryExcept)): + if any(root.nodes_of_class((nodes.Import, nodes.ImportFrom))): return self._first_non_import_node = node @@ -655,8 +656,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): if prev: # consecutive future statements are possible if not ( - isinstance(prev, astroid.ImportFrom) - and prev.modname == "__future__" + isinstance(prev, nodes.ImportFrom) and prev.modname == "__future__" ): self.add_message("misplaced-future", node=node) return @@ -681,14 +681,14 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): def _record_import(self, node, importedmodnode): """Record the package `node` imports from""" - if isinstance(node, astroid.ImportFrom): + if isinstance(node, nodes.ImportFrom): importedname = node.modname else: importedname = importedmodnode.name if importedmodnode else None if not importedname: importedname = node.names[0][0].split(".")[0] - if isinstance(node, astroid.ImportFrom) and (node.level or 0) >= 1: + if isinstance(node, nodes.ImportFrom) and (node.level or 0) >= 1: # We need the importedname with first point to detect local package # Example of node: # 'from .my_package1 import MyClass1' @@ -725,7 +725,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): package = "." + modname.split(".")[1] else: package = modname.split(".")[0] - nested = not isinstance(node.parent, astroid.Module) + nested = not isinstance(node.parent, nodes.Module) ignore_for_import_order = not self.linter.is_message_enabled( "wrong-import-order", node.fromlineno ) @@ -813,7 +813,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): return None def _add_imported_module( - self, node: Union[astroid.Import, astroid.ImportFrom], importedmodname: str + self, node: Union[nodes.Import, nodes.ImportFrom], importedmodname: str ) -> None: """notify an imported module, used to analyze dependencies""" module_file = node.root().file @@ -828,7 +828,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): pass in_type_checking_block = ( - isinstance(node.parent, astroid.If) and node.parent.is_typing_guard() + isinstance(node.parent, nodes.If) and node.parent.is_typing_guard() ) if context_name == importedmodname: @@ -866,7 +866,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): ) def _check_import_as_rename( - self, node: Union[astroid.Import, astroid.ImportFrom] + self, node: Union[nodes.Import, nodes.ImportFrom] ) -> None: names = node.names for name in names: @@ -982,12 +982,12 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): """Check whether the import is made outside the module toplevel.""" # If the scope of the import is a module, then obviously it is # not outside the module toplevel. - if isinstance(node.scope(), astroid.Module): + if isinstance(node.scope(), nodes.Module): return module_names = [ f"{node.modname}.{name[0]}" - if isinstance(node, astroid.ImportFrom) + if isinstance(node, nodes.ImportFrom) else name[0] for name in node.names ] diff --git a/pylint/checkers/logging.py b/pylint/checkers/logging.py index 411e2f574..9eb7ab172 100644 --- a/pylint/checkers/logging.py +++ b/pylint/checkers/logging.py @@ -26,6 +26,7 @@ import string import astroid +from astroid import nodes from pylint import checkers, interfaces from pylint.checkers import utils @@ -198,8 +199,8 @@ class LoggingChecker(checkers.BaseChecker): def is_logging_name(): return ( - isinstance(node.func, astroid.Attribute) - and isinstance(node.func.expr, astroid.Name) + isinstance(node.func, nodes.Attribute) + and isinstance(node.func.expr, nodes.Name) and node.func.expr.name in self._logging_names ) @@ -208,7 +209,7 @@ class LoggingChecker(checkers.BaseChecker): for inferred in node.func.infer(): if isinstance(inferred, astroid.BoundMethod): parent = inferred._proxied.parent - if isinstance(parent, astroid.ClassDef) and ( + if isinstance(parent, nodes.ClassDef) and ( parent.qname() == "logging.Logger" or any( ancestor.qname() == "logging.Logger" @@ -245,7 +246,7 @@ class LoggingChecker(checkers.BaseChecker): else: return - if isinstance(node.args[format_pos], astroid.BinOp): + if isinstance(node.args[format_pos], nodes.BinOp): binop = node.args[format_pos] emit = binop.op == "%" if binop.op == "+": @@ -261,11 +262,11 @@ class LoggingChecker(checkers.BaseChecker): node=node, args=(self._helper_string(node),), ) - elif isinstance(node.args[format_pos], astroid.Call): + elif isinstance(node.args[format_pos], nodes.Call): self._check_call_func(node.args[format_pos]) - elif isinstance(node.args[format_pos], astroid.Const): + elif isinstance(node.args[format_pos], nodes.Const): self._check_format_string(node, format_pos) - elif isinstance(node.args[format_pos], astroid.JoinedStr): + elif isinstance(node.args[format_pos], nodes.JoinedStr): self.add_message( "logging-fstring-interpolation", node=node, @@ -294,7 +295,7 @@ class LoggingChecker(checkers.BaseChecker): """ Return True if the operand in argument is a literal string """ - return isinstance(operand, astroid.Const) and operand.name == "str" + return isinstance(operand, nodes.Const) and operand.name == "str" def _check_call_func(self, node): """Checks that function call is not format_string.format(). @@ -319,7 +320,7 @@ class LoggingChecker(checkers.BaseChecker): """Checks that format string tokens match the supplied arguments. Args: - node (astroid.node_classes.NodeNG): AST node to be checked. + node (nodes.NodeNG): AST node to be checked. format_arg (int): Index of the format string in the node arguments. """ num_args = _count_supplied_tokens(node.args[format_arg + 1 :]) @@ -376,13 +377,13 @@ def is_complex_format_str(node): """Checks if node represents a string with complex formatting specs. Args: - node (astroid.node_classes.NodeNG): AST node to check + node (nodes.NodeNG): AST node to check Returns: bool: True if inferred string uses complex formatting, False otherwise """ inferred = utils.safe_infer(node) if inferred is None or not ( - isinstance(inferred, astroid.Const) and isinstance(inferred.value, str) + isinstance(inferred, nodes.Const) and isinstance(inferred.value, str) ): return True try: @@ -409,7 +410,7 @@ def _count_supplied_tokens(args): Returns: int: Number of AST nodes that aren't keywords. """ - return sum(1 for arg in args if not isinstance(arg, astroid.Keyword)) + return sum(1 for arg in args if not isinstance(arg, nodes.Keyword)) def register(linter): diff --git a/pylint/checkers/newstyle.py b/pylint/checkers/newstyle.py index 770eea39c..8c5ae5e83 100644 --- a/pylint/checkers/newstyle.py +++ b/pylint/checkers/newstyle.py @@ -22,6 +22,7 @@ """check for new / old style related problems """ import astroid +from astroid import nodes from pylint.checkers import BaseChecker from pylint.checkers.utils import check_messages, has_known_bases, node_frame_class @@ -61,20 +62,20 @@ class NewStyleConflictChecker(BaseChecker): if not node.is_method(): return klass = node.parent.frame() - for stmt in node.nodes_of_class(astroid.Call): + for stmt in node.nodes_of_class(nodes.Call): if node_frame_class(stmt) != node_frame_class(node): # Don't look down in other scopes. continue expr = stmt.func - if not isinstance(expr, astroid.Attribute): + if not isinstance(expr, nodes.Attribute): continue call = expr.expr # skip the test if using super if not ( - isinstance(call, astroid.Call) - and isinstance(call.func, astroid.Name) + isinstance(call, nodes.Call) + and isinstance(call.func, nodes.Name) and call.func.name == "super" ): continue @@ -89,8 +90,8 @@ class NewStyleConflictChecker(BaseChecker): # in derived classes arg0 = call.args[0] if ( - isinstance(arg0, astroid.Call) - and isinstance(arg0.func, astroid.Name) + isinstance(arg0, nodes.Call) + and isinstance(arg0.func, nodes.Name) and arg0.func.name == "type" ): self.add_message("bad-super-call", node=call, args=("type",)) @@ -100,9 +101,9 @@ class NewStyleConflictChecker(BaseChecker): # in derived classes if ( len(call.args) >= 2 - and isinstance(call.args[1], astroid.Name) + and isinstance(call.args[1], nodes.Name) and call.args[1].name == "self" - and isinstance(arg0, astroid.Attribute) + and isinstance(arg0, nodes.Attribute) and arg0.attrname == "__class__" ): self.add_message( diff --git a/pylint/checkers/python3.py b/pylint/checkers/python3.py index ccce98901..d5cf02926 100644 --- a/pylint/checkers/python3.py +++ b/pylint/checkers/python3.py @@ -46,6 +46,7 @@ import tokenize from collections import namedtuple import astroid +from astroid import nodes from pylint import checkers, interfaces from pylint.checkers import utils @@ -69,7 +70,7 @@ def _is_old_octal(literal): def _inferred_value_is_dict(value): - if isinstance(value, astroid.Dict): + if isinstance(value, nodes.Dict): return True return isinstance(value, astroid.Instance) and "dict" in value.basenames @@ -120,20 +121,20 @@ def _in_iterating_context(node): # Since a call can't be the loop variant we only need to know if the node's # parent is a 'for' loop to know it's being used as the iterator for the # loop. - if isinstance(parent, astroid.For): + if isinstance(parent, nodes.For): return True # Need to make sure the use of the node is in the iterator part of the # comprehension. - if isinstance(parent, astroid.Comprehension): + if isinstance(parent, nodes.Comprehension): if parent.iter == node: return True # Various built-ins can take in an iterable or list and lead to the same # value. - elif isinstance(parent, astroid.Call): - if isinstance(parent.func, astroid.Name): + elif isinstance(parent, nodes.Call): + if isinstance(parent.func, nodes.Name): if parent.func.name in _ACCEPTS_ITERATOR: return True - elif isinstance(parent.func, astroid.Attribute): + elif isinstance(parent.func, nodes.Attribute): if parent.func.attrname in ATTRIBUTES_ACCEPTS_ITERATOR: return True @@ -146,23 +147,23 @@ def _in_iterating_context(node): return True # If the call is in an unpacking, there's no need to warn, # since it can be considered iterating. - elif isinstance(parent, astroid.Assign) and isinstance( - parent.targets[0], (astroid.List, astroid.Tuple) + elif isinstance(parent, nodes.Assign) and isinstance( + parent.targets[0], (nodes.List, nodes.Tuple) ): if len(parent.targets[0].elts) > 1: return True # If the call is in a containment check, we consider that to # be an iterating context elif ( - isinstance(parent, astroid.Compare) + isinstance(parent, nodes.Compare) and len(parent.ops) == 1 and parent.ops[0][0] in ["in", "not in"] ): return True # Also if it's an `yield from`, that's fair - elif isinstance(parent, astroid.YieldFrom): + elif isinstance(parent, nodes.YieldFrom): return True - if isinstance(parent, astroid.Starred): + if isinstance(parent, nodes.Starred): return True return False @@ -171,7 +172,7 @@ def _is_conditional_import(node): """Checks if an import node is in the context of a conditional.""" parent = node.parent return isinstance( - parent, (astroid.TryExcept, astroid.ExceptHandler, astroid.If, astroid.IfExp) + parent, (nodes.TryExcept, nodes.ExceptHandler, nodes.If, nodes.IfExp) ) @@ -933,13 +934,13 @@ class Python3Checker(checkers.BaseChecker): super().add_message(msg_id, *args, **kwargs) def _is_py2_test(self, node): - if isinstance(node.test, astroid.Attribute) and isinstance( - node.test.expr, astroid.Name + if isinstance(node.test, nodes.Attribute) and isinstance( + node.test.expr, nodes.Name ): if node.test.expr.name == "six" and node.test.attrname == "PY2": return True elif ( - isinstance(node.test, astroid.Compare) + isinstance(node.test, nodes.Compare) and node.test.repr_tree() in self._python_2_tests ): return True @@ -988,7 +989,7 @@ class Python3Checker(checkers.BaseChecker): @utils.check_messages("parameter-unpacking") def visit_arguments(self, node): for arg in node.args: - if isinstance(arg, astroid.Tuple): + if isinstance(arg, nodes.Tuple): self.add_message("parameter-unpacking", node=arg) @utils.check_messages("comprehension-escape") @@ -996,14 +997,14 @@ class Python3Checker(checkers.BaseChecker): names = { generator.target.name for generator in node.generators - if isinstance(generator.target, astroid.AssignName) + if isinstance(generator.target, nodes.AssignName) } scope = node.parent.scope() - scope_names = scope.nodes_of_class(astroid.Name, skip_klass=astroid.FunctionDef) + scope_names = scope.nodes_of_class(nodes.Name, skip_klass=nodes.FunctionDef) has_redefined_assign_name = any( assign_name for assign_name in scope.nodes_of_class( - astroid.AssignName, skip_klass=astroid.FunctionDef + nodes.AssignName, skip_klass=nodes.FunctionDef ) if assign_name.name in names and assign_name.lineno > node.lineno ) @@ -1032,7 +1033,7 @@ class Python3Checker(checkers.BaseChecker): if node.name not in self._bad_builtins: return if node_ignores_exception(node) or isinstance( - find_try_except_wrapper_node(node), astroid.ExceptHandler + find_try_except_wrapper_node(node), nodes.ExceptHandler ): return @@ -1070,7 +1071,7 @@ class Python3Checker(checkers.BaseChecker): if node.names[0][0] == "*": if self.linter.is_message_enabled("import-star-module-level"): - if not isinstance(node.scope(), astroid.Module): + if not isinstance(node.scope(), nodes.Module): self.add_message("import-star-module-level", node=node) def visit_import(self, node): @@ -1098,7 +1099,7 @@ class Python3Checker(checkers.BaseChecker): # If we can infer the object and that object is not an int, bail out. if inferred and not ( ( - isinstance(inferred, astroid.Const) + isinstance(inferred, nodes.Const) and isinstance(inferred.value, int) ) or ( @@ -1113,16 +1114,16 @@ class Python3Checker(checkers.BaseChecker): def _check_cmp_argument(self, node): # Check that the `cmp` argument is used kwargs = [] - if isinstance(node.func, astroid.Attribute) and node.func.attrname == "sort": + if isinstance(node.func, nodes.Attribute) and node.func.attrname == "sort": inferred = utils.safe_infer(node.func.expr) if not inferred: return builtins_list = f"{astroid.bases.BUILTINS}.list" - if isinstance(inferred, astroid.List) or inferred.qname() == builtins_list: + if isinstance(inferred, nodes.List) or inferred.qname() == builtins_list: kwargs = node.keywords - elif isinstance(node.func, astroid.Name) and node.func.name == "sorted": + elif isinstance(node.func, nodes.Name) and node.func.name == "sorted": inferred = utils.safe_infer(node.func) if not inferred: return @@ -1138,13 +1139,13 @@ class Python3Checker(checkers.BaseChecker): @staticmethod def _is_constant_string_or_name(node): - if isinstance(node, astroid.Const): + if isinstance(node, nodes.Const): return isinstance(node.value, str) - return isinstance(node, astroid.Name) + return isinstance(node, nodes.Name) @staticmethod def _is_none(node): - return isinstance(node, astroid.Const) and node.value is None + return isinstance(node, nodes.Const) and node.value is None @staticmethod def _has_only_n_positional_args(node, number_of_args): @@ -1157,7 +1158,7 @@ class Python3Checker(checkers.BaseChecker): if inferred_type is astroid.Uninferable: confidence = INFERENCE_FAILURE elif not ( - isinstance(inferred_type, astroid.Const) + isinstance(inferred_type, nodes.Const) and isinstance(inferred_type.value, str) ): return None @@ -1166,7 +1167,7 @@ class Python3Checker(checkers.BaseChecker): def visit_call(self, node): self._check_cmp_argument(node) - if isinstance(node.func, astroid.Attribute): + if isinstance(node.func, nodes.Attribute): inferred_types = set() try: @@ -1176,7 +1177,7 @@ class Python3Checker(checkers.BaseChecker): if inferred_receiver is astroid.Uninferable: continue inferred_types.add(inferred_receiver) - if isinstance(inferred_receiver, astroid.Module): + if isinstance(inferred_receiver, nodes.Module): self._warn_if_deprecated( node, inferred_receiver.name, @@ -1234,7 +1235,7 @@ class Python3Checker(checkers.BaseChecker): self.add_message("dict-iter-method", node=node) elif node.func.attrname in ("viewkeys", "viewvalues", "viewitems"): self.add_message("dict-view-method", node=node) - elif isinstance(node.func, astroid.Name): + elif isinstance(node.func, nodes.Name): found_node = node.func.lookup(node.func.name)[0] if _is_builtin(found_node): if node.func.name in ("filter", "map", "range", "zip"): @@ -1249,7 +1250,7 @@ class Python3Checker(checkers.BaseChecker): break def _validate_encoding(self, encoding, node): - if isinstance(encoding, astroid.Const): + if isinstance(encoding, nodes.Const): value = encoding.value if value in self._invalid_encodings: self.add_message("invalid-str-codec", node=node) @@ -1267,7 +1268,7 @@ class Python3Checker(checkers.BaseChecker): return def visit_assignattr(self, node): - if isinstance(node.assign_type(), astroid.AugAssign): + if isinstance(node.assign_type(), nodes.AugAssign): self.visit_attribute(node) def visit_delattr(self, node): @@ -1294,7 +1295,7 @@ class Python3Checker(checkers.BaseChecker): if exception_message in inferred.instance_attrs: continue self.add_message("exception-message-attribute", node=node) - if isinstance(inferred, astroid.Module): + if isinstance(inferred, nodes.Module): self._warn_if_deprecated( node, inferred.name, {node.attrname}, report_on_modules=False ) @@ -1311,7 +1312,7 @@ class Python3Checker(checkers.BaseChecker): current = current.parent return current is not None - if isinstance(node.name, (astroid.Tuple, astroid.List)): + if isinstance(node.name, (nodes.Tuple, nodes.List)): self.add_message("unpacking-in-except", node=node) return @@ -1320,7 +1321,7 @@ class Python3Checker(checkers.BaseChecker): # Find any names scope = node.parent.scope() - scope_names = scope.nodes_of_class(astroid.Name, skip_klass=astroid.FunctionDef) + scope_names = scope.nodes_of_class(nodes.Name, skip_klass=nodes.FunctionDef) scope_names = list(scope_names) potential_leaked_names = [ scope_name @@ -1332,7 +1333,7 @@ class Python3Checker(checkers.BaseChecker): reassignments_for_same_name = { assign_name.lineno for assign_name in scope.nodes_of_class( - astroid.AssignName, skip_klass=astroid.FunctionDef + nodes.AssignName, skip_klass=nodes.FunctionDef ) if assign_name.name == node.name.name } @@ -1367,7 +1368,7 @@ class Python3Checker(checkers.BaseChecker): self._check_raise_value(node, value) def _check_raise_value(self, node, expr): - if isinstance(expr, astroid.Const): + if isinstance(expr, nodes.Const): value = expr.value if isinstance(value, str): self.add_message("raising-string", node=node) diff --git a/pylint/checkers/similar.py b/pylint/checkers/similar.py index b44081924..e9792ebeb 100644 --- a/pylint/checkers/similar.py +++ b/pylint/checkers/similar.py @@ -64,7 +64,7 @@ from typing import ( ) import astroid -from astroid.node_classes import NodeNG +from astroid import nodes from pylint.checkers import BaseChecker, MapReduceMixin, table_lines_from_stats from pylint.interfaces import IRawChecker @@ -576,7 +576,7 @@ def stripped_lines( tree = astroid.parse("".join(lines)) if ignore_imports: node_is_import_by_lineno = ( - (node.lineno, isinstance(node, (astroid.Import, astroid.ImportFrom))) + (node.lineno, isinstance(node, (nodes.Import, nodes.ImportFrom))) for node in tree.body ) line_begins_import = { @@ -588,16 +588,18 @@ def stripped_lines( current_line_is_import = False if ignore_signatures: - def _get_functions(functions: List[NodeNG], tree: NodeNG) -> List[NodeNG]: + def _get_functions( + functions: List[nodes.NodeNG], tree: nodes.NodeNG + ) -> List[nodes.NodeNG]: """Recursively get all functions including nested in the classes from the tree.""" for node in tree.body: - if isinstance(node, (astroid.FunctionDef, astroid.AsyncFunctionDef)): + if isinstance(node, (nodes.FunctionDef, nodes.AsyncFunctionDef)): functions.append(node) if isinstance( node, - (astroid.ClassDef, astroid.FunctionDef, astroid.AsyncFunctionDef), + (nodes.ClassDef, nodes.FunctionDef, nodes.AsyncFunctionDef), ): _get_functions(functions, node) diff --git a/pylint/checkers/stdlib.py b/pylint/checkers/stdlib.py index 5ff77ff83..95bec2e5d 100644 --- a/pylint/checkers/stdlib.py +++ b/pylint/checkers/stdlib.py @@ -41,6 +41,7 @@ import sys from collections.abc import Iterable import astroid +from astroid import nodes from pylint.checkers import BaseChecker, DeprecatedMixin, utils from pylint.interfaces import IAstroidChecker @@ -513,25 +514,25 @@ class StdlibChecker(DeprecatedMixin, BaseChecker): continue if inferred.root().name == OPEN_MODULE: if ( - isinstance(node.func, astroid.Name) + isinstance(node.func, nodes.Name) and node.func.name in OPEN_FILES_MODE ): self._check_open_mode(node) if ( - isinstance(node.func, astroid.Name) + isinstance(node.func, nodes.Name) and node.func.name in OPEN_FILES_ENCODING - or isinstance(node.func, astroid.Attribute) + or isinstance(node.func, nodes.Attribute) and node.func.attrname in OPEN_FILES_ENCODING ): self._check_open_encoded(node) elif inferred.root().name == UNITTEST_CASE: self._check_redundant_assert(node, inferred) - elif isinstance(inferred, astroid.ClassDef): + elif isinstance(inferred, nodes.ClassDef): if inferred.qname() == THREADING_THREAD: self._check_bad_thread_instantiation(node) elif inferred.qname() == SUBPROCESS_POPEN: self._check_for_preexec_fn_in_popen(node) - elif isinstance(inferred, astroid.FunctionDef): + elif isinstance(inferred, nodes.FunctionDef): name = inferred.qname() if name == COPY_COPY: self._check_shallow_copy_environ(node) @@ -567,7 +568,7 @@ class StdlibChecker(DeprecatedMixin, BaseChecker): if ( isinstance(infer, astroid.BoundMethod) and node.args - and isinstance(node.args[0], astroid.Const) + and isinstance(node.args[0], nodes.Const) and infer.name in ["assertTrue", "assertFalse"] ): self.add_message( @@ -598,12 +599,12 @@ class StdlibChecker(DeprecatedMixin, BaseChecker): return if mode_arg: mode_arg = utils.safe_infer(mode_arg) - if isinstance(mode_arg, astroid.Const) and not _check_mode_str( + if isinstance(mode_arg, nodes.Const) and not _check_mode_str( mode_arg.value ): self.add_message("bad-open-mode", node=node, args=mode_arg.value) - def _check_open_encoded(self, node: astroid.Call) -> None: + def _check_open_encoded(self, node: nodes.Call) -> None: """Check that the encoded argument of an open call is valid.""" mode_arg = None try: @@ -625,10 +626,7 @@ class StdlibChecker(DeprecatedMixin, BaseChecker): if encoding_arg: encoding_arg = utils.safe_infer(encoding_arg) - if ( - isinstance(encoding_arg, astroid.Const) - and encoding_arg.value is None - ): + if isinstance(encoding_arg, nodes.Const) and encoding_arg.value is None: self.add_message("unspecified-encoding", node=node) def _check_env_function(self, node, infer): @@ -675,7 +673,7 @@ class StdlibChecker(DeprecatedMixin, BaseChecker): return name = infer.qname() - if isinstance(call_arg, astroid.Const): + if isinstance(call_arg, nodes.Const): emit = False if call_arg.value is None: emit = not allow_none diff --git a/pylint/checkers/strings.py b/pylint/checkers/strings.py index 4058a2687..a0eb9b269 100644 --- a/pylint/checkers/strings.py +++ b/pylint/checkers/strings.py @@ -41,6 +41,7 @@ import tokenize from typing import TYPE_CHECKING, Iterable import astroid +from astroid import nodes from pylint.checkers import BaseChecker, BaseTokenChecker, utils from pylint.checkers.utils import check_messages @@ -213,13 +214,13 @@ MSGS = { # pylint: disable=consider-using-namedtuple-or-dataclass } OTHER_NODES = ( - astroid.Const, - astroid.List, - astroid.Lambda, - astroid.FunctionDef, - astroid.ListComp, - astroid.SetComp, - astroid.GeneratorExp, + nodes.Const, + nodes.List, + nodes.Lambda, + nodes.FunctionDef, + nodes.ListComp, + nodes.SetComp, + nodes.GeneratorExp, ) BUILTINS_STR = BUILTINS + ".str" @@ -287,7 +288,7 @@ class StringFormatChecker(BaseChecker): left = node.left args = node.right - if not (isinstance(left, astroid.Const) and isinstance(left.value, str)): + if not (isinstance(left, nodes.Const) and isinstance(left.value, str)): return format_string = left.value try: @@ -320,11 +321,11 @@ class StringFormatChecker(BaseChecker): # Check that the RHS of the % operator is a mapping object # that contains precisely the set of keys required by the # format string. - if isinstance(args, astroid.Dict): + if isinstance(args, nodes.Dict): keys = set() unknown_keys = False for k, _ in args.items: - if isinstance(k, astroid.Const): + if isinstance(k, nodes.Const): key = k.value if isinstance(key, str): keys.add(key) @@ -350,7 +351,7 @@ class StringFormatChecker(BaseChecker): "unused-format-string-key", node=node, args=key ) for key, arg in args.items: - if not isinstance(key, astroid.Const): + if not isinstance(key, nodes.Const): continue format_type = required_key_types.get(key.value, None) arg_type = utils.safe_infer(arg) @@ -364,7 +365,7 @@ class StringFormatChecker(BaseChecker): node=node, args=(arg_type.pytype(), format_type), ) - elif isinstance(args, (OTHER_NODES, astroid.Tuple)): + elif isinstance(args, (OTHER_NODES, nodes.Tuple)): type_name = type(args).__name__ self.add_message("format-needs-mapping", node=node, args=type_name) # else: @@ -377,13 +378,13 @@ class StringFormatChecker(BaseChecker): # the % operator matches the number required by the format # string. args_elts = () - if isinstance(args, astroid.Tuple): + if isinstance(args, nodes.Tuple): rhs_tuple = utils.safe_infer(args) num_args = None if hasattr(rhs_tuple, "elts"): args_elts = rhs_tuple.elts num_args = len(args_elts) - elif isinstance(args, (OTHER_NODES, (astroid.Dict, astroid.DictComp))): + elif isinstance(args, (OTHER_NODES, (nodes.Dict, nodes.DictComp))): args_elts = [args] num_args = 1 else: @@ -416,10 +417,10 @@ class StringFormatChecker(BaseChecker): @check_messages("f-string-without-interpolation") def visit_joinedstr(self, node): - if isinstance(node.parent, astroid.FormattedValue): + if isinstance(node.parent, nodes.FormattedValue): return for value in node.values: - if isinstance(value, astroid.FormattedValue): + if isinstance(value, nodes.FormattedValue): return self.add_message("f-string-without-interpolation", node=node) @@ -433,7 +434,7 @@ class StringFormatChecker(BaseChecker): ): if func.name in ("strip", "lstrip", "rstrip") and node.args: arg = utils.safe_infer(node.args[0]) - if not isinstance(arg, astroid.Const) or not isinstance(arg.value, str): + if not isinstance(arg, nodes.Const) or not isinstance(arg.value, str): return if len(arg.value) != len(set(arg.value)): self.add_message( @@ -446,7 +447,7 @@ class StringFormatChecker(BaseChecker): def _detect_vacuous_formatting(self, node, positional_arguments): counter = collections.Counter( - arg.name for arg in positional_arguments if isinstance(arg, astroid.Name) + arg.name for arg in positional_arguments if isinstance(arg, nodes.Name) ) for name, count in counter.items(): if count == 1: @@ -466,8 +467,8 @@ class StringFormatChecker(BaseChecker): # # fmt = 'some string {}'.format # fmt('arg') - if isinstance(node.func, astroid.Attribute) and not isinstance( - node.func.expr, astroid.Const + if isinstance(node.func, nodes.Attribute) and not isinstance( + node.func.expr, nodes.Const ): return if node.starargs or node.kwargs: @@ -476,7 +477,7 @@ class StringFormatChecker(BaseChecker): strnode = next(func.bound.infer()) except astroid.InferenceError: return - if not (isinstance(strnode, astroid.Const) and isinstance(strnode.value, str)): + if not (isinstance(strnode, nodes.Const) and isinstance(strnode.value, str)): return try: call_site = astroid.arguments.CallSite.from_call(node) @@ -571,7 +572,7 @@ class StringFormatChecker(BaseChecker): # No need to check this key if it doesn't # use attribute / item access continue - if argument.parent and isinstance(argument.parent, astroid.Arguments): + if argument.parent and isinstance(argument.parent, nodes.Arguments): # Ignore any object coming from an argument, # because we can't infer its value properly. continue @@ -602,7 +603,7 @@ class StringFormatChecker(BaseChecker): warn_error = False if hasattr(previous, "getitem"): try: - previous = previous.getitem(astroid.Const(specifier)) + previous = previous.getitem(nodes.Const(specifier)) except ( astroid.AstroidIndexError, astroid.AstroidTypeError, @@ -759,7 +760,7 @@ class StringConstantChecker(BaseTokenChecker): self.check_for_concatenated_strings(node.elts, "tuple") def visit_assign(self, node): - if isinstance(node.value, astroid.Const) and isinstance(node.value.value, str): + if isinstance(node.value, nodes.Const) and isinstance(node.value.value, str): self.check_for_concatenated_strings([node.value], "assignment") def check_for_consistent_string_delimiters( @@ -800,7 +801,7 @@ class StringConstantChecker(BaseTokenChecker): def check_for_concatenated_strings(self, elements, iterable_type): for elt in elements: if not ( - isinstance(elt, astroid.Const) and elt.pytype() in _AST_NODE_STR_TYPES + isinstance(elt, nodes.Const) and elt.pytype() in _AST_NODE_STR_TYPES ): continue if elt.col_offset < 0: @@ -913,13 +914,13 @@ class StringConstantChecker(BaseTokenChecker): index += 2 @check_messages("redundant-u-string-prefix") - def visit_const(self, node: astroid.Const): + def visit_const(self, node: nodes.Const): if node.pytype() == "builtins.str" and not isinstance( - node.parent, astroid.JoinedStr + node.parent, nodes.JoinedStr ): self._detect_u_string_prefix(node) - def _detect_u_string_prefix(self, node: astroid.Const): + def _detect_u_string_prefix(self, node: nodes.Const): """Check whether strings include a 'u' prefix like u'String'""" if node.kind == "u": self.add_message( diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 3291393a4..502a0390c 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -69,6 +69,7 @@ from functools import singledispatch from typing import Pattern, Tuple import astroid +from astroid import nodes from pylint.checkers import BaseChecker, utils from pylint.checkers.utils import ( @@ -100,9 +101,9 @@ STR_FORMAT = {"%s.str.format" % BUILTINS} ASYNCIO_COROUTINE = "asyncio.coroutines.coroutine" BUILTIN_TUPLE = "builtins.tuple" TYPE_ANNOTATION_NODES_TYPES = ( - astroid.AnnAssign, - astroid.Arguments, - astroid.FunctionDef, + nodes.AnnAssign, + nodes.Arguments, + nodes.FunctionDef, ) @@ -179,7 +180,7 @@ def _node_names(node): return node.locals.keys() -@_node_names.register(astroid.ClassDef) +@_node_names.register(nodes.ClassDef) @_node_names.register(astroid.Instance) def _(node): values = itertools.chain(node.instance_attrs.keys(), node.locals.keys()) @@ -459,17 +460,17 @@ def _emit_no_member(node, owner, owner_name, ignored_mixins=True, ignored_none=T # pylint: disable=too-many-return-statements if node_ignores_exception(node, AttributeError): return False - if ignored_none and isinstance(owner, astroid.Const) and owner.value is None: + if ignored_none and isinstance(owner, nodes.Const) and owner.value is None: return False if is_super(owner) or getattr(owner, "type", None) == "metaclass": return False if owner_name and ignored_mixins and owner_name[-5:].lower() == "mixin": return False - if isinstance(owner, astroid.FunctionDef) and ( + if isinstance(owner, nodes.FunctionDef) and ( owner.decorators or owner.is_abstract() ): return False - if isinstance(owner, (astroid.Instance, astroid.ClassDef)): + if isinstance(owner, (astroid.Instance, nodes.ClassDef)): if owner.has_dynamic_getattr(): # Issue #2565: Don't ignore enums, as they have a `__getattr__` but it's not # invoked at this point. @@ -499,7 +500,7 @@ def _emit_no_member(node, owner, owner_name, ignored_mixins=True, ignored_none=T return False if not all(has_known_bases(base) for base in owner.type.mro()): return False - if isinstance(owner, astroid.Module): + if isinstance(owner, nodes.Module): try: owner.getattr("__getattr__") return False @@ -515,7 +516,7 @@ def _emit_no_member(node, owner, owner_name, ignored_mixins=True, ignored_none=T return True if ( owner.parent - and isinstance(owner.parent, astroid.ClassDef) + and isinstance(owner.parent, nodes.ClassDef) and owner.parent.name == "EnumMeta" and owner_name == "__members__" and node.attrname in ["items", "values", "keys"] @@ -529,19 +530,19 @@ def _emit_no_member(node, owner, owner_name, ignored_mixins=True, ignored_none=T # would evaluate as `False`, # and wheater the node is part of the `body`. # * Continue checking until scope of node is reached. - scope: astroid.NodeNG = node.scope() - node_origin: astroid.NodeNG = node - parent: astroid.NodeNG = node.parent + scope: nodes.NodeNG = node.scope() + node_origin: nodes.NodeNG = node + parent: nodes.NodeNG = node.parent while parent != scope: - if isinstance(parent, (astroid.If, astroid.IfExp)): + if isinstance(parent, (nodes.If, nodes.IfExp)): inferred = safe_infer(parent.test) if ( # pylint: disable=too-many-boolean-expressions - isinstance(inferred, astroid.Const) + isinstance(inferred, nodes.Const) and inferred.bool_value() is False and ( - isinstance(parent, astroid.If) + isinstance(parent, nodes.If) and node_origin in parent.body - or isinstance(parent, astroid.IfExp) + or isinstance(parent, nodes.IfExp) and node_origin == parent.body ) ): @@ -562,11 +563,11 @@ def _determine_callable(callable_obj): return callable_obj, parameters, callable_obj.type if isinstance(callable_obj, astroid.UnboundMethod): return callable_obj, parameters, "unbound method" - if isinstance(callable_obj, astroid.FunctionDef): + if isinstance(callable_obj, nodes.FunctionDef): return callable_obj, parameters, callable_obj.type - if isinstance(callable_obj, astroid.Lambda): + if isinstance(callable_obj, nodes.Lambda): return callable_obj, parameters, "lambda" - if isinstance(callable_obj, astroid.ClassDef): + if isinstance(callable_obj, nodes.ClassDef): # Class instantiation, lookup __new__ instead. # If we only find object.__new__, we can safely check __init__ # instead. If __new__ belongs to builtins, then we look @@ -591,7 +592,7 @@ def _determine_callable(callable_obj): else: callable_obj = new - if not isinstance(callable_obj, astroid.FunctionDef): + if not isinstance(callable_obj, nodes.FunctionDef): raise ValueError # both have an extra implicit 'cls'/'self' argument. return callable_obj, parameters, "constructor" @@ -611,30 +612,30 @@ def _no_context_variadic_keywords(node, scope): statement = node.statement() variadics = () - if isinstance(scope, astroid.Lambda) and not isinstance(scope, astroid.FunctionDef): + if isinstance(scope, nodes.Lambda) and not isinstance(scope, nodes.FunctionDef): variadics = list(node.keywords or []) + node.kwargs - elif isinstance( - statement, (astroid.Return, astroid.Expr, astroid.Assign) - ) and isinstance(statement.value, astroid.Call): + elif isinstance(statement, (nodes.Return, nodes.Expr, nodes.Assign)) and isinstance( + statement.value, nodes.Call + ): call = statement.value variadics = list(call.keywords or []) + call.kwargs - return _no_context_variadic(node, scope.args.kwarg, astroid.Keyword, variadics) + return _no_context_variadic(node, scope.args.kwarg, nodes.Keyword, variadics) def _no_context_variadic_positional(node, scope): variadics = () - if isinstance(scope, astroid.Lambda) and not isinstance(scope, astroid.FunctionDef): + if isinstance(scope, nodes.Lambda) and not isinstance(scope, nodes.FunctionDef): variadics = node.starargs + node.kwargs else: statement = node.statement() if isinstance( - statement, (astroid.Expr, astroid.Return, astroid.Assign) - ) and isinstance(statement.value, astroid.Call): + statement, (nodes.Expr, nodes.Return, nodes.Assign) + ) and isinstance(statement.value, nodes.Call): call = statement.value variadics = call.starargs + call.kwargs - return _no_context_variadic(node, scope.args.vararg, astroid.Starred, variadics) + return _no_context_variadic(node, scope.args.vararg, nodes.Starred, variadics) def _no_context_variadic(node, variadic_name, variadic_type, variadics): @@ -649,30 +650,30 @@ def _no_context_variadic(node, variadic_name, variadic_type, variadics): too few arguments. """ scope = node.scope() - is_in_lambda_scope = not isinstance(scope, astroid.FunctionDef) and isinstance( - scope, astroid.Lambda + is_in_lambda_scope = not isinstance(scope, nodes.FunctionDef) and isinstance( + scope, nodes.Lambda ) statement = node.statement() - for name in statement.nodes_of_class(astroid.Name): + for name in statement.nodes_of_class(nodes.Name): if name.name != variadic_name: continue inferred = safe_infer(name) - if isinstance(inferred, (astroid.List, astroid.Tuple)): + if isinstance(inferred, (nodes.List, nodes.Tuple)): length = len(inferred.elts) - elif isinstance(inferred, astroid.Dict): + elif isinstance(inferred, nodes.Dict): length = len(inferred.items) else: continue - if is_in_lambda_scope and isinstance(inferred.parent, astroid.Arguments): + if is_in_lambda_scope and isinstance(inferred.parent, nodes.Arguments): # The statement of the variadic will be the assignment itself, # so we need to go the lambda instead inferred_statement = inferred.parent.parent else: inferred_statement = inferred.statement() - if not length and isinstance(inferred_statement, astroid.Lambda): + if not length and isinstance(inferred_statement, nodes.Lambda): is_in_starred_context = _has_parent_of_type(node, variadic_type, statement) used_as_starred_argument = any( variadic.value == name or variadic.value.parent_of(name) @@ -695,7 +696,7 @@ def _is_invalid_metaclass(metaclass): return False -def _infer_from_metaclass_constructor(cls, func): +def _infer_from_metaclass_constructor(cls, func: nodes.FunctionDef): """Try to infer what the given *func* constructor is building :param astroid.FunctionDef func: @@ -714,14 +715,14 @@ def _infer_from_metaclass_constructor(cls, func): """ context = astroid.context.InferenceContext() - class_bases = astroid.List() + class_bases = nodes.List() class_bases.postinit(elts=cls.bases) - attrs = astroid.Dict() + attrs = nodes.Dict() local_names = [(name, values[-1]) for name, values in cls.locals.items()] attrs.postinit(local_names) - builder_args = astroid.Tuple() + builder_args = nodes.Tuple() builder_args.postinit([cls.name, class_bases, attrs]) context.callcontext = astroid.context.CallContext(builder_args) @@ -745,9 +746,9 @@ def _is_invalid_isinstance_type(arg): if not inferred: # Cannot infer it so skip it. return False - if isinstance(inferred, astroid.Tuple): + if isinstance(inferred, nodes.Tuple): return any(_is_invalid_isinstance_type(elt) for elt in inferred.elts) - if isinstance(inferred, astroid.ClassDef): + if isinstance(inferred, nodes.ClassDef): return False if isinstance(inferred, astroid.Instance) and inferred.qname() == BUILTIN_TUPLE: return False @@ -926,7 +927,7 @@ accessed. Python regular expressions are accepted.", @check_messages("invalid-metaclass") def visit_classdef(self, node): def _metaclass_name(metaclass): - if isinstance(metaclass, (astroid.ClassDef, astroid.FunctionDef)): + if isinstance(metaclass, (nodes.ClassDef, nodes.FunctionDef)): return metaclass.name return metaclass.as_string() @@ -934,14 +935,14 @@ accessed. Python regular expressions are accepted.", if not metaclass: return - if isinstance(metaclass, astroid.FunctionDef): + if isinstance(metaclass, nodes.FunctionDef): # Try to infer the result. metaclass = _infer_from_metaclass_constructor(node, metaclass) if not metaclass: # Don't do anything if we cannot infer the result. return - if isinstance(metaclass, astroid.ClassDef): + if isinstance(metaclass, nodes.ClassDef): if _is_invalid_metaclass(metaclass): self.add_message( "invalid-metaclass", node=node, args=(_metaclass_name(metaclass),) @@ -952,7 +953,7 @@ accessed. Python regular expressions are accepted.", ) def visit_assignattr(self, node): - if isinstance(node.assign_type(), astroid.AugAssign): + if isinstance(node.assign_type(), nodes.AugAssign): self.visit_attribute(node) def visit_delattr(self, node): @@ -985,8 +986,7 @@ accessed. Python regular expressions are accepted.", non_opaque_inference_results = [ owner for owner in inferred - if owner is not astroid.Uninferable - and not isinstance(owner, astroid.nodes.Unknown) + if owner is not astroid.Uninferable and not isinstance(owner, nodes.Unknown) ] if ( len(non_opaque_inference_results) != len(inferred) @@ -1013,7 +1013,7 @@ accessed. Python regular expressions are accepted.", if not [ n for n in owner.getattr(node.attrname) - if not isinstance(n.statement(), astroid.AugAssign) + if not isinstance(n.statement(), nodes.AugAssign) ]: missingattr.add((owner, name)) continue @@ -1064,7 +1064,7 @@ accessed. Python regular expressions are accepted.", def _get_nomember_msgid_hint(self, node, owner): suggestions_are_possible = self._suggestion_mode and isinstance( - owner, astroid.Module + owner, nodes.Module ) if suggestions_are_possible and _is_c_extension(owner): msg = "c-extension-no-member" @@ -1099,11 +1099,11 @@ accessed. Python regular expressions are accepted.", """check that if assigning to a function call, the function is possibly returning something valuable """ - if not isinstance(node.value, astroid.Call): + if not isinstance(node.value, nodes.Call): return function_node = safe_infer(node.value.func) - funcs = (astroid.FunctionDef, astroid.UnboundMethod, astroid.BoundMethod) + funcs = (nodes.FunctionDef, astroid.UnboundMethod, astroid.BoundMethod) if not isinstance(function_node, funcs): return @@ -1118,7 +1118,7 @@ accessed. Python regular expressions are accepted.", # pylint: disable=too-many-boolean-expressions if ( not function_node.is_function - or isinstance(function_node, astroid.AsyncFunctionDef) + or isinstance(function_node, nodes.AsyncFunctionDef) or function_node.decorators or function_node.is_generator() or function_node.is_abstract(pass_is_abstract=False) @@ -1128,14 +1128,14 @@ accessed. Python regular expressions are accepted.", return returns = list( - function_node.nodes_of_class(astroid.Return, skip_klass=astroid.FunctionDef) + function_node.nodes_of_class(nodes.Return, skip_klass=nodes.FunctionDef) ) if not returns: self.add_message("assignment-from-no-return", node=node) else: for rnode in returns: if not ( - isinstance(rnode.value, astroid.Const) + isinstance(rnode.value, nodes.Const) and rnode.value.value is None or rnode.value is None ): @@ -1150,21 +1150,19 @@ accessed. Python regular expressions are accepted.", # Check the left hand side of the assignment is <something>.__name__ lhs = node.targets[0] - if not isinstance(lhs, astroid.node_classes.AssignAttr): + if not isinstance(lhs, nodes.AssignAttr): return if not lhs.attrname == "__name__": return # If the right hand side is not a string rhs = node.value - if isinstance(rhs, astroid.Const) and isinstance(rhs.value, str): + if isinstance(rhs, nodes.Const) and isinstance(rhs.value, str): return inferred = utils.safe_infer(rhs) if not inferred: return - if not ( - isinstance(inferred, astroid.Const) and isinstance(inferred.value, str) - ): + if not (isinstance(inferred, nodes.Const) and isinstance(inferred.value, str)): # Add the message self.add_message("non-str-assignment-to-dunder-name", node=node) @@ -1173,7 +1171,7 @@ accessed. Python regular expressions are accepted.", Check that the given uninferable Call node does not call an actual function. """ - if not isinstance(node.func, astroid.Attribute): + if not isinstance(node.func, nodes.Attribute): return # Look for properties. First, obtain @@ -1198,7 +1196,7 @@ accessed. Python regular expressions are accepted.", for attr in attrs: if attr is astroid.Uninferable: continue - if not isinstance(attr, astroid.FunctionDef): + if not isinstance(attr, nodes.FunctionDef): continue # Decorated, see if it is decorated with a property. @@ -1227,7 +1225,7 @@ accessed. Python regular expressions are accepted.", # Check for called function being an object instance function # If so, ignore the initial 'self' argument in the signature try: - is_classdef = isinstance(called.parent, astroid.scoped_nodes.ClassDef) + is_classdef = isinstance(called.parent, nodes.ClassDef) if is_classdef and called_param_names[0] == "self": called_param_names = called_param_names[1:] except IndexError: @@ -1283,7 +1281,7 @@ accessed. Python regular expressions are accepted.", not has_known_bases(called) or ( called.parent is not None - and isinstance(called.scope(), astroid.ClassDef) + and isinstance(called.scope(), nodes.ClassDef) and "__get__" in called.locals ) ): @@ -1336,7 +1334,7 @@ accessed. Python regular expressions are accepted.", # Determine if we don't have a context for our call and we use variadics. node_scope = node.scope() - if isinstance(node_scope, (astroid.Lambda, astroid.FunctionDef)): + if isinstance(node_scope, (nodes.Lambda, nodes.FunctionDef)): has_no_context_positional_variadic = _no_context_variadic_positional( node, node_scope ) @@ -1361,12 +1359,12 @@ accessed. Python regular expressions are accepted.", parameters = [] parameter_name_to_index = {} for i, arg in enumerate(args): - if isinstance(arg, astroid.Tuple): + if isinstance(arg, nodes.Tuple): name = None # Don't store any parameter names within the tuple, since those # are not assignable from keyword arguments. else: - assert isinstance(arg, astroid.AssignName) + assert isinstance(arg, nodes.AssignName) # This occurs with: # def f( (a), (b) ): pass name = arg.name @@ -1379,10 +1377,10 @@ accessed. Python regular expressions are accepted.", kwparams = {} for i, arg in enumerate(called.args.kwonlyargs): - if isinstance(arg, astroid.Keyword): + if isinstance(arg, nodes.Keyword): name = arg.arg else: - assert isinstance(arg, astroid.AssignName) + assert isinstance(arg, nodes.AssignName) name = arg.name kwparams[name] = [called.args.kw_defaults[i], False] @@ -1480,13 +1478,13 @@ accessed. Python regular expressions are accepted.", ): self.add_message("missing-kwoa", node=node, args=(name, callable_name)) - def _check_invalid_sequence_index(self, subscript: astroid.Subscript): + def _check_invalid_sequence_index(self, subscript: nodes.Subscript): # Look for index operations where the parent is a sequence type. # If the types can be determined, only allow indices to be int, # slice or instances with __index__. parent_type = safe_infer(subscript.value) if not isinstance( - parent_type, (astroid.ClassDef, astroid.Instance) + parent_type, (nodes.ClassDef, astroid.Instance) ) or not has_known_bases(parent_type): return None @@ -1515,7 +1513,7 @@ accessed. Python regular expressions are accepted.", ): return None if ( - not isinstance(itemmethod, astroid.FunctionDef) + not isinstance(itemmethod, nodes.FunctionDef) or itemmethod.root().name != BUILTINS or not itemmethod.parent or itemmethod.parent.name not in SEQUENCE_TYPES @@ -1525,14 +1523,14 @@ accessed. Python regular expressions are accepted.", # For ExtSlice objects coming from visit_extslice, no further # inference is necessary, since if we got this far the ExtSlice # is an error. - if isinstance(subscript.value, astroid.ExtSlice): + if isinstance(subscript.value, nodes.ExtSlice): index_type = subscript.value else: index_type = safe_infer(subscript.slice) if index_type is None or index_type is astroid.Uninferable: return None # Constants must be of type int - if isinstance(index_type, astroid.Const): + if isinstance(index_type, nodes.Const): if isinstance(index_type.value, int): return None # Instance values must be int, slice, or have an __index__ method @@ -1544,7 +1542,7 @@ accessed. Python regular expressions are accepted.", return None except astroid.NotFoundError: pass - elif isinstance(index_type, astroid.Slice): + elif isinstance(index_type, nodes.Slice): # A slice can be present # here after inferring the index node, which could # be a `slice(...)` call for instance. @@ -1574,7 +1572,7 @@ accessed. Python regular expressions are accepted.", continue # Constants must of type int or None - if isinstance(index_type, astroid.Const): + if isinstance(index_type, nodes.Const): if isinstance(index_type.value, (int, type(None))): continue # Instance values must be of type int, None or an object @@ -1596,19 +1594,19 @@ accessed. Python regular expressions are accepted.", # Anything else is an error, unless the object that is indexed # is a custom object, which knows how to handle this kind of slices parent = node.parent - if isinstance(parent, astroid.ExtSlice): + if isinstance(parent, nodes.ExtSlice): parent = parent.parent - if isinstance(parent, astroid.Subscript): + if isinstance(parent, nodes.Subscript): inferred = safe_infer(parent.value) if inferred is None or inferred is astroid.Uninferable: # Don't know what this is return known_objects = ( - astroid.List, - astroid.Dict, - astroid.Tuple, + nodes.List, + nodes.Dict, + nodes.Tuple, astroid.objects.FrozenSet, - astroid.Set, + nodes.Set, ) if not isinstance(inferred, known_objects): # Might be an instance that knows how to handle this slice object @@ -1651,7 +1649,7 @@ accessed. Python regular expressions are accepted.", if not inferred_path: continue scope = inferred_path.scope() - if not isinstance(scope, astroid.FunctionDef): + if not isinstance(scope, nodes.FunctionDef): continue if decorated_with(scope, self.config.contextmanager_decorators): break @@ -1687,11 +1685,11 @@ accessed. Python regular expressions are accepted.", self.add_message("invalid-unary-operand-type", args=str(error), node=node) @check_messages("unsupported-binary-operation") - def visit_binop(self, node: astroid.BinOp): + def visit_binop(self, node: nodes.BinOp): if node.op == "|": self._detect_unsupported_alternative_union_syntax(node) - def _detect_unsupported_alternative_union_syntax(self, node: astroid.BinOp) -> None: + def _detect_unsupported_alternative_union_syntax(self, node: nodes.BinOp) -> None: """Detect if unsupported alternative Union syntax (PEP 604) was used.""" if PY310_PLUS: # 310+ supports the new syntax return @@ -1706,14 +1704,14 @@ accessed. Python regular expressions are accepted.", if isinstance( node.parent, ( - astroid.Assign, - astroid.Call, - astroid.Keyword, - astroid.Dict, - astroid.Tuple, - astroid.Set, - astroid.List, - astroid.BinOp, + nodes.Assign, + nodes.Call, + nodes.Keyword, + nodes.Dict, + nodes.Tuple, + nodes.Set, + nodes.List, + nodes.BinOp, ), ): # Check other contexts the syntax might appear, but are invalid. @@ -1727,17 +1725,17 @@ accessed. Python regular expressions are accepted.", allowed_nested_syntax = True break parent_node = parent_node.parent - if isinstance(parent_node, astroid.Module): + if isinstance(parent_node, nodes.Module): break if not allowed_nested_syntax: self._check_unsupported_alternative_union_syntax(node) - def _check_unsupported_alternative_union_syntax(self, node: astroid.BinOp) -> None: + def _check_unsupported_alternative_union_syntax(self, node: nodes.BinOp) -> None: """Check if left or right node is of type `type`.""" msg = "unsupported operand type(s) for |" for n in (node.left, node.right): n = astroid.helpers.object_type(n) - if isinstance(n, astroid.ClassDef) and is_classdef_type(n): + if isinstance(n, nodes.ClassDef) and is_classdef_type(n): self.add_message("unsupported-binary-operation", args=msg, node=node) break @@ -1755,7 +1753,7 @@ accessed. Python regular expressions are accepted.", for error in node.type_errors(): # Let the error customize its output. if any( - isinstance(obj, astroid.ClassDef) and not has_known_bases(obj) + isinstance(obj, nodes.ClassDef) and not has_known_bases(obj) for obj in (error.left_type, error.right_type) ): continue @@ -1795,10 +1793,10 @@ accessed. Python regular expressions are accepted.", self._check_invalid_sequence_index(node) supported_protocol = None - if isinstance(node.value, (astroid.ListComp, astroid.DictComp)): + if isinstance(node.value, (nodes.ListComp, nodes.DictComp)): return - if isinstance(node.value, astroid.Dict): + if isinstance(node.value, nodes.Dict): # Assert dict key is hashable inferred = safe_infer(node.slice) if inferred not in (None, astroid.Uninferable): @@ -1820,7 +1818,7 @@ accessed. Python regular expressions are accepted.", supported_protocol = supports_delitem msg = "unsupported-delete-operation" - if isinstance(node.value, astroid.SetComp): + if isinstance(node.value, nodes.SetComp): self.add_message(msg, args=node.value.as_string(), node=node.value) return @@ -1834,7 +1832,7 @@ accessed. Python regular expressions are accepted.", if getattr(inferred, "decorators", None): first_decorator = astroid.helpers.safe_infer(inferred.decorators.nodes[0]) - if isinstance(first_decorator, astroid.ClassDef): + if isinstance(first_decorator, nodes.ClassDef): inferred = first_decorator.instantiate_class() else: return # It would be better to handle function @@ -1845,7 +1843,7 @@ accessed. Python regular expressions are accepted.", @check_messages("dict-items-missing-iter") def visit_for(self, node): - if not isinstance(node.target, astroid.node_classes.Tuple): + if not isinstance(node.target, nodes.Tuple): # target is not a tuple return if not len(node.target.elts) == 2: @@ -1853,14 +1851,14 @@ accessed. Python regular expressions are accepted.", return iterable = node.iter - if not isinstance(iterable, astroid.node_classes.Name): + if not isinstance(iterable, nodes.Name): # it's not a bare variable return inferred = safe_infer(iterable) if not inferred: return - if not isinstance(inferred, astroid.node_classes.Dict): + if not isinstance(inferred, nodes.Dict): # the iterable is not a dict return @@ -1899,17 +1897,17 @@ class IterableChecker(BaseChecker): @staticmethod def _is_asyncio_coroutine(node): - if not isinstance(node, astroid.Call): + if not isinstance(node, nodes.Call): return False inferred_func = safe_infer(node.func) - if not isinstance(inferred_func, astroid.FunctionDef): + if not isinstance(inferred_func, nodes.FunctionDef): return False if not inferred_func.decorators: return False for decorator in inferred_func.decorators.nodes: inferred_decorator = safe_infer(decorator) - if not isinstance(inferred_decorator, astroid.FunctionDef): + if not isinstance(inferred_decorator, nodes.FunctionDef): continue if inferred_decorator.qname() != ASYNCIO_COROUTINE: continue @@ -1928,7 +1926,7 @@ class IterableChecker(BaseChecker): def _check_mapping(self, node): if is_inside_abstract_class(node): return - if isinstance(node, astroid.DictComp): + if isinstance(node, nodes.DictComp): return inferred = safe_infer(node) if inferred is None or inferred is astroid.Uninferable: @@ -1978,15 +1976,15 @@ class IterableChecker(BaseChecker): self._check_iterable(gen.iter, check_async=gen.is_async) @check_messages("await-outside-async") - def visit_await(self, node: astroid.Await) -> None: + def visit_await(self, node: nodes.Await) -> None: self._check_await_outside_coroutine(node) - def _check_await_outside_coroutine(self, node: astroid.Await) -> None: + def _check_await_outside_coroutine(self, node: nodes.Await) -> None: node_scope = node.scope() - while not isinstance(node_scope, astroid.Module): - if isinstance(node_scope, astroid.AsyncFunctionDef): + while not isinstance(node_scope, nodes.Module): + if isinstance(node_scope, nodes.AsyncFunctionDef): return - if isinstance(node_scope, astroid.FunctionDef): + if isinstance(node_scope, nodes.FunctionDef): break node_scope = node_scope.parent.scope() self.add_message("await-outside-async", node=node) |