mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-16 00:59:52 +00:00
Fix handling of logical lines with noqa
When attempting to centralize all inline NoQA handling in the StyleGuide we inadvertently broke plugins relying on it in combination with checker state. For example, the check for E402 relies both on NoQA and the state to determine if it has seen a non-import line. Placing NoQA on the sole line that is not an import is more elegant than placing it on each of the following import lines. Closes #186
This commit is contained in:
parent
6eca38f2f2
commit
e51fc5458b
5 changed files with 33 additions and 24 deletions
|
|
@ -6,7 +6,12 @@
|
||||||
- Fix indexing of column numbers. We accidentally were starting column indices
|
- Fix indexing of column numbers. We accidentally were starting column indices
|
||||||
at 0 instead of 1.
|
at 0 instead of 1.
|
||||||
|
|
||||||
|
- Fix regression in handling of errors like E402 that rely on a combination of
|
||||||
|
attributes. (See also `GitLab#186`_)
|
||||||
|
|
||||||
|
|
||||||
.. links
|
.. links
|
||||||
.. _GitLab#181:
|
.. _GitLab#181:
|
||||||
https://gitlab.com/pycqa/flake8/issues/181
|
https://gitlab.com/pycqa/flake8/issues/181
|
||||||
|
.. _GitLab#186:
|
||||||
|
https://gitlab.com/pycqa/flake8/issues/186
|
||||||
|
|
|
||||||
4
setup.py
4
setup.py
|
|
@ -7,9 +7,9 @@ import sys
|
||||||
|
|
||||||
import setuptools
|
import setuptools
|
||||||
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src')) # noqa
|
||||||
|
|
||||||
import flake8 # noqa
|
import flake8
|
||||||
|
|
||||||
|
|
||||||
tests_require = ['mock', 'pytest']
|
tests_require = ['mock', 'pytest']
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
"""Constants that define defaults."""
|
"""Constants that define defaults."""
|
||||||
|
import re
|
||||||
|
|
||||||
EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg'
|
EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg'
|
||||||
IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504'
|
IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504'
|
||||||
|
|
@ -15,3 +16,19 @@ STATISTIC_NAMES = (
|
||||||
'physical lines',
|
'physical lines',
|
||||||
'tokens',
|
'tokens',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NOQA_INLINE_REGEXP = re.compile(
|
||||||
|
# We're looking for items that look like this:
|
||||||
|
# ``# noqa``
|
||||||
|
# ``# noqa: E123``
|
||||||
|
# ``# noqa: E123,W451,F921``
|
||||||
|
# ``# NoQA: E123,W451,F921``
|
||||||
|
# ``# NOQA: E123,W451,F921``
|
||||||
|
# We do not care about the ``: `` that follows ``noqa``
|
||||||
|
# We do not care about the casing of ``noqa``
|
||||||
|
# We want a comma-separated list of errors
|
||||||
|
'# noqa(?:: (?P<codes>[A-Z0-9,]+))?',
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
|
|
||||||
|
NOQA_FILE = re.compile(r'\s*# flake8[:=]\s*noqa', re.I)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
import tokenize
|
import tokenize
|
||||||
|
|
||||||
|
|
@ -47,8 +46,6 @@ class FileProcessor(object):
|
||||||
- :attr:`verbose`
|
- :attr:`verbose`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
NOQA_FILE = re.compile(r'\s*# flake8[:=]\s*noqa', re.I)
|
|
||||||
|
|
||||||
def __init__(self, filename, options, lines=None):
|
def __init__(self, filename, options, lines=None):
|
||||||
"""Initialice our file processor.
|
"""Initialice our file processor.
|
||||||
|
|
||||||
|
|
@ -147,6 +144,7 @@ class FileProcessor(object):
|
||||||
self.previous_logical = self.logical_line
|
self.previous_logical = self.logical_line
|
||||||
self.blank_lines = 0
|
self.blank_lines = 0
|
||||||
self.tokens = []
|
self.tokens = []
|
||||||
|
self.noqa = False
|
||||||
|
|
||||||
def build_logical_line_tokens(self):
|
def build_logical_line_tokens(self):
|
||||||
"""Build the mapping, comments, and logical line lists."""
|
"""Build the mapping, comments, and logical line lists."""
|
||||||
|
|
@ -189,9 +187,12 @@ class FileProcessor(object):
|
||||||
def build_logical_line(self):
|
def build_logical_line(self):
|
||||||
"""Build a logical line from the current tokens list."""
|
"""Build a logical line from the current tokens list."""
|
||||||
comments, logical, mapping_list = self.build_logical_line_tokens()
|
comments, logical, mapping_list = self.build_logical_line_tokens()
|
||||||
|
joined_comments = ''.join(comments)
|
||||||
self.logical_line = ''.join(logical)
|
self.logical_line = ''.join(logical)
|
||||||
|
if defaults.NOQA_INLINE_REGEXP.search(joined_comments):
|
||||||
|
self.noqa = True
|
||||||
self.statistics['logical lines'] += 1
|
self.statistics['logical lines'] += 1
|
||||||
return ''.join(comments), self.logical_line, mapping_list
|
return joined_comments, self.logical_line, mapping_list
|
||||||
|
|
||||||
def split_line(self, token):
|
def split_line(self, token):
|
||||||
"""Split a physical line's line based on new-lines.
|
"""Split a physical line's line based on new-lines.
|
||||||
|
|
@ -316,12 +317,12 @@ class FileProcessor(object):
|
||||||
"""Check if ``# flake8: noqa`` is in the file to be ignored.
|
"""Check if ``# flake8: noqa`` is in the file to be ignored.
|
||||||
|
|
||||||
:returns:
|
:returns:
|
||||||
True if a line matches :attr:`FileProcessor.NOQA_FILE`,
|
True if a line matches :attr:`defaults.NOQA_FILE`,
|
||||||
otherwise False
|
otherwise False
|
||||||
:rtype:
|
:rtype:
|
||||||
bool
|
bool
|
||||||
"""
|
"""
|
||||||
ignore_file = self.NOQA_FILE.search
|
ignore_file = defaults.NOQA_FILE.search
|
||||||
return any(ignore_file(line) for line in self.lines)
|
return any(ignore_file(line) for line in self.lines)
|
||||||
|
|
||||||
def strip_utf_bom(self):
|
def strip_utf_bom(self):
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import collections
|
||||||
import enum
|
import enum
|
||||||
import linecache
|
import linecache
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
|
|
||||||
|
from flake8 import defaults
|
||||||
from flake8 import statistics
|
from flake8 import statistics
|
||||||
from flake8 import utils
|
from flake8 import utils
|
||||||
|
|
||||||
|
|
@ -53,20 +53,6 @@ Error = collections.namedtuple(
|
||||||
class StyleGuide(object):
|
class StyleGuide(object):
|
||||||
"""Manage a Flake8 user's style guide."""
|
"""Manage a Flake8 user's style guide."""
|
||||||
|
|
||||||
NOQA_INLINE_REGEXP = re.compile(
|
|
||||||
# We're looking for items that look like this:
|
|
||||||
# ``# noqa``
|
|
||||||
# ``# noqa: E123``
|
|
||||||
# ``# noqa: E123,W451,F921``
|
|
||||||
# ``# NoQA: E123,W451,F921``
|
|
||||||
# ``# NOQA: E123,W451,F921``
|
|
||||||
# We do not care about the ``: `` that follows ``noqa``
|
|
||||||
# We do not care about the casing of ``noqa``
|
|
||||||
# We want a comma-separated list of errors
|
|
||||||
'# noqa(?:: (?P<codes>[A-Z0-9,]+))?',
|
|
||||||
re.IGNORECASE
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, options, listener_trie, formatter):
|
def __init__(self, options, listener_trie, formatter):
|
||||||
"""Initialize our StyleGuide.
|
"""Initialize our StyleGuide.
|
||||||
|
|
||||||
|
|
@ -177,7 +163,7 @@ class StyleGuide(object):
|
||||||
if physical_line is None:
|
if physical_line is None:
|
||||||
physical_line = linecache.getline(error.filename,
|
physical_line = linecache.getline(error.filename,
|
||||||
error.line_number)
|
error.line_number)
|
||||||
noqa_match = self.NOQA_INLINE_REGEXP.search(physical_line)
|
noqa_match = defaults.NOQA_INLINE_REGEXP.search(physical_line)
|
||||||
if noqa_match is None:
|
if noqa_match is None:
|
||||||
LOG.debug('%r is not inline ignored', error)
|
LOG.debug('%r is not inline ignored', error)
|
||||||
return False
|
return False
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue