From 411ff24392a9e19fd5f65aa38d95d7e93c863fa9 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 14 Nov 2021 21:35:40 -0800 Subject: [PATCH] move from allowlist to blocklist for mypy --- setup.cfg | 38 ++++++++------------ src/flake8/checker.py | 20 +++++------ src/flake8/main/application.py | 6 ++-- src/flake8/main/options.py | 5 +-- src/flake8/plugins/pyflakes.py | 18 +++++++--- tests/fixtures/config_files/local-plugin.ini | 4 +-- tests/integration/__init__.py | 0 tests/integration/subdir/__init__.py | 0 tests/unit/__init__.py | 0 tests/unit/test_get_local_plugins.py | 8 +++-- tests/unit/test_pyflakes_codes.py | 2 +- 11 files changed, 53 insertions(+), 48 deletions(-) create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/subdir/__init__.py create mode 100644 tests/unit/__init__.py diff --git a/setup.cfg b/setup.cfg index 1477769..372bbb4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -102,33 +102,23 @@ universal = 1 check_untyped_defs = true disallow_any_generics = true disallow_incomplete_defs = true -# TODO: disallow_untyped_defs = true +disallow_untyped_defs = true no_implicit_optional = true warn_unused_ignores = true -# TODO: until we opt in all the modules -[mypy-flake8.__init__] -disallow_untyped_defs = true -[mypy-flake8.defaults] -disallow_untyped_defs = true -[mypy-flake8.discover_files] -disallow_untyped_defs = true -[mypy-flake8.exceptions] -disallow_untyped_defs = true -[mypy-flake8.formatting.*] -disallow_untyped_defs = true -[mypy-flake8.options.manager] -disallow_untyped_defs = true -[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 +# TODO: fix these +[mypy-flake8.api.legacy] +disallow_untyped_defs = false +[mypy-flake8.checker] +disallow_untyped_defs = false +[mypy-flake8.main.application] +disallow_untyped_defs = false +[mypy-flake8.main.debug] +disallow_untyped_defs = false +[mypy-flake8.options.config] +disallow_untyped_defs = false +[mypy-flake8.plugins.manager] +disallow_untyped_defs = false [mypy-tests.*] disallow_untyped_defs = false diff --git a/src/flake8/checker.py b/src/flake8/checker.py index dba5d08..059d05c 100644 --- a/src/flake8/checker.py +++ b/src/flake8/checker.py @@ -87,7 +87,7 @@ class Manager: itertools.chain(self.options.exclude, self.options.extend_exclude) ) - def _process_statistics(self): + def _process_statistics(self) -> None: for checker in self.checkers: for statistic in defaults.STATISTIC_NAMES: self.statistics[statistic] += checker.statistics[statistic] @@ -142,7 +142,7 @@ class Manager: # it to an integer return jobs.n_jobs - def _handle_results(self, filename, results): + def _handle_results(self, filename: str, results: Results) -> int: style_guide = self.style_guide reported_results_count = 0 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") 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. :param list paths: @@ -268,7 +268,7 @@ class Manager: LOG.info("Making checkers") self.make_checkers(paths) - def stop(self): + def stop(self) -> None: """Stop checking files.""" self._process_statistics() @@ -450,7 +450,7 @@ class FileChecker: text=text, ) - def run_logical_checks(self): + def run_logical_checks(self) -> None: """Run all checks expecting a logical line.""" assert self.processor is not None comments, logical_line, mapping = self.processor.build_logical_line() @@ -476,7 +476,7 @@ class FileChecker: 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. A single physical check may return multiple errors. @@ -507,7 +507,7 @@ class FileChecker: text=text, ) - def process_tokens(self): + def process_tokens(self) -> None: """Process tokens and trigger checks. Instead of using this directly, you should use @@ -551,7 +551,7 @@ class FileChecker: self.statistics["logical lines"] = logical_lines 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.""" assert self.processor is not None if token_type == tokenize.NEWLINE: @@ -616,7 +616,7 @@ def _try_initialize_processpool( 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. - 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) -def _run_checks(checker): +def _run_checks(checker: FileChecker) -> Tuple[str, Results, Dict[str, int]]: return checker.run_checks() diff --git a/src/flake8/main/application.py b/src/flake8/main/application.py index 70165c0..2ed2f68 100644 --- a/src/flake8/main/application.py +++ b/src/flake8/main/application.py @@ -272,7 +272,7 @@ class Application: self.file_checker_manager.stop() self.end_time = time.time() - def report_benchmarks(self): + def report_benchmarks(self) -> None: """Aggregate, calculate, and report benchmarks for this run.""" assert self.options is not None if not self.options.benchmark: @@ -309,7 +309,7 @@ class Application: self.result_count, ) - def report_statistics(self): + def report_statistics(self) -> None: """Aggregate and report statistics from this run.""" assert self.options is not None if not self.options.statistics: @@ -345,7 +345,7 @@ class Application: self.make_guide() self.make_file_checker_manager() - def report(self): + def report(self) -> None: """Report errors, statistics, and benchmarks.""" assert self.formatter is not None self.formatter.start() diff --git a/src/flake8/main/options.py b/src/flake8/main/options.py index 74440db..babd44b 100644 --- a/src/flake8/main/options.py +++ b/src/flake8/main/options.py @@ -4,6 +4,7 @@ import functools from flake8 import defaults from flake8.main import debug +from flake8.options.manager import OptionManager def register_preliminary_options(parser: argparse.ArgumentParser) -> None: @@ -84,12 +85,12 @@ class JobsArgument: """Representation for debugging.""" return f"{type(self).__name__}({str(self)!r})" - def __str__(self): + def __str__(self) -> str: """Format our JobsArgument class.""" 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. The default options include: diff --git a/src/flake8/plugins/pyflakes.py b/src/flake8/plugins/pyflakes.py index 4d1d7b8..7509438 100644 --- a/src/flake8/plugins/pyflakes.py +++ b/src/flake8/plugins/pyflakes.py @@ -1,10 +1,18 @@ """Plugin built-in to Flake8 to treat pyflakes as a plugin.""" +import argparse +import ast import os +from typing import Any +from typing import Generator from typing import List +from typing import Tuple +from typing import Type import pyflakes.checker from flake8 import utils +from flake8.options.manager import OptionManager +from flake8.processor import _Token FLAKE8_PYFLAKES_CODES = { "UnusedImport": "F401", @@ -67,7 +75,9 @@ class FlakesChecker(pyflakes.checker.Checker): include_in_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.""" filename = utils.normalize_path(filename) with_doctest = self.with_doctest @@ -99,7 +109,7 @@ class FlakesChecker(pyflakes.checker.Checker): ) @classmethod - def add_options(cls, parser): + def add_options(cls, parser: OptionManager) -> None: """Register options for PyFlakes on the Flake8 OptionManager.""" parser.add_option( "--builtins", @@ -134,7 +144,7 @@ class FlakesChecker(pyflakes.checker.Checker): ) @classmethod - def parse_options(cls, options): + def parse_options(cls, options: argparse.Namespace) -> None: """Parse option values from Flake8's OptionManager.""" if options.builtins: cls.builtIns = cls.builtIns.union(options.builtins) @@ -171,7 +181,7 @@ class FlakesChecker(pyflakes.checker.Checker): f"both for doctesting." ) - def run(self): + def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]: """Run the plugin.""" for message in self.messages: col = getattr(message, "col", 0) diff --git a/tests/fixtures/config_files/local-plugin.ini b/tests/fixtures/config_files/local-plugin.ini index d0aa3be..8344f76 100644 --- a/tests/fixtures/config_files/local-plugin.ini +++ b/tests/fixtures/config_files/local-plugin.ini @@ -1,5 +1,5 @@ [flake8:local-plugins] extension = - XE = test_plugins:ExtensionTestPlugin + XE = tests.integration.test_plugins:ExtensionTestPlugin report = - XR = test_plugins:ReportTestPlugin + XR = tests.integration.test_plugins:ReportTestPlugin diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/subdir/__init__.py b/tests/integration/subdir/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/test_get_local_plugins.py b/tests/unit/test_get_local_plugins.py index 7e7b318..44d8725 100644 --- a/tests/unit/test_get_local_plugins.py +++ b/tests/unit/test_get_local_plugins.py @@ -41,5 +41,9 @@ def test_get_local_plugins(): localcfs.return_value = [config_fixture_path] local_plugins = config.get_local_plugins(config_finder) - assert local_plugins.extension == ["XE = test_plugins:ExtensionTestPlugin"] - assert local_plugins.report == ["XR = test_plugins:ReportTestPlugin"] + assert local_plugins.extension == [ + "XE = tests.integration.test_plugins:ExtensionTestPlugin" + ] + assert local_plugins.report == [ + "XR = tests.integration.test_plugins:ReportTestPlugin" + ] diff --git a/tests/unit/test_pyflakes_codes.py b/tests/unit/test_pyflakes_codes.py index 526832e..c251721 100644 --- a/tests/unit/test_pyflakes_codes.py +++ b/tests/unit/test_pyflakes_codes.py @@ -25,7 +25,7 @@ def f(): sys = sys """ 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()] assert message_texts == [ "F823 local variable 'sys' defined in enclosing scope on line 1 referenced before assignment", # noqa: E501