Skip to content

Commit

Permalink
Refactor - Create a pylint.message package
Browse files Browse the repository at this point in the history
There is a lot of Message related class in Utils
this warrant the creation of a new package.

See also review for burst utils.py into a package here:
#2654 (comment)
  • Loading branch information
Pierre-Sassoulas authored and PCManticore committed Mar 9, 2019
1 parent b1780d1 commit 2b50749
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 95 deletions.
3 changes: 2 additions & 1 deletion pylint/checkers/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@

from pylint.interfaces import IRawChecker, ITokenChecker
from pylint.checkers import BaseChecker
from pylint.utils import OPTION_RGX, MessagesHandlerMixIn
from pylint.utils import OPTION_RGX
from pylint.message import MessagesHandlerMixIn


class ByIdManagedMessagesChecker(BaseChecker):
Expand Down
35 changes: 21 additions & 14 deletions pylint/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,15 @@
from pylint import checkers
from pylint import interfaces
from pylint import reporters
from pylint.message import MessagesStore, Message, MSG_TYPES, MessagesHandlerMixIn
from pylint.utils import (
FileState,
PyLintASTWalker,
ReportsHandlerMixIn,
OPTION_RGX,
utils,
)
from pylint import exceptions
from pylint import utils
from pylint import config
from pylint.__pkginfo__ import version
from pylint.reporters.ureports import nodes as report_nodes
Expand Down Expand Up @@ -308,8 +315,8 @@ def _run_linter(self, file_or_module):
# pylint: disable=too-many-instance-attributes
class PyLinter(
config.OptionsManagerMixIn,
utils.MessagesHandlerMixIn,
utils.ReportsHandlerMixIn,
MessagesHandlerMixIn,
ReportsHandlerMixIn,
checkers.BaseTokenChecker,
):
"""lint Python modules using external checkers.
Expand Down Expand Up @@ -594,15 +601,15 @@ def __init__(self, options=(), reporter=None, option_groups=(), pylintrc=None):
# some stuff has to be done before ancestors initialization...
#
# messages store / checkers / reporter / astroid manager
self.msgs_store = utils.MessagesStore()
self.msgs_store = MessagesStore()
self.reporter = None
self._reporter_name = None
self._reporters = {}
self._checkers = collections.defaultdict(list)
self._pragma_lineno = {}
self._ignore_file = False
# visit variables
self.file_state = utils.FileState()
self.file_state = FileState()
self.current_name = None
self.current_file = None
self.stats = None
Expand All @@ -620,8 +627,8 @@ def __init__(self, options=(), reporter=None, option_groups=(), pylintrc=None):
astroid_version,
sys.version,
)
utils.MessagesHandlerMixIn.__init__(self)
utils.ReportsHandlerMixIn.__init__(self)
MessagesHandlerMixIn.__init__(self)
ReportsHandlerMixIn.__init__(self)
super(PyLinter, self).__init__(
usage=__doc__, version=full_version, config_file=pylintrc or config.PYLINTRC
)
Expand Down Expand Up @@ -836,7 +843,7 @@ def process_tokens(self, tokens):
for (tok_type, content, start, _, _) in tokens:
if tok_type != tokenize.COMMENT:
continue
match = utils.OPTION_RGX.search(content)
match = OPTION_RGX.search(content)
if match is None:
continue

Expand Down Expand Up @@ -1049,7 +1056,7 @@ def _parallel_check(self, files_or_modules):
(_, self.file_state.base_name, module, messages, stats, msg_status) = result

for msg in messages:
msg = utils.Message(*msg)
msg = Message(*msg)
self.set_current_module(module)
self.reporter.handle_message(msg)

Expand All @@ -1065,7 +1072,7 @@ def _parallel_check(self, files_or_modules):
checker.stats = self.stats

def _do_check(self, files_or_modules):
walker = utils.PyLintASTWalker(self)
walker = PyLintASTWalker(self)
_checkers = self.prepare_checkers()
tokencheckers = [
c
Expand Down Expand Up @@ -1102,7 +1109,7 @@ def _do_check(self, files_or_modules):
ast_node = _ast_from_string(_read_stdin(), filepath, modname)

if ast_node is not None:
self.file_state = utils.FileState(filepath)
self.file_state = FileState(filepath)
self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers)
# warn about spurious inline messages handling
spurious_messages = self.file_state.iter_spurious_suppression_messages(
Expand All @@ -1124,7 +1131,7 @@ def _do_check(self, files_or_modules):
# XXX to be correct we need to keep module_msgs_state for every
# analyzed module (the problem stands with localized messages which
# are only detected in the .close step)
self.file_state = utils.FileState(descr["basename"])
self.file_state = FileState(descr["basename"])
self._ignore_file = False
# fix the current file (if the source file was not available or
# if it's actually a c extension)
Expand Down Expand Up @@ -1167,7 +1174,7 @@ def set_current_module(self, modname, filepath=None):
self.current_file = filepath or modname
self.stats["by_module"][modname] = {}
self.stats["by_module"][modname]["statement"] = 0
for msg_cat in utils.MSG_TYPES.values():
for msg_cat in MSG_TYPES.values():
self.stats["by_module"][modname][msg_cat] = 0

def get_ast(self, filepath, modname):
Expand Down Expand Up @@ -1223,7 +1230,7 @@ def open(self):
MANAGER.always_load_extensions = self.config.unsafe_load_any_extension
MANAGER.max_inferable_values = self.config.limit_inference_results
MANAGER.extension_package_whitelist.update(self.config.extension_pkg_whitelist)
for msg_cat in utils.MSG_TYPES.values():
for msg_cat in MSG_TYPES.values():
self.stats[msg_cat] = 0

def generate_reports(self):
Expand Down
55 changes: 55 additions & 0 deletions pylint/message/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
# Copyright (c) 2009 Vincent
# Copyright (c) 2009 Mads Kiilerich <mads@kiilerich.com>
# Copyright (c) 2012-2014 Google, Inc.
# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com>
# Copyright (c) 2014-2015 Michal Nowikowski <godfryd@gmail.com>
# Copyright (c) 2014 LCD 47 <lcd047@gmail.com>
# Copyright (c) 2014 Brett Cannon <brett@python.org>
# Copyright (c) 2014 Arun Persaud <arun@nubati.net>
# Copyright (c) 2014 Damien Nozay <damien.nozay@gmail.com>
# Copyright (c) 2015 Aru Sahni <arusahni@gmail.com>
# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
# Copyright (c) 2015 Simu Toni <simutoni@gmail.com>
# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com>
# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net>
# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com>
# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk>
# Copyright (c) 2016 xmo-odoo <xmo-odoo@users.noreply.github.com>
# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com>
# Copyright (c) 2017 Pierre Sassoulas <pierre.sassoulas@cea.fr>
# Copyright (c) 2017 Bryce Guinta <bryce.paul.guinta@gmail.com>
# Copyright (c) 2017 Chris Lamb <chris@chris-lamb.co.uk>
# Copyright (c) 2017 Anthony Sottile <asottile@umich.edu>
# Copyright (c) 2017 Thomas Hisch <t.hisch@gmail.com>
# Copyright (c) 2017 Mikhail Fesenko <proggga@gmail.com>
# Copyright (c) 2017 Craig Citro <craigcitro@gmail.com>
# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi>
# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com>
# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com>
# Copyright (c) 2018 Pierre Sassoulas <pierre.sassoulas@wisebim.fr>
# Copyright (c) 2018 Reverb C <reverbc@users.noreply.github.com>
# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com>

# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

"""All the classes related to Message handling."""

from pylint.message.constants import (
MSG_STATE_CONFIDENCE,
_SCOPE_EXEMPT,
MSG_STATE_SCOPE_CONFIG,
MSG_STATE_SCOPE_MODULE,
MSG_TYPES,
MSG_TYPES_LONG,
MSG_TYPES_STATUS,
)
from pylint.message.build_message_definition import build_message_def
from pylint.message.message import Message
from pylint.message.message_definition import MessageDefinition
from pylint.message.message_handler_mix_in import MessagesHandlerMixIn
from pylint.message.message_store import MessagesStore
34 changes: 34 additions & 0 deletions pylint/message/build_message_definition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-

# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

import warnings

from pylint.interfaces import IRawChecker, ITokenChecker, implements
from pylint.message.message_definition import MessageDefinition
from pylint.utils.warning_scope import WarningScope


def build_message_def(checker, msgid, msg_tuple):
if implements(checker, (IRawChecker, ITokenChecker)):
default_scope = WarningScope.LINE
else:
default_scope = WarningScope.NODE
options = {}
if len(msg_tuple) > 3:
(msg, symbol, descr, options) = msg_tuple
elif len(msg_tuple) > 2:
(msg, symbol, descr) = msg_tuple
else:
# messages should have a symbol, but for backward compatibility
# they may not.
(msg, descr) = msg_tuple
warnings.warn(
"[pylint 0.26] description of message %s doesn't include "
"a symbolic name" % msgid,
DeprecationWarning,
)
symbol = None
options.setdefault("scope", default_scope)
return MessageDefinition(checker, msgid, msg, descr, symbol, **options)
24 changes: 24 additions & 0 deletions pylint/message/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-

# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

MSG_STATE_CONFIDENCE = 2
_MSG_ORDER = "EWRCIF"
MSG_STATE_SCOPE_CONFIG = 0
MSG_STATE_SCOPE_MODULE = 1

# The line/node distinction does not apply to fatal errors and reports.
_SCOPE_EXEMPT = "FR"

MSG_TYPES = {
"I": "info",
"C": "convention",
"R": "refactor",
"W": "warning",
"E": "error",
"F": "fatal",
}
MSG_TYPES_LONG = {v: k for k, v in MSG_TYPES.items()}

MSG_TYPES_STATUS = {"I": 0, "C": 16, "R": 8, "W": 4, "E": 2, "F": 1}
2 changes: 1 addition & 1 deletion pylint/utils/message.py → pylint/message/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import collections

from pylint.utils.constants import MSG_TYPES
from pylint.message.constants import MSG_TYPES

_MsgBase = collections.namedtuple(
"_MsgBase",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sys

from pylint.exceptions import InvalidMessageError
from pylint.utils.constants import MSG_TYPES
from pylint.message.constants import MSG_TYPES
from pylint.utils.normalize_text import normalize_text


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from pylint.exceptions import InvalidMessageError, UnknownMessageError
from pylint.interfaces import UNDEFINED
from pylint.utils.constants import (
from pylint.message.constants import (
_MSG_ORDER,
_SCOPE_EXEMPT,
MSG_STATE_CONFIDENCE,
Expand All @@ -19,11 +19,11 @@
MSG_TYPES,
MSG_TYPES_STATUS,
)
from pylint.utils.message import Message
from pylint.message.message import Message
from pylint.utils.warning_scope import WarningScope
from pylint.message.build_message_definition import build_message_def
from pylint.utils.utils import (
WarningScope,
_format_option_value,
build_message_def,
category_id,
get_module_and_frameid,
normalize_text,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import collections

from pylint.exceptions import InvalidMessageError, UnknownMessageError
from pylint.utils.utils import build_message_def
from pylint.message.build_message_definition import build_message_def


class MessagesStore:
Expand Down
5 changes: 2 additions & 3 deletions pylint/test/unittest_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@

from pylint import config, lint
from pylint.lint import PyLinter, Run, preprocess_options, ArgumentPreprocessingError
from pylint.utils import (
from pylint.message import (
MSG_STATE_SCOPE_CONFIG,
MSG_STATE_SCOPE_MODULE,
MSG_STATE_CONFIDENCE,
MessagesStore,
MessageDefinition,
FileState,
tokenize_module,
)
from pylint.utils import FileState, tokenize_module
from pylint.exceptions import InvalidMessageError, UnknownMessageError
import pylint.testutils as testutils
from pylint.reporters import text
Expand Down
11 changes: 6 additions & 5 deletions pylint/test/utils/unittest_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@

import astroid

from pylint import utils
from pylint.utils import utils, PyLintASTWalker
from pylint.message import MessagesStore, MessageDefinition
from pylint.checkers.utils import check_messages, get_node_last_lineno
from pylint.exceptions import InvalidMessageError
import pytest
Expand Down Expand Up @@ -60,7 +61,7 @@ def test_check_messages(self):
linter = self.MockLinter(
{"first-message": True, "second-message": False, "third-message": True}
)
walker = utils.PyLintASTWalker(linter)
walker = PyLintASTWalker(linter)
checker = self.Checker()
walker.add_checker(checker)
walker.walk(astroid.parse("x = func()"))
Expand All @@ -76,7 +77,7 @@ def visit_assname(self, node):
self.called = True

linter = self.MockLinter({"first-message": True})
walker = utils.PyLintASTWalker(linter)
walker = PyLintASTWalker(linter)
checker = Checker()
walker.add_checker(checker)
with warnings.catch_warnings(record=True):
Expand All @@ -100,7 +101,7 @@ def test__basename_in_blacklist_re_nomatch():

@pytest.fixture
def store():
return utils.MessagesStore()
return MessagesStore()


@pytest.mark.parametrize(
Expand Down Expand Up @@ -240,7 +241,7 @@ class CheckerTwo(object):
)
def test_create_invalid_message_type(msgid, expected):
with pytest.raises(InvalidMessageError) as cm:
utils.MessageDefinition("checker", msgid, "msg", "descr", "symbol", "scope")
MessageDefinition("checker", msgid, "msg", "descr", "symbol", "scope")
assert str(cm.value) == expected


Expand Down
16 changes: 1 addition & 15 deletions pylint/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,8 @@
main pylint class
"""

from pylint.utils.constants import (
MSG_STATE_CONFIDENCE,
MSG_STATE_SCOPE_CONFIG,
MSG_STATE_SCOPE_MODULE,
MSG_TYPES,
MSG_TYPES_LONG,
MSG_TYPES_STATUS,
OPTION_RGX,
PY_EXTS,
)
from pylint.utils.constants import OPTION_RGX, PY_EXTS
from pylint.utils.file_state import FileState
from pylint.utils.message import Message
from pylint.utils.message_definition import MessageDefinition
from pylint.utils.message_handler_mix_in import MessagesHandlerMixIn
from pylint.utils.message_store import MessagesStore
from pylint.utils.normalize_text import normalize_text
from pylint.utils.pylint_ast_walker import PyLintASTWalker
from pylint.utils.reports_handler_mix_in import ReportsHandlerMixIn
Expand All @@ -65,7 +52,6 @@
_format_option_value,
_splitstrip,
_unquote,
build_message_def,
category_id,
decoding_stream,
deprecated_option,
Expand Down

0 comments on commit 2b50749

Please sign in to comment.