Skip to content

Add typing to basic_checker #6769

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

Merged
merged 1 commit into from
May 31, 2022
Merged
Changes from all commits
Commits
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
52 changes: 35 additions & 17 deletions pylint/checkers/base/basic_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import collections
import itertools
import sys
from collections.abc import Iterator
from typing import TYPE_CHECKING, cast

import astroid
Expand All @@ -21,7 +22,7 @@
from pylint.utils import LinterStats

if TYPE_CHECKING:
pass
from pylint.lint.pylinter import PyLinter

if sys.version_info >= (3, 8):
from typing import Literal
Expand Down Expand Up @@ -63,10 +64,10 @@ class _BasicChecker(BaseChecker):


def report_by_type_stats(
sect,
sect: reporter_nodes.Section,
stats: LinterStats,
old_stats: LinterStats | None,
):
) -> None:
"""Make a report of.

* percentage of different types documented
Expand Down Expand Up @@ -254,11 +255,11 @@ class BasicChecker(_BasicChecker):

reports = (("RP0101", "Statistics by type", report_by_type_stats),)

def __init__(self, linter):
def __init__(self, linter: PyLinter) -> None:
super().__init__(linter)
self._tryfinallys = None
self._tryfinallys: list[nodes.TryFinally] | None = None

def open(self):
def open(self) -> None:
"""Initialize visit variables and statistics."""
py_version = self.linter.config.py_version
self._py38_plus = py_version >= (3, 8)
Expand All @@ -285,7 +286,11 @@ def visit_comprehension(self, node: nodes.Comprehension) -> None:
for if_test in node.ifs:
self._check_using_constant_test(node, if_test)

def _check_using_constant_test(self, node, test):
def _check_using_constant_test(
self,
node: nodes.If | nodes.IfExp | nodes.Comprehension,
test: nodes.NodeNG | None,
) -> None:
const_nodes = (
nodes.Module,
nodes.GeneratorExp,
Expand Down Expand Up @@ -395,7 +400,9 @@ def visit_expr(self, node: nodes.Expr) -> None:
self.add_message("pointless-statement", node=node)

@staticmethod
def _filter_vararg(node, call_args):
def _filter_vararg(
node: nodes.Lambda, call_args: list[nodes.NodeNG]
) -> Iterator[nodes.NodeNG]:
# Return the arguments for the given call which are
# not passed as vararg.
for arg in call_args:
Expand All @@ -409,7 +416,9 @@ def _filter_vararg(node, call_args):
yield arg

@staticmethod
def _has_variadic_argument(args, variadic_name):
def _has_variadic_argument(
args: list[nodes.Starred | nodes.Keyword], variadic_name: str
) -> bool:
if not args:
return True
for arg in args:
Expand Down Expand Up @@ -493,10 +502,10 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None:

visit_asyncfunctiondef = visit_functiondef

def _check_dangerous_default(self, node):
def _check_dangerous_default(self, node: nodes.FunctionDef) -> None:
"""Check for dangerous default values as arguments."""

def is_iterable(internal_node):
def is_iterable(internal_node: nodes.NodeNG) -> bool:
return isinstance(internal_node, (nodes.List, nodes.Set, nodes.Dict))

defaults = node.args.defaults or [] + node.args.kw_defaults or []
Expand Down Expand Up @@ -574,7 +583,7 @@ def visit_raise(self, node: nodes.Raise) -> None:
"""
self._check_unreachable(node)

def _check_misplaced_format_function(self, call_node):
def _check_misplaced_format_function(self, call_node: nodes.Call) -> None:
if not isinstance(call_node.func, nodes.Attribute):
return
if call_node.func.attrname != "format":
Expand Down Expand Up @@ -664,13 +673,17 @@ def visit_set(self, node: nodes.Set) -> None:

def visit_tryfinally(self, node: nodes.TryFinally) -> None:
"""Update try...finally flag."""
assert self._tryfinallys is not None
self._tryfinallys.append(node)

def leave_tryfinally(self, _: nodes.TryFinally) -> None:
"""Update try...finally flag."""
assert self._tryfinallys is not None
self._tryfinallys.pop()

def _check_unreachable(self, node):
def _check_unreachable(
self, node: nodes.Return | nodes.Continue | nodes.Break | nodes.Raise
) -> None:
"""Check unreachable code."""
unreach_stmt = node.next_sibling()
if unreach_stmt is not None:
Expand All @@ -686,7 +699,12 @@ def _check_unreachable(self, node):
return
self.add_message("unreachable", node=unreach_stmt)

def _check_not_in_finally(self, node, node_name, breaker_classes=()):
def _check_not_in_finally(
self,
node: nodes.Break | nodes.Return,
node_name: str,
breaker_classes: tuple[nodes.NodeNG, ...] = (),
) -> None:
"""Check that a node is not inside a 'finally' clause of a
'try...finally' statement.

Expand All @@ -706,7 +724,7 @@ def _check_not_in_finally(self, node, node_name, breaker_classes=()):
_node = _parent
_parent = _node.parent

def _check_reversed(self, node):
def _check_reversed(self, node: nodes.Call) -> None:
"""Check that the argument to `reversed` is a sequence."""
try:
argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
Expand Down Expand Up @@ -779,7 +797,7 @@ def visit_with(self, node: nodes.With) -> None:
# we assume it's a nested "with".
self.add_message("confusing-with-statement", node=node)

def _check_self_assigning_variable(self, node):
def _check_self_assigning_variable(self, node: nodes.Assign) -> None:
# Detect assigning to the same variable.

scope = node.scope()
Expand Down Expand Up @@ -820,7 +838,7 @@ def _check_self_assigning_variable(self, node):
"self-assigning-variable", args=(target.name,), node=target
)

def _check_redeclared_assign_name(self, targets):
def _check_redeclared_assign_name(self, targets: list[nodes.NodeNG | None]) -> None:
dummy_variables_rgx = self.linter.config.dummy_variables_rgx

for target in targets:
Expand Down