diff options
author | Ashley Whetter <ashley@awhetter.co.uk> | 2018-02-24 17:00:31 -0800 |
---|---|---|
committer | Ashley Whetter <ashley@awhetter.co.uk> | 2019-02-09 13:27:33 -0800 |
commit | 451f9307e573f669beb5f04c52d9b917789f76af (patch) | |
tree | 53781d61580cfc62755d0e8bfaac1f917b66848b | |
parent | 5965b38a2c8a4c02111b9d5310663669c84cb56b (diff) | |
download | pylint-git-451f9307e573f669beb5f04c52d9b917789f76af.tar.gz |
PyLinter is no longer a reports handler
-rw-r--r-- | pylint/lint.py | 102 | ||||
-rw-r--r-- | pylint/utils.py | 32 |
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 |