mirror of
https://github.com/PyCQA/flake8.git
synced 2026-03-31 03:06:53 +00:00
Wire up last pieces to make --diff work
To make sure we reduce as much duplication as possible, we parse the diff output in our main command-line Application. That then takes responsibility for telling the StyleGuide about the line numbers that are in the diff as well as telling the file checker manager which files from the diff should be checked.
This commit is contained in:
parent
0cdde196e8
commit
59c3ba75e6
4 changed files with 84 additions and 8 deletions
|
|
@ -280,10 +280,15 @@ class Manager(object):
|
|||
LOG.warning('Running in serial after OS exception, %r', oserr)
|
||||
self.run_serial()
|
||||
|
||||
def start(self):
|
||||
"""Start checking files."""
|
||||
def start(self, paths=None):
|
||||
"""Start checking files.
|
||||
|
||||
:param list paths:
|
||||
Path names to check. This is passed directly to
|
||||
:meth:`~Manager.make_checkers`.
|
||||
"""
|
||||
LOG.info('Making checkers')
|
||||
self.make_checkers()
|
||||
self.make_checkers(paths)
|
||||
if not self.using_multiprocessing:
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import flake8
|
|||
from flake8 import checker
|
||||
from flake8 import defaults
|
||||
from flake8 import style_guide
|
||||
from flake8 import utils
|
||||
from flake8.options import aggregator
|
||||
from flake8.options import manager
|
||||
from flake8.plugins import manager as plugin_manager
|
||||
|
|
@ -266,6 +267,11 @@ class Application(object):
|
|||
#: flake8
|
||||
self.result_count = 0
|
||||
|
||||
#: Whether the program is processing a diff or not
|
||||
self.running_against_diff = False
|
||||
#: The parsed diff information
|
||||
self.parsed_diff = {}
|
||||
|
||||
def exit(self):
|
||||
# type: () -> NoneType
|
||||
"""Handle finalization and exiting the program.
|
||||
|
|
@ -318,6 +324,10 @@ class Application(object):
|
|||
self.option_manager, argv
|
||||
)
|
||||
|
||||
self.running_against_diff = self.options.diff
|
||||
if self.running_against_diff:
|
||||
self.parsed_diff = utils.parse_unified_diff()
|
||||
|
||||
self.check_plugins.provide_options(self.option_manager, self.options,
|
||||
self.args)
|
||||
self.listening_plugins.provide_options(self.option_manager,
|
||||
|
|
@ -349,6 +359,9 @@ class Application(object):
|
|||
self.options, self.listener_trie, self.formatter
|
||||
)
|
||||
|
||||
if self.running_against_diff:
|
||||
self.guide.add_diff_ranges(self.parsed_diff)
|
||||
|
||||
def make_file_checker_manager(self):
|
||||
# type: () -> NoneType
|
||||
"""Initialize our FileChecker Manager."""
|
||||
|
|
@ -367,7 +380,10 @@ class Application(object):
|
|||
:class:`~flake8.checker.Manger` instance run the checks it is
|
||||
managing.
|
||||
"""
|
||||
self.file_checker_manager.start()
|
||||
files = None
|
||||
if self.running_against_diff:
|
||||
files = list(sorted(self.parsed_diff.keys()))
|
||||
self.file_checker_manager.start(files)
|
||||
self.file_checker_manager.run()
|
||||
LOG.info('Finished running')
|
||||
self.file_checker_manager.stop()
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ class StyleGuide(object):
|
|||
self._selected = tuple(options.select)
|
||||
self._ignored = tuple(options.ignore)
|
||||
self._decision_cache = {}
|
||||
self._parsed_diff = {}
|
||||
|
||||
def is_user_selected(self, code):
|
||||
# type: (str) -> Union[Selected, Ignored]
|
||||
|
|
@ -194,17 +195,68 @@ class StyleGuide(object):
|
|||
error, codes_str)
|
||||
return False
|
||||
|
||||
def is_in_diff(self, error):
|
||||
# type: (Error) -> bool
|
||||
"""Determine if an error is included in a diff's line ranges.
|
||||
|
||||
This function relies on the parsed data added via
|
||||
:meth:`~StyleGuide.add_diff_ranges`. If that has not been called and
|
||||
we are not evaluating files in a diff, then this will always return
|
||||
True. If there are diff ranges, then this will return True if the
|
||||
line number in the error falls inside one of the ranges for the file
|
||||
(and assuming the file is part of the diff data). If there are diff
|
||||
ranges, this will return False if the file is not part of the diff
|
||||
data or the line number of the error is not in any of the ranges of
|
||||
the diff.
|
||||
|
||||
:returns:
|
||||
True if there is no diff or if the error is in the diff's line
|
||||
number ranges. False if the error's line number falls outside
|
||||
the diff's line number ranges.
|
||||
:rtype:
|
||||
bool
|
||||
"""
|
||||
if not self._parsed_diff:
|
||||
return True
|
||||
|
||||
# NOTE(sigmavirus24): The parsed diff will be a defaultdict with
|
||||
# a set as the default value (if we have received it from
|
||||
# flake8.utils.parse_unified_diff). In that case ranges below
|
||||
# could be an empty set (which is False-y) or if someone else
|
||||
# is using this API, it could be None. If we could guarantee one
|
||||
# or the other, we would check for it more explicitly.
|
||||
line_numbers = self._parsed_diff.get(error.filename)
|
||||
if not line_numbers:
|
||||
return False
|
||||
|
||||
return error.line_number in line_numbers
|
||||
|
||||
def handle_error(self, code, filename, line_number, column_number, text,
|
||||
physical_line=None):
|
||||
# type: (str, str, int, int, str) -> NoneType
|
||||
"""Handle an error reported by a check."""
|
||||
error = Error(code, filename, line_number, column_number, text,
|
||||
physical_line)
|
||||
if (self.should_report_error(error.code) is Decision.Selected and
|
||||
self.is_inline_ignored(error) is False):
|
||||
error_is_selected = (self.should_report_error(error.code) is
|
||||
Decision.Selected)
|
||||
is_not_inline_ignored = self.is_inline_ignored(error) is False
|
||||
is_included_in_diff = self.is_in_diff(error)
|
||||
if (error_is_selected and is_not_inline_ignored and
|
||||
is_included_in_diff):
|
||||
self.formatter.handle(error)
|
||||
self.listener.notify(error.code, error)
|
||||
|
||||
def add_diff_ranges(self, diffinfo):
|
||||
"""Update the StyleGuide to filter out information not in the diff.
|
||||
|
||||
This provides information to the StyleGuide so that only the errors
|
||||
in the line number ranges are reported.
|
||||
|
||||
:param dict diffinfo:
|
||||
Dictionary mapping filenames to sets of line number ranges.
|
||||
"""
|
||||
self._parsed_diff = diffinfo
|
||||
|
||||
# Should separate style guide logic from code that runs checks
|
||||
# StyleGuide should manage select/ignore logic as well as include/exclude
|
||||
# logic. See also https://github.com/PyCQA/pep8/pull/433
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ def stdin_get_value():
|
|||
else:
|
||||
cached_type = io.StringIO
|
||||
stdin_get_value.cached_stdin = cached_type(stdin_value)
|
||||
cached_value = stdin_get_value.cached_stdin
|
||||
return cached_value.getvalue()
|
||||
|
||||
|
||||
|
|
@ -78,8 +79,10 @@ def parse_unified_diff():
|
|||
# type: () -> List[str]
|
||||
"""Parse the unified diff passed on stdin.
|
||||
|
||||
:returns: dictionary mapping file names to sets of ranges
|
||||
:rtype: dict
|
||||
:returns:
|
||||
dictionary mapping file names to sets of line numbers
|
||||
:rtype:
|
||||
dict
|
||||
"""
|
||||
diff = stdin_get_value()
|
||||
number_of_rows = None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue