Skip to content

Commit 6425777

Browse files
hippo91PCManticore
authored andcommitted
Fixes `pylint disable=fixme directives ignored for comments following the last statement in a file (#1740)
Fixes #1681
1 parent b4c17e8 commit 6425777

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ What's New in Pylint 1.8?
164164
modules when checking import order.
165165
Close #1702
166166

167+
* Fix ``pylint disable=fixme`` directives ignored for comments following the
168+
last statement in a file.
169+
Close #1681
170+
167171
* Fix ``line-too-long`` message deactivated by wrong disable directive.
168172
The directive ``disable=fixme`` doesn't deactivate anymore the emission
169173
of ``line-too-long`` message for long commented lines.

doc/whatsnew/1.8.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,9 @@ Other Changes
358358
With this fix, pylint distinguishes first and third party modules when checking
359359
import order.
360360

361+
* Fix the ignored ``pylint disable=fixme`` directives for comments following
362+
the last statement in a file.
363+
361364
* Fix ``line-too-long`` message deactivated by wrong disable directive.
362365
The directive ``disable=fixme`` doesn't deactivate anymore the emission
363366
of ``line-too-long`` message for long commented lines.

pylint/checkers/misc.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from pylint.interfaces import IRawChecker
1919
from pylint.checkers import BaseChecker
20+
from pylint.utils import OPTION_RGX
2021

2122

2223
MSGS = {
@@ -50,7 +51,22 @@ class EncodingChecker(BaseChecker):
5051
'help': ('List of note tags to take in consideration, '
5152
'separated by a comma.')}),)
5253

53-
def _check_note(self, notes, lineno, line):
54+
def _check_note(self, notes, lineno, line, module_last_lineno):
55+
"""
56+
Add the message 'fixme' in case a note is found in the line.
57+
58+
:param notes: regular expression object matching any notes
59+
(XXX, TODO, FIXME) behind a '#'
60+
:type notes: re.pattern object
61+
:param lineno: line number
62+
:type lineno: int
63+
:param line: line to be checked
64+
:type line: str
65+
:param module_last_lineno: last line number of the module as parsed by astroid
66+
(may be different from real last line number in case
67+
commented lines exist at the end of the module)
68+
:type module_last_lineno: int
69+
"""
5470
# First, simply check if the notes are in the line at all. This is an
5571
# optimisation to prevent using the regular expression on every line,
5672
# but rather only on lines which may actually contain one of the notes.
@@ -65,8 +81,25 @@ def _check_note(self, notes, lineno, line):
6581
match = notes.search(line)
6682
if not match:
6783
return
68-
self.add_message('fixme', args=line[match.start(1):].rstrip(),
69-
line=lineno)
84+
# In case the module ends with commented lines, the astroid parser
85+
# don't take into account those lines, then:
86+
# - the line number of those lines is greater than the
87+
#  module last line number (module.tolineno)
88+
# - astroid module object can't inform pylint
89+
# of disabled messages in those extra lines.
90+
if lineno > module_last_lineno:
91+
disable_option_match = OPTION_RGX.search(line)
92+
if disable_option_match:
93+
try:
94+
_, value = disable_option_match.group(1).split('=', 1)
95+
values = [_val.strip().upper() for _val in value.split(',')]
96+
if set(values) & set(self.config.notes):
97+
return
98+
except ValueError:
99+
self.add_message('bad-inline-option',
100+
args=disable_option_match.group(1).strip(), line=line)
101+
return
102+
self.add_message('fixme', args=line[match.start(1):].rstrip(), line=lineno)
70103

71104
def _check_encoding(self, lineno, line, file_encoding):
72105
try:
@@ -100,7 +133,7 @@ def process_module(self, module):
100133
for lineno, line in enumerate(stream):
101134
line = self._check_encoding(lineno + 1, line, encoding)
102135
if line is not None and notes:
103-
self._check_note(notes, lineno + 1, line)
136+
self._check_note(notes, lineno + 1, line, module.tolineno)
104137

105138

106139
def register(linter):

pylint/test/functional/fixme.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
# -*- encoding=utf-8 -*-
12
# pylint: disable=missing-docstring, unused-variable
23

3-
44
# +1: [fixme]
55
# FIXME: beep
66

@@ -16,3 +16,6 @@ def function():
1616
xxx = "n/a" # XXX: Fix this later
1717
# +1: [fixme]
1818
#FIXME: no space after hash
19+
#FIXME: in fact nothing to fix #pylint: disable=fixme
20+
#TODO: in fact nothing to do #pylint: disable=fixme
21+
#TODO: in fact nothing to do #pylint: disable=line-too-long, fixme

0 commit comments

Comments
 (0)