summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshley Whetter <ashley@awhetter.co.uk>2018-02-24 17:00:31 -0800
committerAshley Whetter <ashley@awhetter.co.uk>2019-02-09 13:27:33 -0800
commit451f9307e573f669beb5f04c52d9b917789f76af (patch)
tree53781d61580cfc62755d0e8bfaac1f917b66848b
parent5965b38a2c8a4c02111b9d5310663669c84cb56b (diff)
downloadpylint-git-451f9307e573f669beb5f04c52d9b917789f76af.tar.gz
PyLinter is no longer a reports handler
-rw-r--r--pylint/lint.py102
-rw-r--r--pylint/utils.py32
2 files changed, 59 insertions, 75 deletions
diff --git a/pylint/lint.py b/pylint/lint.py
index 91cf8defd..7e5770375 100644
--- a/pylint/lint.py
+++ b/pylint/lint.py
@@ -271,9 +271,7 @@ MSGS = {
# pylint: disable=too-many-instance-attributes
-class PyLinter(
- utils.MessagesHandlerMixIn, utils.ReportsHandlerMixIn, checkers.BaseTokenChecker
-):
+class PyLinter(utils.MessagesHandlerMixIn, checkers.BaseTokenChecker):
"""lint Python modules using external checkers.
This is the main checker controlling the other ones and the reports
@@ -544,7 +542,6 @@ class PyLinter(
# visit variables
self.current_name = None
self.current_file = None
- self.stats = None
# TODO: Runner needs to give this to parser?
full_version = "%%prog %s\nastroid %s\nPython %s" % (
@@ -582,12 +579,6 @@ class PyLinter(
for msgid in msgids:
self.disable(msgid)
- def disable_reporters(self):
- """disable all reporters"""
- for _reporters in self._reports.values():
- for report_id, _, _ in _reporters:
- self.disable_report(report_id)
-
def error_mode(self):
"""error mode: enable only errors; no reports, no persistent"""
self._error_mode = True
@@ -688,31 +679,6 @@ class PyLinter(
# code checking methods ###################################################
- def get_checkers(self):
- """return all available checkers as a list"""
- return [self] + [
- c
- for _checkers in self._checkers.values()
- for c in _checkers
- if c is not self
- ]
-
- def prepare_checkers(self):
- """return checkers needed for activated messages and reports"""
- if not self.config.reports:
- self.disable_reporters()
- # get needed checkers
- neededcheckers = [self]
- for checker in self.get_checkers()[1:]:
- messages = {msg for msg in checker.msgs if self.is_message_enabled(msg)}
- if messages or any(self.report_is_enabled(r[0]) for r in checker.reports):
- neededcheckers.append(checker)
- # Sort checkers by priority
- neededcheckers = sorted(
- neededcheckers, key=operator.attrgetter("priority"), reverse=True
- )
- return neededcheckers
-
# pylint: disable=unused-argument
@staticmethod
def should_analyze_file(modname, path, is_argument=False):
@@ -743,7 +709,7 @@ class PyLinter(
if not msg.may_be_emitted():
self._msgs_state[msg.msgid] = False
- def check(self, files_or_modules):
+ def check(self, files_or_modules, checkers_):
"""main checking entry: check a list of files or modules from their
name.
"""
@@ -754,21 +720,20 @@ class PyLinter(
if not isinstance(files_or_modules, (list, tuple)):
files_or_modules = (files_or_modules,)
- self._do_check(files_or_modules)
+ self._do_check(files_or_modules, checkers_)
- def _do_check(self, files_or_modules):
+ def _do_check(self, files_or_modules, checkers_):
walker = utils.PyLintASTWalker(self)
- _checkers = self.prepare_checkers()
tokencheckers = [
c
- for c in _checkers
+ for c in checkers_
if interfaces.implements(c, interfaces.ITokenChecker) and c is not self
]
rawcheckers = [
- c for c in _checkers if interfaces.implements(c, interfaces.IRawChecker)
+ c for c in checkers_ if interfaces.implements(c, interfaces.IRawChecker)
]
# notify global begin
- for checker in _checkers:
+ for checker in checkers_:
checker.open()
if interfaces.implements(checker, interfaces.IAstroidChecker):
walker.add_checker(checker)
@@ -806,7 +771,7 @@ class PyLinter(
self.add_message(msgid, line, None, args)
# notify global end
self.stats["statement"] = walker.nbstatements
- for checker in reversed(_checkers):
+ for checker in reversed(checkers_):
checker.close()
def set_current_module(self, modname, filepath=None):
@@ -926,7 +891,9 @@ def guess_lint_path(args):
return value
-class PluginRegistry(object):
+# TODO: Split the ReportsHandlerMixIn, keeping register methods here,
+# and moving report_order and make_reports to the runner.
+class PluginRegistry(utils.ReportsHandlerMixIn):
"""A class to register checkers to."""
def __init__(self, linter, register_options=(lambda options: None)):
@@ -936,12 +903,10 @@ class PluginRegistry(object):
# TODO: Remove. This is needed for the MessagesHandlerMixIn for now.
linter._checkers = self._checkers
self._reporters = {}
- linter._reporters = self._reporters
self._linter = linter
- # TODO: Move elsewhere
for r_id, r_title, r_cb in linter.reports:
- self._linter.register_post_report(r_id, r_title, r_cb)
+ self.register_post_report(r_id, r_title, r_cb)
self.register_options(linter.options)
@@ -972,9 +937,8 @@ class PluginRegistry(object):
self._checkers[checker.name].append(checker)
- # TODO: Move elsewhere
for r_id, r_title, r_cb in checker.reports:
- self._linter.register_report(r_id, r_title, r_cb, checker)
+ self.register_report(r_id, r_title, r_cb, checker)
self.register_options(checker.options)
@@ -997,7 +961,7 @@ class PluginRegistry(object):
self._reporters[reporter_class.name] = reporter_class
- # For now simply defer missing attributs to the linter,
+ # For now simply defer missing attributes to the linter,
# until we know what API we want.
def __getattr__(self, attribute):
return getattr(self._linter, attribute)
@@ -1143,7 +1107,7 @@ group are mutually exclusive.",
)
def __init__(self):
- super(CLIRunner, self).__init__()
+ super().__init__()
self._linter = PyLinter()
self._plugin_registry = PluginRegistry(self._linter)
self._loaded_plugins = set()
@@ -1274,9 +1238,14 @@ group are mutually exclusive.",
for checker in self._plugin_registry.for_all_checkers():
checker.config = self._global_config
+ if not self._global_config.reports:
+ self._plugin_registry.disable_reporters()
+
with fix_import_path(self._global_config.module_or_package):
assert self._global_config.jobs == 1
- self._linter.check(self._global_config.module_or_package)
+ self._linter.check(
+ self._global_config.module_or_package, self.prepare_checkers()
+ )
self.generate_reports()
@@ -1348,7 +1317,10 @@ group are mutually exclusive.",
# XXX code below needs refactoring to be more reporter agnostic
self._reporter.on_close(self._linter.stats, previous_stats)
if self._global_config.reports:
- sect = self._linter.make_reports(self._linter.stats, previous_stats)
+ # TODO: The Runner should make reports, not the registry.
+ sect = self._plugin_registry.make_reports(
+ self._linter.stats, previous_stats
+ )
else:
sect = report_nodes.Section()
@@ -1388,6 +1360,30 @@ group are mutually exclusive.",
sect = report_nodes.EvaluationSection(msg)
self._reporter.display_reports(sect)
+ def get_checkers(self):
+ """return all available checkers as a list"""
+ return [self._linter] + [
+ c for c in self._plugin_registry.for_all_checkers() if c is not self._linter
+ ]
+
+ def prepare_checkers(self):
+ """return checkers needed for activated messages and reports"""
+ # get needed checkers
+ neededcheckers = [self._linter]
+ for checker in self.get_checkers()[1:]:
+ messages = set(
+ msg for msg in checker.msgs if self._linter.is_message_enabled(msg)
+ )
+ if messages or any(
+ self._plugin_registry.report_is_enabled(r[0]) for r in checker.reports
+ ):
+ neededcheckers.append(checker)
+ # Sort checkers by priority
+ neededcheckers = sorted(
+ neededcheckers, key=operator.attrgetter("priority"), reverse=True
+ )
+ return neededcheckers
+
if __name__ == "__main__":
CLIRunner().run(sys.argv[1:])
diff --git a/pylint/utils.py b/pylint/utils.py
index f8baa96a7..56f8c5f96 100644
--- a/pylint/utils.py
+++ b/pylint/utils.py
@@ -287,6 +287,7 @@ class MessagesHandlerMixIn:
self.msg_status = 0
self.msgs_store = MessagesStore()
self.reporter = None
+ self.stats = {"by_module": {}, "by_msg": {}}
super().__init__()
def _checker_messages(self, checker):
@@ -364,13 +365,7 @@ class MessagesHandlerMixIn:
self._set_msg_status(_msgid, enable, scope, line)
return
- # msgid is report id?
- if msgid.lower().startswith("rp"):
- if enable:
- self.enable_report(msgid)
- else:
- self.disable_report(msgid)
- return
+ # TODO: Need to add enable/disable report back?
try:
# msgid is a symbolic or numeric msgid.
@@ -1057,9 +1052,7 @@ class MessagesStore:
class ReportsHandlerMixIn:
- """a mix-in class containing all the reports and stats manipulation
- related methods for the main lint class
- """
+ """A report handlers organises and calls report methods."""
_POST_CHECKER = object()
@@ -1120,6 +1113,12 @@ class ReportsHandlerMixIn:
reportid = reportid.upper()
self._reports_state[reportid] = False
+ def disable_reporters(self):
+ """Disable all reporters."""
+ for _reporters in self._reports.values():
+ for report_id, _, _ in _reporters:
+ self.disable_report(report_id)
+
def report_is_enabled(self, reportid):
"""return true if the report associated to the given identifier is
enabled
@@ -1128,7 +1127,7 @@ class ReportsHandlerMixIn:
def make_reports(self, stats, old_stats):
"""render registered reports"""
- sect = Section("Report", "%s statements analysed." % (self.stats["statement"]))
+ sect = Section("Report", "%s statements analysed." % (stats["statement"]))
for checker in self.report_order():
for reportid, r_title, r_cb in self._reports[checker]:
if not self.report_is_enabled(reportid):
@@ -1142,17 +1141,6 @@ class ReportsHandlerMixIn:
sect.append(report_sect)
return sect
- def add_stats(self, **kwargs):
- """add some stats entries to the statistic dictionary
- raise an AssertionError if there is a key conflict
- """
- for key, value in kwargs.items():
- if key[-1] == "_":
- key = key[:-1]
- assert key not in self.stats
- self.stats[key] = value
- return self.stats
-
def _basename_in_blacklist_re(base_name, black_list_re):
"""Determines if the basename is matched in a regex blacklist