summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Sottile <asottile@umich.edu>2021-04-07 08:30:55 -0700
committerGitHub <noreply@github.com>2021-04-07 08:30:55 -0700
commit5899e7d7206d35328b0feca9b1d407ff0ffcc484 (patch)
tree148541f950701bf41df5fa7c31eb2aba792c76f9
parent1623a8ea4f6665f95978bfc3ff386480f2aa1158 (diff)
parent3f10c04fd029cf520b9769e574ada7df87083db6 (diff)
downloadflake8-5899e7d7206d35328b0feca9b1d407ff0ffcc484.tar.gz
Merge pull request #1307 from PyCQA/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
-rw-r--r--.pre-commit-config.yaml4
-rw-r--r--src/flake8/checker.py16
-rw-r--r--src/flake8/main/application.py37
-rw-r--r--src/flake8/plugins/manager.py4
-rw-r--r--src/flake8/style_guide.py27
-rw-r--r--src/flake8/utils.py2
-rw-r--r--tests/integration/test_plugins.py4
-rw-r--r--tests/unit/test_exceptions.py70
-rw-r--r--tests/unit/test_plugin_manager.py8
9 files changed, 94 insertions, 78 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index eb4ff62..c676e5c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,7 +1,7 @@
exclude: ^tests/fixtures/example-code/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v2.3.0
+ rev: v3.4.0
hooks:
- id: check-yaml
- id: debug-statements
@@ -26,7 +26,7 @@ repos:
- id: pyupgrade
args: [--py36-plus]
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.720
+ rev: v0.812
hooks:
- id: mypy
exclude: ^(docs/|example-plugin/|tests/fixtures)
diff --git a/src/flake8/checker.py b/src/flake8/checker.py
index 2e4f0b8..6f8c0c1 100644
--- a/src/flake8/checker.py
+++ b/src/flake8/checker.py
@@ -40,11 +40,7 @@ SERIAL_RETRY_ERRNOS = {
def _multiprocessing_is_fork(): # type () -> bool
"""Class state is only preserved when using the `fork` strategy."""
- return (
- multiprocessing
- # https://github.com/python/typeshed/pull/3415
- and multiprocessing.get_start_method() == "fork" # type: ignore
- )
+ return multiprocessing and multiprocessing.get_start_method() == "fork"
class Manager:
@@ -396,7 +392,7 @@ class FileChecker:
# If we're recovering from a problem in _make_processor, we will not
# have this attribute.
- if hasattr(self, "processor"):
+ if hasattr(self, "processor") and self.processor is not None:
line = self.processor.noqa_line_for(line_number)
else:
line = None
@@ -407,6 +403,7 @@ class FileChecker:
def run_check(self, plugin, **arguments):
"""Run the check in a single plugin."""
LOG.debug("Running %r with %r", plugin, arguments)
+ assert self.processor is not None
try:
self.processor.keyword_arguments_for(
plugin["parameters"], arguments
@@ -467,6 +464,7 @@ class FileChecker:
def run_ast_checks(self) -> None:
"""Run all checks expecting an abstract syntax tree."""
+ assert self.processor is not None
try:
ast = self.processor.build_ast()
except (ValueError, SyntaxError, TypeError) as e:
@@ -494,6 +492,7 @@ class FileChecker:
def run_logical_checks(self):
"""Run all checks expecting a logical line."""
+ assert self.processor is not None
comments, logical_line, mapping = self.processor.build_logical_line()
if not mapping:
return
@@ -522,6 +521,7 @@ class FileChecker:
A single physical check may return multiple errors.
"""
+ assert self.processor is not None
for plugin in self.checks["physical_line_plugins"]:
self.processor.update_checker_state_for(plugin)
result = self.run_check(plugin, physical_line=physical_line)
@@ -554,6 +554,7 @@ class FileChecker:
Instead of using this directly, you should use
:meth:`flake8.checker.FileChecker.run_checks`.
"""
+ assert self.processor is not None
parens = 0
statistics = self.statistics
file_processor = self.processor
@@ -577,6 +578,7 @@ class FileChecker:
def run_checks(self):
"""Run checks against the file."""
+ assert self.processor is not None
try:
self.process_tokens()
self.run_ast_checks()
@@ -594,6 +596,7 @@ class FileChecker:
def handle_newline(self, token_type):
"""Handle the logic when encountering a newline token."""
+ assert self.processor is not None
if token_type == tokenize.NEWLINE:
self.run_logical_checks()
self.processor.reset_blank_before()
@@ -608,6 +611,7 @@ class FileChecker:
self, token: processor._Token, prev_physical: str
) -> None:
"""Run physical checks if and only if it is at the end of the line."""
+ assert self.processor is not None
# a newline token ends a single physical line.
if processor.is_eol_token(token):
# if the file does not end with a newline, the NEWLINE
diff --git a/src/flake8/main/application.py b/src/flake8/main/application.py
index 6e99ec2..44a5524 100644
--- a/src/flake8/main/application.py
+++ b/src/flake8/main/application.py
@@ -44,7 +44,7 @@ class Application:
#: The timestamp when the Application instance was instantiated.
self.start_time = time.time()
#: The timestamp when the Application finished reported errors.
- self.end_time: float = None
+ self.end_time: Optional[float] = None
#: The name of the program being run
self.program = program
#: The version of the program being run
@@ -63,24 +63,26 @@ class Application:
options.register_default_options(self.option_manager)
#: The instance of :class:`flake8.plugins.manager.Checkers`
- self.check_plugins: plugin_manager.Checkers = None
+ self.check_plugins: Optional[plugin_manager.Checkers] = None
#: The instance of :class:`flake8.plugins.manager.ReportFormatters`
- self.formatting_plugins: plugin_manager.ReportFormatters = None
+ self.formatting_plugins: Optional[
+ plugin_manager.ReportFormatters
+ ] = None
#: The user-selected formatter from :attr:`formatting_plugins`
- self.formatter: BaseFormatter = None
+ self.formatter: Optional[BaseFormatter] = None
#: The :class:`flake8.style_guide.StyleGuideManager` built from the
#: user's options
- self.guide: style_guide.StyleGuideManager = None
+ self.guide: Optional[style_guide.StyleGuideManager] = None
#: The :class:`flake8.checker.Manager` that will handle running all of
#: the checks selected by the user.
- self.file_checker_manager: checker.Manager = None
+ self.file_checker_manager: Optional[checker.Manager] = None
#: The user-supplied options parsed into an instance of
#: :class:`argparse.Namespace`
- self.options: argparse.Namespace = None
+ self.options: Optional[argparse.Namespace] = None
#: The left over arguments that were not parsed by
#: :attr:`option_manager`
- self.args: List[str] = None
+ self.args: Optional[List[str]] = None
#: The number of errors, warnings, and other messages after running
#: flake8 and taking into account ignored errors and lines.
self.result_count = 0
@@ -128,6 +130,7 @@ class Application:
This should be the last thing called on the application instance. It
will check certain options and exit appropriately.
"""
+ assert self.options is not None
if self.options.count:
print(self.result_count)
@@ -162,8 +165,10 @@ class Application:
def register_plugin_options(self) -> None:
"""Register options provided by plugins to our option manager."""
+ assert self.check_plugins is not None
self.check_plugins.register_options(self.option_manager)
self.check_plugins.register_plugin_versions(self.option_manager)
+ assert self.formatting_plugins is not None
self.formatting_plugins.register_options(self.option_manager)
def parse_configuration_and_cli(
@@ -190,15 +195,18 @@ class Application:
if not self.parsed_diff:
self.exit()
+ assert self.check_plugins is not None
self.check_plugins.provide_options(
self.option_manager, self.options, self.args
)
+ assert self.formatting_plugins is not None
self.formatting_plugins.provide_options(
self.option_manager, self.options, self.args
)
def formatter_for(self, formatter_plugin_name):
"""Retrieve the formatter class by plugin name."""
+ assert self.formatting_plugins is not None
default_formatter = self.formatting_plugins["default"]
formatter_plugin = self.formatting_plugins.get(formatter_plugin_name)
if formatter_plugin is None:
@@ -214,6 +222,7 @@ class Application:
self, formatter_class: Optional[Type["BaseFormatter"]] = None
) -> None:
"""Initialize a formatter based on the parsed options."""
+ assert self.options is not None
format_plugin = self.options.format
if 1 <= self.options.quiet < 2:
format_plugin = "quiet-filename"
@@ -227,6 +236,8 @@ class Application:
def make_guide(self) -> None:
"""Initialize our StyleGuide."""
+ assert self.formatter is not None
+ assert self.options is not None
self.guide = style_guide.StyleGuideManager(
self.options, self.formatter
)
@@ -252,6 +263,7 @@ class Application:
:param list files:
List of filenames to process
"""
+ assert self.file_checker_manager is not None
if self.running_against_diff:
files = sorted(self.parsed_diff)
self.file_checker_manager.start(files)
@@ -267,9 +279,12 @@ class Application:
def report_benchmarks(self):
"""Aggregate, calculate, and report benchmarks for this run."""
+ assert self.options is not None
if not self.options.benchmark:
return
+ assert self.file_checker_manager is not None
+ assert self.end_time is not None
time_elapsed = self.end_time - self.start_time
statistics = [("seconds elapsed", time_elapsed)]
add_statistic = statistics.append
@@ -280,6 +295,7 @@ class Application:
per_second_description = f"{statistic} processed per second"
add_statistic((per_second_description, int(value / time_elapsed)))
+ assert self.formatter is not None
self.formatter.show_benchmarks(statistics)
def report_errors(self) -> None:
@@ -289,6 +305,7 @@ class Application:
number of errors, warnings, and other messages found.
"""
LOG.info("Reporting errors")
+ assert self.file_checker_manager is not None
results = self.file_checker_manager.report()
self.total_result_count, self.result_count = results
LOG.info(
@@ -299,9 +316,12 @@ class Application:
def report_statistics(self):
"""Aggregate and report statistics from this run."""
+ assert self.options is not None
if not self.options.statistics:
return
+ assert self.formatter is not None
+ assert self.guide is not None
self.formatter.show_statistics(self.guide.stats)
def initialize(self, argv: List[str]) -> None:
@@ -332,6 +352,7 @@ class Application:
def report(self):
"""Report errors, statistics, and benchmarks."""
+ assert self.formatter is not None
self.formatter.start()
self.report_errors()
self.report_statistics()
diff --git a/src/flake8/plugins/manager.py b/src/flake8/plugins/manager.py
index a7f285a..3779b20 100644
--- a/src/flake8/plugins/manager.py
+++ b/src/flake8/plugins/manager.py
@@ -251,7 +251,9 @@ class PluginManager: # pylint: disable=too-few-public-methods
for plugin_str in local_plugins:
name, _, entry_str = plugin_str.partition("=")
name, entry_str = name.strip(), entry_str.strip()
- entry_point = importlib_metadata.EntryPoint(name, entry_str, None)
+ entry_point = importlib_metadata.EntryPoint(
+ name, entry_str, self.namespace
+ )
self._load_plugin_from_entrypoint(entry_point, local=True)
def _load_entrypoint_plugins(self):
diff --git a/src/flake8/style_guide.py b/src/flake8/style_guide.py
index c35c739..5c91be8 100644
--- a/src/flake8/style_guide.py
+++ b/src/flake8/style_guide.py
@@ -54,20 +54,19 @@ def find_noqa(physical_line: str) -> Optional[Match[str]]:
return defaults.NOQA_INLINE_REGEXP.search(physical_line)
-_Violation = collections.namedtuple(
- "Violation",
- [
- "code",
- "filename",
- "line_number",
- "column_number",
- "text",
- "physical_line",
- ],
-)
-
-
-class Violation(_Violation):
+class Violation(
+ collections.namedtuple(
+ "Violation",
+ [
+ "code",
+ "filename",
+ "line_number",
+ "column_number",
+ "text",
+ "physical_line",
+ ],
+ )
+):
"""Class representing a violation reported by Flake8."""
def is_inline_ignored(self, disable_noqa: bool) -> bool:
diff --git a/src/flake8/utils.py b/src/flake8/utils.py
index fe5d907..c5c134e 100644
--- a/src/flake8/utils.py
+++ b/src/flake8/utils.py
@@ -57,7 +57,7 @@ def parse_comma_separated_list(
return [item for item in item_gen if item]
-_Token = collections.namedtuple("Token", ("tp", "src"))
+_Token = collections.namedtuple("_Token", ("tp", "src"))
_CODE, _FILE, _COLON, _COMMA, _WS = "code", "file", "colon", "comma", "ws"
_EOF = "eof"
_FILE_LIST_TOKEN_TYPES = [
diff --git a/tests/integration/test_plugins.py b/tests/integration/test_plugins.py
index 1b6203e..867a94e 100644
--- a/tests/integration/test_plugins.py
+++ b/tests/integration/test_plugins.py
@@ -41,7 +41,9 @@ def test_enable_local_plugin_from_config():
app = application.Application()
app.initialize(['flake8', '--config', LOCAL_PLUGIN_CONFIG])
+ assert app.check_plugins is not None
assert app.check_plugins['XE'].plugin is ExtensionTestPlugin
+ assert app.formatting_plugins is not None
assert app.formatting_plugins['XR'].plugin is ReportTestPlugin
@@ -51,6 +53,7 @@ def test_local_plugin_can_add_option():
app.initialize(
['flake8', '--config', LOCAL_PLUGIN_CONFIG, '--anopt', 'foo'])
+ assert app.options is not None
assert app.options.anopt == 'foo'
@@ -59,4 +62,5 @@ def test_enable_local_plugin_at_non_installed_path():
app = application.Application()
app.initialize(['flake8', '--config', LOCAL_PLUGIN_PATH_CONFIG])
+ assert app.check_plugins is not None
assert app.check_plugins['XE'].plugin.name == 'ExtensionTestPlugin2'
diff --git a/tests/unit/test_exceptions.py b/tests/unit/test_exceptions.py
index 0254cb2..89490fa 100644
--- a/tests/unit/test_exceptions.py
+++ b/tests/unit/test_exceptions.py
@@ -1,48 +1,34 @@
"""Tests for the flake8.exceptions module."""
import pickle
-from flake8 import exceptions
-
-
-class _ExceptionTest:
- def test_pickleable(self):
- """Test that the exception is round-trip pickleable."""
- for proto in range(pickle.HIGHEST_PROTOCOL + 1):
- new_err = pickle.loads(pickle.dumps(self.err, protocol=proto))
- assert str(self.err) == str(new_err)
- orig_e = self.err.original_exception
- new_e = new_err.original_exception
- assert (type(orig_e), orig_e.args) == (type(new_e), new_e.args)
-
-
-class TestFailedToLoadPlugin(_ExceptionTest):
- """Tests for the FailedToLoadPlugin exception."""
-
- err = exceptions.FailedToLoadPlugin(
- plugin_name='plugin_name',
- exception=ValueError('boom!'),
- )
-
-
-class TestInvalidSyntax(_ExceptionTest):
- """Tests for the InvalidSyntax exception."""
-
- err = exceptions.InvalidSyntax(exception=ValueError('Unexpected token: $'))
-
-
-class TestPluginRequestedUnknownParameters(_ExceptionTest):
- """Tests for the PluginRequestedUnknownParameters exception."""
-
- err = exceptions.PluginRequestedUnknownParameters(
- plugin={'plugin_name': 'plugin_name'},
- exception=ValueError('boom!'),
- )
+import pytest
+from flake8 import exceptions
-class TestPluginExecutionFailed(_ExceptionTest):
- """Tests for the PluginExecutionFailed exception."""
- err = exceptions.PluginExecutionFailed(
- plugin={'plugin_name': 'plugin_name'},
- exception=ValueError('boom!'),
- )
+@pytest.mark.parametrize(
+ 'err',
+ (
+ exceptions.FailedToLoadPlugin(
+ plugin_name='plugin_name',
+ exception=ValueError('boom!'),
+ ),
+ exceptions.InvalidSyntax(exception=ValueError('Unexpected token: $')),
+ exceptions.PluginRequestedUnknownParameters(
+ plugin={'plugin_name': 'plugin_name'},
+ exception=ValueError('boom!'),
+ ),
+ exceptions.PluginExecutionFailed(
+ plugin={'plugin_name': 'plugin_name'},
+ exception=ValueError('boom!'),
+ )
+ ),
+)
+def test_pickleable(err):
+ """Ensure that our exceptions can cross pickle boundaries."""
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ new_err = pickle.loads(pickle.dumps(err, protocol=proto))
+ assert str(err) == str(new_err)
+ orig_e = err.original_exception
+ new_e = new_err.original_exception
+ assert (type(orig_e), orig_e.args) == (type(new_e), new_e.args)
diff --git a/tests/unit/test_plugin_manager.py b/tests/unit/test_plugin_manager.py
index 55c3e24..6f95a72 100644
--- a/tests/unit/test_plugin_manager.py
+++ b/tests/unit/test_plugin_manager.py
@@ -18,8 +18,8 @@ def test_calls_entrypoints_creates_plugins_automaticaly(entry_points_mck):
"""Verify that we create Plugins on instantiation."""
entry_points_mck.return_value = {
'testing.entrypoints': [
- importlib_metadata.EntryPoint('T100', '', None),
- importlib_metadata.EntryPoint('T200', '', None),
+ importlib_metadata.EntryPoint('T100', '', 'testing.entrypoints'),
+ importlib_metadata.EntryPoint('T200', '', 'testing.entrypoints'),
],
}
plugin_mgr = manager.PluginManager(namespace='testing.entrypoints')
@@ -36,8 +36,8 @@ def test_handles_mapping_functions_across_plugins(entry_points_mck):
"""Verify we can use the PluginManager call functions on all plugins."""
entry_points_mck.return_value = {
'testing.entrypoints': [
- importlib_metadata.EntryPoint('T100', '', None),
- importlib_metadata.EntryPoint('T200', '', None),
+ importlib_metadata.EntryPoint('T100', '', 'testing.entrypoints'),
+ importlib_metadata.EntryPoint('T200', '', 'testing.entrypoints'),
],
}
plugin_mgr = manager.PluginManager(namespace='testing.entrypoints')