Suppport per-file '# flake8: noqa [ignore_codes]'

This commit is contained in:
Wes Turner 2020-02-18 04:51:05 -05:00
parent 8f9b4931b9
commit 6b7cfba3e0
5 changed files with 45 additions and 10 deletions

View file

@ -136,6 +136,13 @@ the errors in that file will show up without having to modify our
configuration. Both exist so we can choose which is better for us. configuration. Both exist so we can choose which is better for us.
Ignoring Specific Errors within a File
--------------------------------------
.. code-block:: python
# flake8: noqa E221,E222
Selecting Violations with Flake8 Selecting Violations with Flake8
================================ ================================

View file

@ -1,5 +1,6 @@
"""Checker Manager and Checker classes.""" """Checker Manager and Checker classes."""
import collections import collections
import copy
import errno import errno
import itertools import itertools
import logging import logging
@ -368,7 +369,7 @@ class FileChecker(object):
:type options: :type options:
argparse.Namespace argparse.Namespace
""" """
self.options = options self.options = copy.copy(options)
self.filename = filename self.filename = filename
self.checks = checks self.checks = checks
# fmt: off # fmt: off
@ -384,7 +385,13 @@ class FileChecker(object):
self.should_process = False self.should_process = False
if self.processor is not None: if self.processor is not None:
self.display_name = self.processor.filename self.display_name = self.processor.filename
self.should_process = not self.processor.should_ignore_file() should_ignore = self.processor.should_ignore_file()
if isinstance(should_ignore, list):
self.options.ignore += should_ignore
self.should_process = True
else:
self.should_process = not should_ignore
self.statistics["physical lines"] = len(self.processor.lines) self.statistics["physical lines"] = len(self.processor.lines)
def __repr__(self): # type: () -> str def __repr__(self): # type: () -> str

View file

@ -40,4 +40,5 @@ NOQA_INLINE_REGEXP = re.compile(
re.IGNORECASE, re.IGNORECASE,
) )
NOQA_FILE = re.compile(r"\s*# flake8[:=]\s*noqa", re.I) NOQA_FILE = re.compile(
r"\s*# flake8[:=]\s*noqa(?P<codes>\s*([A-Z]+[0-9]+(?:[,\s]+)?)+)?", re.I)

View file

@ -338,18 +338,26 @@ class FileProcessor(object):
def should_ignore_file(self): def should_ignore_file(self):
# type: () -> bool # type: () -> bool
"""Check if ``flake8: noqa`` is in the file to be ignored. """Check if ``flake8: noqa [Codes]`` is in the file to be ignored.
:returns: :returns:
True if a line matches :attr:`defaults.NOQA_FILE`, True if a line matches :attr:`defaults.NOQA_FILE`,
or a list of codes to ignore if specified,
otherwise False otherwise False
:rtype: :rtype:
bool bool
""" """
if not self.options.disable_noqa and any( if not self.options.disable_noqa:
defaults.NOQA_FILE.match(line) for line in self.lines found_flake_noqa_line = False
): ignore_codes = []
return True for line in self.lines:
matchobj = defaults.NOQA_FILE.match(line)
if matchobj:
found_flake_noqa_line = True
codes = matchobj.groupdict(default="")["codes"].split(",")
codes = (code.strip() for code in codes)
ignore_codes.extend(code for code in codes if code)
return ignore_codes or found_flake_noqa_line
elif any(defaults.NOQA_FILE.search(line) for line in self.lines): elif any(defaults.NOQA_FILE.search(line) for line in self.lines):
LOG.warning( LOG.warning(
"Detected `flake8: noqa` on line with code. To ignore an " "Detected `flake8: noqa` on line with code. To ignore an "

View file

@ -61,6 +61,8 @@ def test_strip_utf_bom(first_line, default_options):
(['\xEF\xBB\xBF"""Module docstring."""\n'], False), (['\xEF\xBB\xBF"""Module docstring."""\n'], False),
([u'\uFEFF"""Module docstring."""\n'], False), ([u'\uFEFF"""Module docstring."""\n'], False),
(['#!/usr/bin/python', '# flake8 is great', 'a = 1'], False), (['#!/usr/bin/python', '# flake8 is great', 'a = 1'], False),
(['#!/usr/bin/python', '# flake8: noqa E221'], ["E221"]),
(['#!/usr/bin/python', '# flake8: noqa E220,E221'], ["E220", "E221"]),
(['#!/usr/bin/python', '# flake8: noqa', 'a = 1'], True), (['#!/usr/bin/python', '# flake8: noqa', 'a = 1'], True),
(['#!/usr/bin/python', '# flake8:noqa', 'a = 1'], True), (['#!/usr/bin/python', '# flake8:noqa', 'a = 1'], True),
(['# flake8: noqa', '#!/usr/bin/python', 'a = 1'], True), (['# flake8: noqa', '#!/usr/bin/python', 'a = 1'], True),
@ -73,14 +75,24 @@ def test_strip_utf_bom(first_line, default_options):
def test_should_ignore_file(lines, expected, default_options): def test_should_ignore_file(lines, expected, default_options):
"""Verify that we ignore a file if told to.""" """Verify that we ignore a file if told to."""
file_processor = processor.FileProcessor('-', default_options, lines) file_processor = processor.FileProcessor('-', default_options, lines)
assert file_processor.should_ignore_file() is expected assert file_processor.should_ignore_file() == expected
def test_should_ignore_file_to_handle_disable_noqa(default_options): def test_should_ignore_file_to_handle_disable_noqa(default_options):
"""Verify that we ignore a file if told to.""" """Verify that we ignore a file if told to."""
lines = ['# flake8: noqa'] lines = ['# flake8: noqa']
file_processor = processor.FileProcessor('-', default_options, lines) file_processor = processor.FileProcessor('-', default_options, lines)
assert file_processor.should_ignore_file() is True assert file_processor.should_ignore_file()
default_options.disable_noqa = True
file_processor = processor.FileProcessor('-', default_options, lines)
assert file_processor.should_ignore_file() is False
def test_should_ignore_file_to_handle_disable_noqa_opts(default_options):
"""Verify that we ignore a file if told to."""
lines = ['# flake8: noqa E220,E221']
file_processor = processor.FileProcessor('-', default_options, lines)
assert file_processor.should_ignore_file() == ["E220", "E221"]
default_options.disable_noqa = True default_options.disable_noqa = True
file_processor = processor.FileProcessor('-', default_options, lines) file_processor = processor.FileProcessor('-', default_options, lines)
assert file_processor.should_ignore_file() is False assert file_processor.should_ignore_file() is False