Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor various typing related issues #4940

Merged
merged 21 commits into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5a1e21d
Add type annotations to ``visit`` & ``leave`` calls
DanielNoord Aug 31, 2021
c81f02f
Fix outstanding mypy issues
DanielNoord Aug 31, 2021
8ea6f70
Fix remaining references to node_classes
DanielNoord Aug 31, 2021
7d2062c
Update typing and mypy configuration
DanielNoord Aug 31, 2021
3fe7bc4
Fix cyclic import in `deprecated.py`
DanielNoord Aug 31, 2021
6bbf2b3
Apply suggestions from code review
DanielNoord Aug 31, 2021
c004d75
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 31, 2021
596fc28
Apply suggestions from code review
DanielNoord Aug 31, 2021
c45ac73
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 31, 2021
1f2d7a7
Add changes from code review
DanielNoord Aug 31, 2021
3c31ed0
Additional typing
DanielNoord Aug 31, 2021
8dbb8fb
Merge branch 'main' of https://github.com/PyCQA/pylint into typing
DanielNoord Sep 1, 2021
8dd90cd
Apply suggestions from code review
DanielNoord Sep 1, 2021
4bf1c59
Merge branch 'main' into typing
DanielNoord Sep 1, 2021
3a47b64
Implement code review
DanielNoord Sep 1, 2021
49aa00c
Fix test
DanielNoord Sep 1, 2021
ce1aa3d
Reverse removal of ``visit_package``
DanielNoord Sep 1, 2021
c2299df
Merge branch 'main' into typing
DanielNoord Sep 2, 2021
1bfe966
Update import of ``objects.ExceptionInstance``
DanielNoord Sep 2, 2021
4e99175
Merge branch 'main' of https://github.com/PyCQA/pylint into typing
DanielNoord Sep 2, 2021
7aeb8c4
Merge branch 'typing' of https://github.com/DanielNoord/pylint into t…
DanielNoord Sep 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pylint/checkers/async.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ def open(self):
self._async_generators = ["contextlib.asynccontextmanager"]

@checker_utils.check_messages("yield-inside-async-function")
def visit_asyncfunctiondef(self, node):
def visit_asyncfunctiondef(self, node: nodes.AsyncFunctionDef) -> None:
for child in node.nodes_of_class(nodes.Yield):
if child.scope() is node and (
sys.version_info[:2] == (3, 5) or isinstance(child, nodes.YieldFrom)
):
self.add_message("yield-inside-async-function", node=child)

@checker_utils.check_messages("not-async-context-manager")
def visit_asyncwith(self, node):
def visit_asyncwith(self, node: nodes.AsyncWith) -> None:
for ctx_mgr, _ in node.items:
inferred = checker_utils.safe_infer(ctx_mgr)
if inferred is None or inferred is astroid.Uninferable:
Expand Down
110 changes: 58 additions & 52 deletions pylint/checkers/base.py

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions pylint/checkers/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ def _ignore_mixin(self):
"inconsistent-mro",
"duplicate-bases",
)
def visit_classdef(self, node):
def visit_classdef(self, node: nodes.ClassDef) -> None:
"""init visit variable _accessed"""
self._check_bases_classes(node)
# if not an exception or a metaclass
Expand Down Expand Up @@ -1092,7 +1092,7 @@ def _check_attribute_defined_outside_init(self, cnode: nodes.ClassDef) -> None:
"attribute-defined-outside-init", args=attr, node=node
)

def visit_functiondef(self, node):
def visit_functiondef(self, node: nodes.FunctionDef) -> None:
"""check method arguments, overriding"""
# ignore actual functions
if not node.is_method():
Expand Down Expand Up @@ -1400,7 +1400,7 @@ def _check_slots_elt(self, elt, node):
"class-variable-slots-conflict", args=(inferred.value,), node=elt
)

def leave_functiondef(self, node):
def leave_functiondef(self, node: nodes.FunctionDef) -> None:
"""on method node, check if this method couldn't be a function

ignore class, static and abstract methods, initializer,
Expand All @@ -1427,7 +1427,7 @@ def leave_functiondef(self, node):
):
self.add_message("no-self-use", node=node)

def visit_attribute(self, node):
def visit_attribute(self, node: nodes.Attribute) -> None:
"""check if the getattr is an access to a class member
if so, register it. Also check for access to protected
class member from outside its class (but ignore __special__
Expand Down Expand Up @@ -1514,7 +1514,7 @@ def _check_in_slots(self, node):
@check_messages(
"protected-access", "no-classmethod-decorator", "no-staticmethod-decorator"
)
def visit_assign(self, assign_node):
def visit_assign(self, assign_node: nodes.Assign) -> None:
self._check_classmethod_declaration(assign_node)
node = assign_node.targets[0]
if not isinstance(node, nodes.AssignAttr):
Expand Down Expand Up @@ -1701,7 +1701,7 @@ def _is_class_attribute(name, klass):
except astroid.NotFoundError:
return False

def visit_name(self, node):
def visit_name(self, node: nodes.Name) -> None:
"""check if the name handle an access to a class member
if so, register it
"""
Expand Down Expand Up @@ -2154,7 +2154,7 @@ def __init__(self, linter=None):
"invalid-getnewargs-returned",
"invalid-getnewargs-ex-returned",
)
def visit_functiondef(self, node):
def visit_functiondef(self, node: nodes.FunctionDef) -> None:
if not node.is_method():
return

Expand Down
10 changes: 5 additions & 5 deletions pylint/checkers/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import astroid
from astroid import nodes

from pylint.checkers import utils
from pylint.checkers import BaseChecker, utils
from pylint.checkers.utils import get_import_name, infer_all, safe_infer

ACCEPTABLE_NODES = (
Expand All @@ -19,7 +19,7 @@
)


class DeprecatedMixin:
class DeprecatedMixin(BaseChecker):
"""A mixin implementing logic for checking deprecated symbols.
A class implementing mixin must define "deprecated-method" Message.
"""
Expand Down Expand Up @@ -68,7 +68,7 @@ def visit_call(self, node: nodes.Call) -> None:
"deprecated-module",
"deprecated-class",
)
def visit_import(self, node):
def visit_import(self, node: nodes.Import) -> None:
"""triggered when an import statement is seen"""
for name in (name for name, _ in node.names):
self.check_deprecated_module(node, name)
Expand All @@ -87,7 +87,7 @@ def deprecated_decorators(self) -> Iterable:
return ()

@utils.check_messages("deprecated-decorator")
def visit_decorators(self, node):
def visit_decorators(self, node: nodes.Decorators) -> None:
"""Triggered when a decorator statement is seen"""
children = list(node.get_children())
if not children:
Expand All @@ -104,7 +104,7 @@ def visit_decorators(self, node):
"deprecated-module",
"deprecated-class",
)
def visit_importfrom(self, node):
def visit_importfrom(self, node: nodes.ImportFrom) -> None:
"""triggered when a from statement is seen"""
basename = node.modname
basename = get_import_name(node, basename)
Expand Down
22 changes: 11 additions & 11 deletions pylint/checkers/design_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ def _get_parents(
if parent.qname() in ignored_parents:
continue
parents.add(parent)
to_explore.extend(parent.ancestors(recurs=False)) # type: ignore
to_explore.extend(parent.ancestors(recurs=False))
return parents


Expand Down Expand Up @@ -417,7 +417,7 @@ def _ignored_argument_names(self):
"too-few-public-methods",
"too-many-public-methods",
)
def visit_classdef(self, node: nodes.ClassDef):
def visit_classdef(self, node: nodes.ClassDef) -> None:
"""check size of inheritance hierarchy and number of instance attributes"""
parents = _get_parents(
node, STDLIB_CLASSES_IGNORE_ANCESTOR.union(self.config.ignored_parents)
Expand All @@ -438,7 +438,7 @@ def visit_classdef(self, node: nodes.ClassDef):
)

@check_messages("too-few-public-methods", "too-many-public-methods")
def leave_classdef(self, node):
def leave_classdef(self, node: nodes.ClassDef) -> None:
"""check number of public methods"""
my_methods = sum(
1 for method in node.mymethods() if not method.name.startswith("_")
Expand Down Expand Up @@ -482,7 +482,7 @@ def leave_classdef(self, node):
"too-many-statements",
"keyword-arg-before-vararg",
)
def visit_functiondef(self, node):
def visit_functiondef(self, node: nodes.FunctionDef) -> None:
"""check function name, docstring, arguments, redefinition,
variable names, max locals
"""
Expand Down Expand Up @@ -525,7 +525,7 @@ def visit_functiondef(self, node):
"too-many-locals",
"too-many-statements",
)
def leave_functiondef(self, node):
def leave_functiondef(self, node: nodes.FunctionDef) -> None:
"""most of the work is done here on close:
checks for max returns, branch, return in __init__
"""
Expand Down Expand Up @@ -554,34 +554,34 @@ def leave_functiondef(self, node):

leave_asyncfunctiondef = leave_functiondef

def visit_return(self, _):
def visit_return(self, _) -> None:
DanielNoord marked this conversation as resolved.
Show resolved Hide resolved
"""count number of returns"""
if not self._returns:
return # return outside function, reported by the base checker
self._returns[-1] += 1

def visit_default(self, node):
def visit_default(self, node) -> None:
"""default visit method -> increments the statements counter if
necessary
"""
if node.is_statement:
self._inc_all_stmts(1)

def visit_tryexcept(self, node):
def visit_tryexcept(self, node: nodes.TryExcept) -> None:
"""increments the branches counter"""
branches = len(node.handlers)
if node.orelse:
branches += 1
self._inc_branch(node, branches)
self._inc_all_stmts(branches)

def visit_tryfinally(self, node):
def visit_tryfinally(self, node: nodes.TryFinally) -> None:
"""increments the branches counter"""
self._inc_branch(node, 2)
self._inc_all_stmts(2)

@check_messages("too-many-boolean-expressions")
def visit_if(self, node):
def visit_if(self, node: nodes.If) -> None:
"""increments the branches counter and checks boolean expressions"""
self._check_boolean_expressions(node)
branches = 1
Expand Down Expand Up @@ -609,7 +609,7 @@ def _check_boolean_expressions(self, node):
args=(nb_bool_expr, self.config.max_bool_expr),
)

def visit_while(self, node):
def visit_while(self, node: nodes.While) -> None:
"""increments the branches counter"""
branches = 1
if node.orelse:
Expand Down
26 changes: 13 additions & 13 deletions pylint/checkers/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,18 @@ def visit(self, node):
else:
self.visit_default(node)

def visit_default(self, node): # pylint: disable=unused-argument
def visit_default(self, node) -> None: # pylint: disable=unused-argument
"""Default implementation for all the nodes."""


class ExceptionRaiseRefVisitor(BaseVisitor):
"""Visit references (anything that is not an AST leaf)."""

def visit_name(self, name):
def visit_name(self, name: nodes.Name) -> None:
DanielNoord marked this conversation as resolved.
Show resolved Hide resolved
if name.name == "NotImplemented":
self._checker.add_message("notimplemented-raised", node=self._node)

def visit_call(self, call):
def visit_call(self, call: nodes.Call) -> None:
if isinstance(call.func, nodes.Name):
self.visit_name(call.func)
if (
Expand All @@ -228,30 +228,30 @@ def visit_call(self, call):
class ExceptionRaiseLeafVisitor(BaseVisitor):
"""Visitor for handling leaf kinds of a raise value."""

def visit_const(self, const):
def visit_const(self, const: nodes.Const) -> None:
if not isinstance(const.value, str):
# raising-string will be emitted from python3 porting checker.
self._checker.add_message(
"raising-bad-type", node=self._node, args=const.value.__class__.__name__
)

def visit_instance(self, instance):
def visit_instance(self, instance) -> None:
# pylint: disable=protected-access
cls = instance._proxied
self.visit_classdef(cls)

# Exception instances have a particular class type
visit_exceptioninstance = visit_instance

def visit_classdef(self, cls):
def visit_classdef(self, cls: nodes.ClassDef) -> None:
if not utils.inherit_from_std_ex(cls) and utils.has_known_bases(cls):
if cls.newstyle:
self._checker.add_message("raising-non-exception", node=self._node)

def visit_tuple(self, _):
def visit_tuple(self, _) -> None:
DanielNoord marked this conversation as resolved.
Show resolved Hide resolved
self._checker.add_message("raising-bad-type", node=self._node, args="tuple")

def visit_default(self, node):
def visit_default(self, node) -> None:
name = getattr(node, "name", node.__class__.__name__)
self._checker.add_message("raising-bad-type", node=self._node, args=name)

Expand Down Expand Up @@ -291,7 +291,7 @@ def open(self):
"raising-format-tuple",
"raise-missing-from",
)
def visit_raise(self, node):
def visit_raise(self, node: nodes.Raise) -> None:
if node.exc is None:
self._check_misplaced_bare_raise(node)
return
Expand Down Expand Up @@ -485,14 +485,14 @@ def gather_exceptions_from_handler(
self.add_message("try-except-raise", node=handler_having_bare_raise)

@utils.check_messages("wrong-exception-operation")
def visit_binop(self, node):
def visit_binop(self, node: nodes.BinOp) -> None:
if isinstance(node.parent, nodes.ExceptHandler):
# except (V | A)
suggestion = f"Did you mean '({node.left.as_string()}, {node.right.as_string()})' instead?"
self.add_message("wrong-exception-operation", node=node, args=(suggestion,))

@utils.check_messages("wrong-exception-operation")
def visit_compare(self, node):
def visit_compare(self, node: nodes.Compare) -> None:
if isinstance(node.parent, nodes.ExceptHandler):
# except (V < A)
suggestion = f"Did you mean '({node.left.as_string()}, {', '.join(operand.as_string() for _, operand in node.ops)})' instead?"
Expand All @@ -507,10 +507,10 @@ def visit_compare(self, node):
"catching-non-exception",
"duplicate-except",
)
def visit_tryexcept(self, node):
def visit_tryexcept(self, node: nodes.TryExcept) -> None:
"""check for empty except"""
self._check_try_except_raise(node)
exceptions_classes = []
exceptions_classes: list = []
DanielNoord marked this conversation as resolved.
Show resolved Hide resolved
nb_handlers = len(node.handlers)
for index, handler in enumerate(node.handlers):
if handler.type is None:
Expand Down
2 changes: 1 addition & 1 deletion pylint/checkers/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ def _check_line_ending(self, line_ending, line_num):
)

@check_messages("multiple-statements")
def visit_default(self, node):
def visit_default(self, node) -> None:
"""check the node line number and check it if not yet done"""
if not node.is_statement:
return
Expand Down
8 changes: 4 additions & 4 deletions pylint/checkers/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker):
),
)

def __init__(self, linter=None):
def __init__(self, linter=None): # pylint: disable=super-init-not-called
DanielNoord marked this conversation as resolved.
Show resolved Hide resolved
BaseChecker.__init__(self, linter)
self.stats = None
self.import_graph = None
Expand Down Expand Up @@ -494,7 +494,7 @@ def deprecated_modules(self):
return self.config.deprecated_modules

@check_messages(*MSGS)
def visit_import(self, node):
def visit_import(self, node: nodes.Import) -> None:
"""triggered when an import statement is seen"""
self._check_reimport(node)
self._check_import_as_rename(node)
Expand All @@ -520,7 +520,7 @@ def visit_import(self, node):
self._add_imported_module(node, imported_module.name)

@check_messages(*MSGS)
def visit_importfrom(self, node):
def visit_importfrom(self, node: nodes.ImportFrom) -> None:
"""triggered when a from statement is seen"""
basename = node.modname
imported_module = self._get_imported_module(node, basename)
Expand Down Expand Up @@ -618,7 +618,7 @@ def compute_first_non_import_node(self, node):
visit_ifexp
) = visit_comprehension = visit_expr = visit_if = compute_first_non_import_node

def visit_functiondef(self, node):
def visit_functiondef(self, node: nodes.FunctionDef) -> None:
if not self.linter.is_message_enabled("wrong-import-position", node.fromlineno):
return
# If it is the first non import instruction of the module, record it.
Expand Down
Loading