Skip to content

Commit 40ddfab

Browse files
Move process_tokens to _MessageStateHandler (#6546)
Co-authored-by: Pierre Sassoulas <[email protected]>
1 parent 8df920b commit 40ddfab

File tree

2 files changed

+98
-97
lines changed

2 files changed

+98
-97
lines changed

pylint/lint/message_state_handler.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from __future__ import annotations
66

77
import sys
8+
import tokenize
89
from typing import TYPE_CHECKING
910

1011
from pylint import exceptions, interfaces
@@ -17,6 +18,12 @@
1718
)
1819
from pylint.message import MessageDefinition
1920
from pylint.typing import ManagedMessage
21+
from pylint.utils.pragma_parser import (
22+
OPTION_PO,
23+
InvalidPragmaError,
24+
UnRecognizedOptionError,
25+
parse_pragma,
26+
)
2027

2128
if sys.version_info >= (3, 8):
2229
from typing import Literal
@@ -43,6 +50,7 @@ def __init__(self, linter: PyLinter) -> None:
4350
"disable-msg": self._options_methods["disable"],
4451
"enable-msg": self._options_methods["enable"],
4552
}
53+
self._pragma_lineno: dict[str, int] = {}
4654

4755
def _set_one_msg_status(
4856
self, scope: str, msg: MessageDefinition, line: int | None, enable: bool
@@ -316,3 +324,89 @@ def is_message_enabled(
316324
# for now.
317325
msgids = [msg_descr]
318326
return any(self._is_one_message_enabled(msgid, line) for msgid in msgids)
327+
328+
def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None:
329+
"""Process tokens from the current module to search for module/block level
330+
options.
331+
332+
See func_block_disable_msg.py test case for expected behaviour.
333+
"""
334+
control_pragmas = {"disable", "disable-next", "enable"}
335+
prev_line = None
336+
saw_newline = True
337+
seen_newline = True
338+
for (tok_type, content, start, _, _) in tokens:
339+
if prev_line and prev_line != start[0]:
340+
saw_newline = seen_newline
341+
seen_newline = False
342+
343+
prev_line = start[0]
344+
if tok_type in (tokenize.NL, tokenize.NEWLINE):
345+
seen_newline = True
346+
347+
if tok_type != tokenize.COMMENT:
348+
continue
349+
match = OPTION_PO.search(content)
350+
if match is None:
351+
continue
352+
try:
353+
for pragma_repr in parse_pragma(match.group(2)):
354+
if pragma_repr.action in {"disable-all", "skip-file"}:
355+
if pragma_repr.action == "disable-all":
356+
self.linter.add_message(
357+
"deprecated-pragma",
358+
line=start[0],
359+
args=("disable-all", "skip-file"),
360+
)
361+
self.linter.add_message("file-ignored", line=start[0])
362+
self._ignore_file = True
363+
return
364+
try:
365+
meth = self._options_methods[pragma_repr.action]
366+
except KeyError:
367+
meth = self._bw_options_methods[pragma_repr.action]
368+
# found a "(dis|en)able-msg" pragma deprecated suppression
369+
self.linter.add_message(
370+
"deprecated-pragma",
371+
line=start[0],
372+
args=(
373+
pragma_repr.action,
374+
pragma_repr.action.replace("-msg", ""),
375+
),
376+
)
377+
for msgid in pragma_repr.messages:
378+
# Add the line where a control pragma was encountered.
379+
if pragma_repr.action in control_pragmas:
380+
self._pragma_lineno[msgid] = start[0]
381+
382+
if (pragma_repr.action, msgid) == ("disable", "all"):
383+
self.linter.add_message(
384+
"deprecated-pragma",
385+
line=start[0],
386+
args=("disable=all", "skip-file"),
387+
)
388+
self.linter.add_message("file-ignored", line=start[0])
389+
self._ignore_file = True
390+
return
391+
# If we did not see a newline between the previous line and now,
392+
# we saw a backslash so treat the two lines as one.
393+
l_start = start[0]
394+
if not saw_newline:
395+
l_start -= 1
396+
try:
397+
meth(msgid, "module", l_start)
398+
except exceptions.UnknownMessageError:
399+
msg = f"{pragma_repr.action}. Don't recognize message {msgid}."
400+
self.linter.add_message(
401+
"bad-option-value", args=msg, line=start[0]
402+
)
403+
except UnRecognizedOptionError as err:
404+
self.linter.add_message(
405+
"unrecognized-inline-option", args=err.token, line=start[0]
406+
)
407+
continue
408+
except InvalidPragmaError as err:
409+
self.linter.add_message(
410+
"bad-inline-option", args=err.token, line=start[0]
411+
)
412+
continue

pylint/lint/pylinter.py

Lines changed: 4 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@
5757
Options,
5858
)
5959
from pylint.utils import ASTWalker, FileState, LinterStats, utils
60-
from pylint.utils.pragma_parser import (
61-
OPTION_PO,
62-
InvalidPragmaError,
63-
UnRecognizedOptionError,
64-
parse_pragma,
65-
)
6660

6761
if sys.version_info >= (3, 8):
6862
from typing import Protocol
@@ -226,7 +220,7 @@ class PyLinter(
226220
_ArgumentsManager,
227221
_MessageStateHandler,
228222
reporters.ReportsHandlerMixIn,
229-
checkers.BaseTokenChecker,
223+
checkers.BaseChecker,
230224
):
231225
"""Lint Python modules using external checkers.
232226
@@ -290,7 +284,6 @@ def __init__(
290284
self.current_name: str | None = None
291285
self.current_file: str | None = None
292286
self._ignore_file = False
293-
self._pragma_lineno: dict[str, int] = {}
294287

295288
# Attributes related to stats
296289
self.stats = LinterStats()
@@ -307,13 +300,13 @@ def __init__(
307300
"""List of message symbols on which pylint should fail, set by --fail-on."""
308301
self._error_mode = False
309302

310-
# Attributes related to messages (states) and their handling
303+
# Attributes related to registering messages and their handling
311304
self.msgs_store = MessageDefinitionStore()
312305
self.msg_status = 0
313306
self._by_id_managed_msgs: list[ManagedMessage] = []
314307

315308
reporters.ReportsHandlerMixIn.__init__(self)
316-
checkers.BaseTokenChecker.__init__(self, self)
309+
checkers.BaseChecker.__init__(self, self)
317310
# provided reports
318311
self.reports = (
319312
("RP0001", "Messages by category", report_total_messages_stats),
@@ -508,91 +501,6 @@ def _parse_error_mode(self) -> None:
508501
self.set_option("persistent", False)
509502
self.set_option("score", False)
510503

511-
# block level option handling #############################################
512-
# see func_block_disable_msg.py test case for expected behaviour
513-
514-
def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None:
515-
"""Process tokens from the current module to search for module/block level
516-
options.
517-
"""
518-
control_pragmas = {"disable", "disable-next", "enable"}
519-
prev_line = None
520-
saw_newline = True
521-
seen_newline = True
522-
for (tok_type, content, start, _, _) in tokens:
523-
if prev_line and prev_line != start[0]:
524-
saw_newline = seen_newline
525-
seen_newline = False
526-
527-
prev_line = start[0]
528-
if tok_type in (tokenize.NL, tokenize.NEWLINE):
529-
seen_newline = True
530-
531-
if tok_type != tokenize.COMMENT:
532-
continue
533-
match = OPTION_PO.search(content)
534-
if match is None:
535-
continue
536-
try:
537-
for pragma_repr in parse_pragma(match.group(2)):
538-
if pragma_repr.action in {"disable-all", "skip-file"}:
539-
if pragma_repr.action == "disable-all":
540-
self.add_message(
541-
"deprecated-pragma",
542-
line=start[0],
543-
args=("disable-all", "skip-file"),
544-
)
545-
self.add_message("file-ignored", line=start[0])
546-
self._ignore_file = True
547-
return
548-
try:
549-
meth = self._options_methods[pragma_repr.action]
550-
except KeyError:
551-
meth = self._bw_options_methods[pragma_repr.action]
552-
# found a "(dis|en)able-msg" pragma deprecated suppression
553-
self.add_message(
554-
"deprecated-pragma",
555-
line=start[0],
556-
args=(
557-
pragma_repr.action,
558-
pragma_repr.action.replace("-msg", ""),
559-
),
560-
)
561-
for msgid in pragma_repr.messages:
562-
# Add the line where a control pragma was encountered.
563-
if pragma_repr.action in control_pragmas:
564-
self._pragma_lineno[msgid] = start[0]
565-
566-
if (pragma_repr.action, msgid) == ("disable", "all"):
567-
self.add_message(
568-
"deprecated-pragma",
569-
line=start[0],
570-
args=("disable=all", "skip-file"),
571-
)
572-
self.add_message("file-ignored", line=start[0])
573-
self._ignore_file = True
574-
return
575-
# If we did not see a newline between the previous line and now,
576-
# we saw a backslash so treat the two lines as one.
577-
l_start = start[0]
578-
if not saw_newline:
579-
l_start -= 1
580-
try:
581-
meth(msgid, "module", l_start)
582-
except exceptions.UnknownMessageError:
583-
msg = f"{pragma_repr.action}. Don't recognize message {msgid}."
584-
self.add_message(
585-
"bad-option-value", args=msg, line=start[0]
586-
)
587-
except UnRecognizedOptionError as err:
588-
self.add_message(
589-
"unrecognized-inline-option", args=err.token, line=start[0]
590-
)
591-
continue
592-
except InvalidPragmaError as err:
593-
self.add_message("bad-inline-option", args=err.token, line=start[0])
594-
continue
595-
596504
# code checking methods ###################################################
597505

598506
def get_checkers(self) -> list[BaseChecker]:
@@ -1025,8 +933,7 @@ def _check_astroid_module(
1025933
self.add_message("raw-checker-failed", args=node.name)
1026934
else:
1027935
# assert astroid.file.endswith('.py')
1028-
# invoke ITokenChecker interface on self to fetch module/block
1029-
# level options
936+
# Parse module/block level option pragma's
1030937
self.process_tokens(tokens)
1031938
if self._ignore_file:
1032939
return False

0 commit comments

Comments
 (0)