Repository: larsoner/flake8-array-spacing

Issue:
BUG: Installing for one repo breaks others
I installed this to make things work for SciPy, now in MNE-Python I get a bunch of A241's even though we have E241 disabled for MNE-Python. I wonder if we need an explicit `--array-spacing` or so. It's trivial to add but seems like a bit of a hack...

Discussion:

Patch:
diff --git a/README.rst b/README.rst
index fa55f59..3487b30 100644
--- a/README.rst
+++ b/README.rst
@@ -1,2 +1,4 @@
-# flake8-array-spacing
+flake8-array-spacing
+====================
+
 Recast some E2XX errors as A2XX with exceptions for array-like variables
diff --git a/flake8_array_spacing/__init__.py b/flake8_array_spacing/__init__.py
index b615b4f..052b4b0 100644
--- a/flake8_array_spacing/__init__.py
+++ b/flake8_array_spacing/__init__.py
@@ -1,9 +1,9 @@
 import re
-from pycodestyle import (
-    extraneous_whitespace,  # 201, 202
-    whitespace_around_operator,  # 221, 222
-    whitespace_around_comma,  # 241
-)
+import tokenize
+
+from pycodestyle import (extraneous_whitespace, whitespace_around_operator,
+                         whitespace_around_comma)
+from flake8.defaults import NOQA_INLINE_REGEXP
 
 __version__ = '0.1.dev0'
 
@@ -12,30 +12,47 @@ __version__ = '0.1.dev0'
 ARRAY_LIKE_REGEX = re.compile(
     r'[\[(][0-9 ij,+\-*^\/&|\[\]]*[\]),;]'
 )
+FUNC_KINDS = (
+    (extraneous_whitespace, ('E201', 'E202')),
+    (whitespace_around_operator, ('E221', 'E222')),
+    (whitespace_around_comma, ('E241',)),
+)
 
 
 class ArraySpacing(object):
+    """Checker for E2XX variants, ignoring array-like."""
+
     name = 'array-spacing'
     version = __version__
 
-    def __init__(self, logical_line):
+    def __init__(self, logical_line, tokens):
         self.logical_line = logical_line
+        self.tokens = tokens
         self._array_ranges = None  # only compute if necessary
 
     def in_array_like(self, idx):
+        """Determine if in array like range."""
         if self._array_ranges is None:
             self._array_ranges = [
                 (match.start() + 1, match.end() + 1)
                 for match in ARRAY_LIKE_REGEX.finditer(self.logical_line)]
         return any(start <= idx <= end for start, end in self._array_ranges)
 
+    def ignoring(self, kind):
+        """Determine if a kind is being ignored."""
+        for token in self.tokens:
+            if token.type == tokenize.COMMENT:
+                codes = NOQA_INLINE_REGEXP.match(token.string).group('codes')
+                if codes is not None and kind in codes:
+                    return True
+        return False
+
     def __iter__(self):
-        for found, msg in extraneous_whitespace(self.logical_line):
-            if msg[:4] in ('E201', 'E202') and not self.in_array_like(found):
-                yield found, 'A' + msg[1:]
-        for found, msg in whitespace_around_operator(self.logical_line):
-            if msg[:4] in ('E221', 'E222') and not self.in_array_like(found):
-                yield found, 'A' + msg[1:]
-        for found, msg in whitespace_around_comma(self.logical_line):
-            if msg[:4] == 'E241' and not self.in_array_like(found):
-                yield found, 'A' + msg[1:]
+        """Iterate over errors."""
+        for func, kinds in FUNC_KINDS:
+            for found, msg in func(self.logical_line):
+                found_kind = msg[:4]
+                if found_kind in kinds and \
+                        (not self.in_array_like(found)) and \
+                        (not self.ignoring(found_kind)):
+                    yield found, 'A' + msg[1:]


Test patch:
diff --git a/flake8_array_spacing/tests/test_array_spacing.py b/flake8_array_spacing/tests/test_array_spacing.py
index a0a2e01..d411f3f 100644
--- a/flake8_array_spacing/tests/test_array_spacing.py
+++ b/flake8_array_spacing/tests/test_array_spacing.py
@@ -10,6 +10,8 @@ def flake8(path, *args):
         ['flake8', '--select', 'A2',
          '--ignore', 'E201,E202,E203,E221,E222,E241', '.'] + list(args),
         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stderr = proc.stderr.decode().strip()
+    assert stderr == ''
     return proc.stdout.decode().strip(), proc.returncode
 
 
@@ -31,6 +33,8 @@ a_b_pre = 'a = 1\nb = 2\n'
     (a_b_pre + '[a  + b, b]', "./bad.py:3:3: A221 multiple spaces before operator", 1),  # noqa: E501
     (a_b_pre + '[a +  b, b]', "./bad.py:3:5: A222 multiple spaces after operator", 1),  # noqa: E501
     (a_b_pre + '[a,  b]', "./bad.py:3:4: A241 multiple spaces after ','", 1),
+    (a_b_pre + '[a,  b]  # noqa', '', 0),
+    (a_b_pre + '[a,  b]  # noqa: E241', '', 0),
 ])
 def test_array_spacing(line, want_output, want_code, tmpdir):
     """Test some cases."""