move from allowlist to blocklist for mypy

This commit is contained in:
Anthony Sottile 2021-11-14 21:35:40 -08:00
parent 500e2de0a0
commit 411ff24392
11 changed files with 53 additions and 48 deletions

View file

@ -102,33 +102,23 @@ universal = 1
check_untyped_defs = true check_untyped_defs = true
disallow_any_generics = true disallow_any_generics = true
disallow_incomplete_defs = true disallow_incomplete_defs = true
# TODO: disallow_untyped_defs = true disallow_untyped_defs = true
no_implicit_optional = true no_implicit_optional = true
warn_unused_ignores = true warn_unused_ignores = true
# TODO: until we opt in all the modules # TODO: fix these
[mypy-flake8.__init__] [mypy-flake8.api.legacy]
disallow_untyped_defs = true disallow_untyped_defs = false
[mypy-flake8.defaults] [mypy-flake8.checker]
disallow_untyped_defs = true disallow_untyped_defs = false
[mypy-flake8.discover_files] [mypy-flake8.main.application]
disallow_untyped_defs = true disallow_untyped_defs = false
[mypy-flake8.exceptions] [mypy-flake8.main.debug]
disallow_untyped_defs = true disallow_untyped_defs = false
[mypy-flake8.formatting.*] [mypy-flake8.options.config]
disallow_untyped_defs = true disallow_untyped_defs = false
[mypy-flake8.options.manager] [mypy-flake8.plugins.manager]
disallow_untyped_defs = true disallow_untyped_defs = false
[mypy-flake8.main.cli]
disallow_untyped_defs = true
[mypy-flake8.processor]
disallow_untyped_defs = true
[mypy-flake8.statistics]
disallow_untyped_defs = true
[mypy-flake8.style_guide]
disallow_untyped_defs = true
[mypy-flake8.utils]
disallow_untyped_defs = true
[mypy-tests.*] [mypy-tests.*]
disallow_untyped_defs = false disallow_untyped_defs = false

View file

@ -87,7 +87,7 @@ class Manager:
itertools.chain(self.options.exclude, self.options.extend_exclude) itertools.chain(self.options.exclude, self.options.extend_exclude)
) )
def _process_statistics(self): def _process_statistics(self) -> None:
for checker in self.checkers: for checker in self.checkers:
for statistic in defaults.STATISTIC_NAMES: for statistic in defaults.STATISTIC_NAMES:
self.statistics[statistic] += checker.statistics[statistic] self.statistics[statistic] += checker.statistics[statistic]
@ -142,7 +142,7 @@ class Manager:
# it to an integer # it to an integer
return jobs.n_jobs return jobs.n_jobs
def _handle_results(self, filename, results): def _handle_results(self, filename: str, results: Results) -> int:
style_guide = self.style_guide style_guide = self.style_guide
reported_results_count = 0 reported_results_count = 0
for (error_code, line_number, column, text, physical_line) in results: for (error_code, line_number, column, text, physical_line) in results:
@ -258,7 +258,7 @@ class Manager:
LOG.warning("Flake8 was interrupted by the user") LOG.warning("Flake8 was interrupted by the user")
raise exceptions.EarlyQuit("Early quit while running checks") raise exceptions.EarlyQuit("Early quit while running checks")
def start(self, paths=None): def start(self, paths: Optional[List[str]] = None) -> None:
"""Start checking files. """Start checking files.
:param list paths: :param list paths:
@ -268,7 +268,7 @@ class Manager:
LOG.info("Making checkers") LOG.info("Making checkers")
self.make_checkers(paths) self.make_checkers(paths)
def stop(self): def stop(self) -> None:
"""Stop checking files.""" """Stop checking files."""
self._process_statistics() self._process_statistics()
@ -450,7 +450,7 @@ class FileChecker:
text=text, text=text,
) )
def run_logical_checks(self): def run_logical_checks(self) -> None:
"""Run all checks expecting a logical line.""" """Run all checks expecting a logical line."""
assert self.processor is not None assert self.processor is not None
comments, logical_line, mapping = self.processor.build_logical_line() comments, logical_line, mapping = self.processor.build_logical_line()
@ -476,7 +476,7 @@ class FileChecker:
self.processor.next_logical_line() self.processor.next_logical_line()
def run_physical_checks(self, physical_line): def run_physical_checks(self, physical_line: str) -> None:
"""Run all checks for a given physical line. """Run all checks for a given physical line.
A single physical check may return multiple errors. A single physical check may return multiple errors.
@ -507,7 +507,7 @@ class FileChecker:
text=text, text=text,
) )
def process_tokens(self): def process_tokens(self) -> None:
"""Process tokens and trigger checks. """Process tokens and trigger checks.
Instead of using this directly, you should use Instead of using this directly, you should use
@ -551,7 +551,7 @@ class FileChecker:
self.statistics["logical lines"] = logical_lines self.statistics["logical lines"] = logical_lines
return self.filename, self.results, self.statistics return self.filename, self.results, self.statistics
def handle_newline(self, token_type): def handle_newline(self, token_type: int) -> None:
"""Handle the logic when encountering a newline token.""" """Handle the logic when encountering a newline token."""
assert self.processor is not None assert self.processor is not None
if token_type == tokenize.NEWLINE: if token_type == tokenize.NEWLINE:
@ -616,7 +616,7 @@ def _try_initialize_processpool(
return None return None
def calculate_pool_chunksize(num_checkers, num_jobs): def calculate_pool_chunksize(num_checkers: int, num_jobs: int) -> int:
"""Determine the chunksize for the multiprocessing Pool. """Determine the chunksize for the multiprocessing Pool.
- For chunksize, see: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool.imap # noqa - For chunksize, see: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool.imap # noqa
@ -628,7 +628,7 @@ def calculate_pool_chunksize(num_checkers, num_jobs):
return max(num_checkers // (num_jobs * 2), 1) return max(num_checkers // (num_jobs * 2), 1)
def _run_checks(checker): def _run_checks(checker: FileChecker) -> Tuple[str, Results, Dict[str, int]]:
return checker.run_checks() return checker.run_checks()

View file

@ -272,7 +272,7 @@ class Application:
self.file_checker_manager.stop() self.file_checker_manager.stop()
self.end_time = time.time() self.end_time = time.time()
def report_benchmarks(self): def report_benchmarks(self) -> None:
"""Aggregate, calculate, and report benchmarks for this run.""" """Aggregate, calculate, and report benchmarks for this run."""
assert self.options is not None assert self.options is not None
if not self.options.benchmark: if not self.options.benchmark:
@ -309,7 +309,7 @@ class Application:
self.result_count, self.result_count,
) )
def report_statistics(self): def report_statistics(self) -> None:
"""Aggregate and report statistics from this run.""" """Aggregate and report statistics from this run."""
assert self.options is not None assert self.options is not None
if not self.options.statistics: if not self.options.statistics:
@ -345,7 +345,7 @@ class Application:
self.make_guide() self.make_guide()
self.make_file_checker_manager() self.make_file_checker_manager()
def report(self): def report(self) -> None:
"""Report errors, statistics, and benchmarks.""" """Report errors, statistics, and benchmarks."""
assert self.formatter is not None assert self.formatter is not None
self.formatter.start() self.formatter.start()

View file

@ -4,6 +4,7 @@ import functools
from flake8 import defaults from flake8 import defaults
from flake8.main import debug from flake8.main import debug
from flake8.options.manager import OptionManager
def register_preliminary_options(parser: argparse.ArgumentParser) -> None: def register_preliminary_options(parser: argparse.ArgumentParser) -> None:
@ -84,12 +85,12 @@ class JobsArgument:
"""Representation for debugging.""" """Representation for debugging."""
return f"{type(self).__name__}({str(self)!r})" return f"{type(self).__name__}({str(self)!r})"
def __str__(self): def __str__(self) -> str:
"""Format our JobsArgument class.""" """Format our JobsArgument class."""
return "auto" if self.is_auto else str(self.n_jobs) return "auto" if self.is_auto else str(self.n_jobs)
def register_default_options(option_manager): def register_default_options(option_manager: OptionManager) -> None:
"""Register the default options on our OptionManager. """Register the default options on our OptionManager.
The default options include: The default options include:

View file

@ -1,10 +1,18 @@
"""Plugin built-in to Flake8 to treat pyflakes as a plugin.""" """Plugin built-in to Flake8 to treat pyflakes as a plugin."""
import argparse
import ast
import os import os
from typing import Any
from typing import Generator
from typing import List from typing import List
from typing import Tuple
from typing import Type
import pyflakes.checker import pyflakes.checker
from flake8 import utils from flake8 import utils
from flake8.options.manager import OptionManager
from flake8.processor import _Token
FLAKE8_PYFLAKES_CODES = { FLAKE8_PYFLAKES_CODES = {
"UnusedImport": "F401", "UnusedImport": "F401",
@ -67,7 +75,9 @@ class FlakesChecker(pyflakes.checker.Checker):
include_in_doctest: List[str] = [] include_in_doctest: List[str] = []
exclude_from_doctest: List[str] = [] exclude_from_doctest: List[str] = []
def __init__(self, tree, file_tokens, filename): def __init__(
self, tree: ast.AST, file_tokens: List[_Token], filename: str
) -> None:
"""Initialize the PyFlakes plugin with an AST tree and filename.""" """Initialize the PyFlakes plugin with an AST tree and filename."""
filename = utils.normalize_path(filename) filename = utils.normalize_path(filename)
with_doctest = self.with_doctest with_doctest = self.with_doctest
@ -99,7 +109,7 @@ class FlakesChecker(pyflakes.checker.Checker):
) )
@classmethod @classmethod
def add_options(cls, parser): def add_options(cls, parser: OptionManager) -> None:
"""Register options for PyFlakes on the Flake8 OptionManager.""" """Register options for PyFlakes on the Flake8 OptionManager."""
parser.add_option( parser.add_option(
"--builtins", "--builtins",
@ -134,7 +144,7 @@ class FlakesChecker(pyflakes.checker.Checker):
) )
@classmethod @classmethod
def parse_options(cls, options): def parse_options(cls, options: argparse.Namespace) -> None:
"""Parse option values from Flake8's OptionManager.""" """Parse option values from Flake8's OptionManager."""
if options.builtins: if options.builtins:
cls.builtIns = cls.builtIns.union(options.builtins) cls.builtIns = cls.builtIns.union(options.builtins)
@ -171,7 +181,7 @@ class FlakesChecker(pyflakes.checker.Checker):
f"both for doctesting." f"both for doctesting."
) )
def run(self): def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]:
"""Run the plugin.""" """Run the plugin."""
for message in self.messages: for message in self.messages:
col = getattr(message, "col", 0) col = getattr(message, "col", 0)

View file

@ -1,5 +1,5 @@
[flake8:local-plugins] [flake8:local-plugins]
extension = extension =
XE = test_plugins:ExtensionTestPlugin XE = tests.integration.test_plugins:ExtensionTestPlugin
report = report =
XR = test_plugins:ReportTestPlugin XR = tests.integration.test_plugins:ReportTestPlugin

View file

View file

0
tests/unit/__init__.py Normal file
View file

View file

@ -41,5 +41,9 @@ def test_get_local_plugins():
localcfs.return_value = [config_fixture_path] localcfs.return_value = [config_fixture_path]
local_plugins = config.get_local_plugins(config_finder) local_plugins = config.get_local_plugins(config_finder)
assert local_plugins.extension == ["XE = test_plugins:ExtensionTestPlugin"] assert local_plugins.extension == [
assert local_plugins.report == ["XR = test_plugins:ReportTestPlugin"] "XE = tests.integration.test_plugins:ExtensionTestPlugin"
]
assert local_plugins.report == [
"XR = tests.integration.test_plugins:ReportTestPlugin"
]

View file

@ -25,7 +25,7 @@ def f():
sys = sys sys = sys
""" """
tree = ast.parse(src) tree = ast.parse(src)
checker = pyflakes_shim.FlakesChecker(tree, (), "t.py") checker = pyflakes_shim.FlakesChecker(tree, [], "t.py")
message_texts = [s for _, _, s, _ in checker.run()] message_texts = [s for _, _, s, _ in checker.run()]
assert message_texts == [ assert message_texts == [
"F823 local variable 'sys' defined in enclosing scope on line 1 referenced before assignment", # noqa: E501 "F823 local variable 'sys' defined in enclosing scope on line 1 referenced before assignment", # noqa: E501