summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhippo91 <guillaume.peillex@gmail.com>2017-12-11 11:52:18 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2017-12-11 11:52:18 +0100
commit642577760a2afb355ccfb1f93e21a5bd1e37a4ed (patch)
treefc87a6897ef51272853cb8f8665ff913ba7dbfe4
parentb4c17e800439ebc6ae5dd5363883035d0311f37b (diff)
downloadpylint-git-642577760a2afb355ccfb1f93e21a5bd1e37a4ed.tar.gz
Fixes ``pylint disable=fixme` directives ignored for comments following the last statement in a file (#1740)
Fixes #1681
-rw-r--r--ChangeLog4
-rw-r--r--doc/whatsnew/1.8.rst3
-rw-r--r--pylint/checkers/misc.py41
-rw-r--r--pylint/test/functional/fixme.py5
4 files changed, 48 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a4326a8b..516add570 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -164,6 +164,10 @@ What's New in Pylint 1.8?
modules when checking import order.
Close #1702
+ * Fix ``pylint disable=fixme`` directives ignored for comments following the
+ last statement in a file.
+ Close #1681
+
* Fix ``line-too-long`` message deactivated by wrong disable directive.
The directive ``disable=fixme`` doesn't deactivate anymore the emission
of ``line-too-long`` message for long commented lines.
diff --git a/doc/whatsnew/1.8.rst b/doc/whatsnew/1.8.rst
index a25195c18..be4740439 100644
--- a/doc/whatsnew/1.8.rst
+++ b/doc/whatsnew/1.8.rst
@@ -358,6 +358,9 @@ Other Changes
With this fix, pylint distinguishes first and third party modules when checking
import order.
+* Fix the ignored ``pylint disable=fixme`` directives for comments following
+ the last statement in a file.
+
* Fix ``line-too-long`` message deactivated by wrong disable directive.
The directive ``disable=fixme`` doesn't deactivate anymore the emission
of ``line-too-long`` message for long commented lines.
diff --git a/pylint/checkers/misc.py b/pylint/checkers/misc.py
index 827b06748..4103069d8 100644
--- a/pylint/checkers/misc.py
+++ b/pylint/checkers/misc.py
@@ -17,6 +17,7 @@ import six
from pylint.interfaces import IRawChecker
from pylint.checkers import BaseChecker
+from pylint.utils import OPTION_RGX
MSGS = {
@@ -50,7 +51,22 @@ class EncodingChecker(BaseChecker):
'help': ('List of note tags to take in consideration, '
'separated by a comma.')}),)
- def _check_note(self, notes, lineno, line):
+ def _check_note(self, notes, lineno, line, module_last_lineno):
+ """
+ Add the message 'fixme' in case a note is found in the line.
+
+ :param notes: regular expression object matching any notes
+ (XXX, TODO, FIXME) behind a '#'
+ :type notes: re.pattern object
+ :param lineno: line number
+ :type lineno: int
+ :param line: line to be checked
+ :type line: str
+ :param module_last_lineno: last line number of the module as parsed by astroid
+ (may be different from real last line number in case
+ commented lines exist at the end of the module)
+ :type module_last_lineno: int
+ """
# First, simply check if the notes are in the line at all. This is an
# optimisation to prevent using the regular expression on every line,
# but rather only on lines which may actually contain one of the notes.
@@ -65,8 +81,25 @@ class EncodingChecker(BaseChecker):
match = notes.search(line)
if not match:
return
- self.add_message('fixme', args=line[match.start(1):].rstrip(),
- line=lineno)
+ # In case the module ends with commented lines, the astroid parser
+ # don't take into account those lines, then:
+ # - the line number of those lines is greater than the
+ #  module last line number (module.tolineno)
+ # - astroid module object can't inform pylint
+ # of disabled messages in those extra lines.
+ if lineno > module_last_lineno:
+ disable_option_match = OPTION_RGX.search(line)
+ if disable_option_match:
+ try:
+ _, value = disable_option_match.group(1).split('=', 1)
+ values = [_val.strip().upper() for _val in value.split(',')]
+ if set(values) & set(self.config.notes):
+ return
+ except ValueError:
+ self.add_message('bad-inline-option',
+ args=disable_option_match.group(1).strip(), line=line)
+ return
+ self.add_message('fixme', args=line[match.start(1):].rstrip(), line=lineno)
def _check_encoding(self, lineno, line, file_encoding):
try:
@@ -100,7 +133,7 @@ class EncodingChecker(BaseChecker):
for lineno, line in enumerate(stream):
line = self._check_encoding(lineno + 1, line, encoding)
if line is not None and notes:
- self._check_note(notes, lineno + 1, line)
+ self._check_note(notes, lineno + 1, line, module.tolineno)
def register(linter):
diff --git a/pylint/test/functional/fixme.py b/pylint/test/functional/fixme.py
index 9d5d966bf..6e2fb241c 100644
--- a/pylint/test/functional/fixme.py
+++ b/pylint/test/functional/fixme.py
@@ -1,6 +1,6 @@
+# -*- encoding=utf-8 -*-
# pylint: disable=missing-docstring, unused-variable
-
# +1: [fixme]
# FIXME: beep
@@ -16,3 +16,6 @@ def function():
xxx = "n/a" # XXX: Fix this later
# +1: [fixme]
#FIXME: no space after hash
+ #FIXME: in fact nothing to fix #pylint: disable=fixme
+ #TODO: in fact nothing to do #pylint: disable=fixme
+ #TODO: in fact nothing to do #pylint: disable=line-too-long, fixme