summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Cordasco <graffatcolmingov@gmail.com>2016-07-27 07:17:29 -0500
committerIan Cordasco <graffatcolmingov@gmail.com>2016-07-27 07:17:29 -0500
commit47e3e65cc1734e46fd16ea11622e57b7978d3e0d (patch)
treea7bf86b9e26ed8f0f9d5fe8553abe585b3c80556
parent846bfafe6c63870f41bac0eadf41b2a0a85c85aa (diff)
downloadflake8-47e3e65cc1734e46fd16ea11622e57b7978d3e0d.tar.gz
Handle AttributeErrors during parameter aggregation
Plugins do not have their parameters checked in advance, so when we try to aggregate parameters for a plugin, there's a chance it may request an attribute of the FileProcessor that simply does not exist. We catch this and re-raise it but we should also capture it in the checker manager and handle it appropriately there as well.
-rw-r--r--src/flake8/checker.py26
-rw-r--r--src/flake8/exceptions.py20
2 files changed, 41 insertions, 5 deletions
diff --git a/src/flake8/checker.py b/src/flake8/checker.py
index d9f0138..e7a94d8 100644
--- a/src/flake8/checker.py
+++ b/src/flake8/checker.py
@@ -40,10 +40,17 @@ SERIAL_RETRY_ERRNOS = set([
def _run_checks_from_queue(process_queue, results_queue, statistics_queue):
LOG.info('Running checks in parallel')
- for checker in iter(process_queue.get, 'DONE'):
- LOG.info('Checking "%s"', checker.filename)
- checker.run_checks(results_queue, statistics_queue)
- results_queue.put('DONE')
+ try:
+ for checker in iter(process_queue.get, 'DONE'):
+ LOG.info('Checking "%s"', checker.filename)
+ checker.run_checks(results_queue, statistics_queue)
+ except exceptions.PluginRequestedUnknownParameters as exc:
+ print(str(exc))
+ except Exception as exc:
+ LOG.error('Unhandled exception occurred')
+ raise
+ finally:
+ results_queue.put('DONE')
class Manager(object):
@@ -356,6 +363,8 @@ class Manager(object):
except KeyboardInterrupt:
LOG.warning('Flake8 was interrupted by the user')
raise exceptions.EarlyQuit('Early quit while running checks')
+ finally:
+ self._force_cleanup()
def start(self, paths=None):
"""Start checking files.
@@ -447,7 +456,14 @@ class FileChecker(object):
def run_check(self, plugin, **arguments):
"""Run the check in a single plugin."""
LOG.debug('Running %r with %r', plugin, arguments)
- self.processor.keyword_arguments_for(plugin.parameters, arguments)
+ try:
+ self.processor.keyword_arguments_for(plugin.parameters, arguments)
+ except AttributeError as ae:
+ LOG.error('Plugin requested unknown parameters.')
+ raise exceptions.PluginRequestedUnknownParameters(
+ plugin=plugin,
+ exception=ae,
+ )
return plugin.execute(**arguments)
def run_ast_checks(self):
diff --git a/src/flake8/exceptions.py b/src/flake8/exceptions.py
index 2b03795..71738b2 100644
--- a/src/flake8/exceptions.py
+++ b/src/flake8/exceptions.py
@@ -49,6 +49,26 @@ class InvalidSyntax(Flake8Exception):
super(InvalidSyntax, self).__init__(*args, **kwargs)
+class PluginRequestedUnknownParameters(Flake8Exception):
+ """The plugin requested unknown parameters."""
+
+ FORMAT = '"%(name)s" requested unknown parameters causing %(exc)s'
+
+ def __init__(self, *args, **kwargs):
+ """Pop certain keyword arguments for initialization."""
+ self.original_exception = kwargs.pop('exception')
+ self.plugin = kwargs.pop('plugin')
+ super(PluginRequestedUnknownParameters, self).__init__(
+ *args,
+ **kwargs
+ )
+
+ def __str__(self):
+ """Format our exception message."""
+ return self.FORMAT % {'name': self.plugin.plugin_name,
+ 'exc': self.original_exception}
+
+
class HookInstallationError(Flake8Exception):
"""Parent exception for all hooks errors."""