summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Cordasco <graffatcolmingov@gmail.com>2015-08-19 20:32:52 -0500
committerIan Cordasco <graffatcolmingov@gmail.com>2015-08-19 20:32:52 -0500
commit1c6c1f51163784005dac358d60ecb8781d726151 (patch)
treedacdf0c8bd3f55862d9a2ed5122192fcc12f4623
parente847ed8bf070dc4d661746bc1957bbebd3d0ae5c (diff)
downloadflake8-bug/74.tar.gz
Refactor how we use StyleGuides for better error recoverybug/74
In bug 74 we discovered that there are some less than ideal problems around our use of multiprocessing. This is a first attempt at fixing 74 by using a fake StyleGuide object which proxies to the real one, and will catch and handle exceptions and then posibly retry the operation we were trying to perform in the first place. Currently we're only implementing that logic for StyleGuide.check_files but we should be careful to implement this in other functions used in hooks and elsewhere. Note: there may be a simpler way to fix this with a context manager that will do the right thing. That may also prove simpler to implement but that will have a much larger impact on the code-base than this. Related to bug #74
-rw-r--r--flake8/engine.py64
1 files changed, 62 insertions, 2 deletions
diff --git a/flake8/engine.py b/flake8/engine.py
index d18cc2c..cb0702a 100644
--- a/flake8/engine.py
+++ b/flake8/engine.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
-import re
+import errno
import platform
+import re
import warnings
import pep8
@@ -81,7 +82,7 @@ def get_parser():
return parser, options_hooks
-class StyleGuide(pep8.StyleGuide):
+class NoQAStyleGuide(pep8.StyleGuide):
def input_file(self, filename, lines=None, expected=None, line_offset=0):
"""Run all checks on a Python source file."""
@@ -95,6 +96,65 @@ class StyleGuide(pep8.StyleGuide):
return fchecker.check_all(expected=expected, line_offset=line_offset)
+class StyleGuide(object):
+ """A wrapper StyleGuide object for Flake8 usage.
+
+ This allows for OSErrors to be caught in the styleguide and special logic
+ to be used to handle those errors.
+ """
+
+ # Reasoning for error numbers is in-line below
+ turn_off_multiprocessing_errors = set([
+ # ENOSPC: Added by sigmavirus24
+ # > On some operating systems (OSX), multiprocessing may cause an
+ # > ENOSPC error while trying to trying to create a Semaphore.
+ # > In those cases, we should replace the customized Queue Report
+ # > class with pep8's StandardReport class to ensure users don't run
+ # > into this problem.
+ # > (See also: https://gitlab.com/pycqa/flake8/issues/74)
+ errno.ENOSPC,
+ # NOTE(sigmavirus24): When adding to this list, include the reasoning
+ # on the lines before the error code and always append your error
+ # code. Further, please always add a trailing `,` to reduce the visual
+ # noise in diffs.
+ ])
+
+ def __init__(self, **kwargs):
+ self._styleguide = NoQAStyleGuide(**kwargs)
+
+ @property
+ def options(self):
+ return self._styleguide.options
+
+ @property
+ def paths(self):
+ return self._styleguide.paths
+
+ def check_files(self, paths=None):
+ try:
+ return self._styleguide.check_files(paths)
+ except IOError as ioerr:
+ if ioerr.errno in self.turn_off_multiprocessing_errors:
+ self.init_report(pep8.StandardReport)
+ else:
+ raise
+ return self._styleguide.check_files(paths)
+
+ def excluded(self, filename, parent=None):
+ return self._styleguide.excluded(filename, parent=parent)
+
+ def init_report(self, reporter=None):
+ return self._styleguide.init_report(reporter)
+
+ def input_file(self, filename, lines=None, expected=None, line_offset=0):
+ return self._styleguide.input_file(
+ filename=filename,
+ lines=lines,
+ expected=expected,
+ line_offset=0,
+ )
+
+
def _disable_extensions(parser, options):
ignored_extensions = set(getattr(parser, 'ignored_extensions', []))
# Remove any of the selected extensions from the extensions ignored by