diff options
author | Ashley Whetter <ashley@awhetter.co.uk> | 2018-07-29 15:47:22 -0700 |
---|---|---|
committer | Ashley Whetter <ashley@awhetter.co.uk> | 2019-02-09 13:40:54 -0800 |
commit | f19b9ff7c5a2363cbcaff1da350128c1435e092f (patch) | |
tree | 2cd800afeffdc346fac7f08c9721e64adca7720e | |
parent | 76b3e8ed90d9ecb6d8a59eaa0240b18622cdbe86 (diff) | |
download | pylint-git-f19b9ff7c5a2363cbcaff1da350128c1435e092f.tar.gz |
Fixed "enable" and "disable" options
-rw-r--r-- | pylint/config.py | 36 | ||||
-rw-r--r-- | pylint/lint.py | 83 | ||||
-rw-r--r-- | pylint/utils.py | 24 |
3 files changed, 83 insertions, 60 deletions
diff --git a/pylint/config.py b/pylint/config.py index 699f789a0..a043520dc 100644 --- a/pylint/config.py +++ b/pylint/config.py @@ -38,6 +38,7 @@ from __future__ import print_function import abc import argparse import collections +import copy import os import pickle import re @@ -229,6 +230,8 @@ VALIDATORS = { "csv": utils._check_csv, "yn": _yn_validator, "non_empty_string": _non_empty_string_validator, + "_msg_on": (lambda value: (utils._check_csv(value), True)), + "_msg_off": (lambda value: (utils._check_csv(value), False)), } @@ -240,6 +243,8 @@ UNVALIDATORS = { "csv": (lambda value: ",".join(value)), "yn": (lambda value: "y" if value else "n"), "non_empty_string": str, + "_msg_on": (lambda value: ",".join(y for y in x[0] for x in value)), + "_msg_off": (lambda value: ",".join(y for y in x[0] for x in value)), } @@ -266,7 +271,13 @@ class Configuration(object): def set_option(self, option, value): option = option.replace("-", "_") - setattr(self, option, value) + definition = self._option_definitions.get(option, {}) + dest = definition.get("dest", option) + if definition.get("action") == "append": + new_value = getattr(self, dest, []) + new_value.append(value) + value = new_value + setattr(self, dest, value) def copy(self): result = self.__class__() @@ -592,8 +603,8 @@ class IniFileParser(FileParser): section = section.upper() for option, value in self._parser.items(section): + definition = self._option_definitions.get(option, {}) if isinstance(value, str): - definition = self._option_definitions.get(option, {}) type_ = definition.get("type") validator = VALIDATORS.get(type_, lambda x: x) value = validator(value) @@ -603,6 +614,27 @@ class IniFileParser(FileParser): self._parser.read(to_parse) self.apply_to_configuration(config) + def preprocess(self, to_parse, *options): + """Do some guess work to get a value for the specified option. + + :param to_parse: The path to the file to parse. + :type to_parse: str + :param options: The names of the options to look for. + :type options: str + + :returns: A config with the processed options. + :rtype: Configuration + """ + config = Configuration() + config.add_options(self._option_definitions.items()) + + pre_config = Configuration() + self.parse(to_parse, pre_config) + for option in options: + setattr(config, option, getattr(pre_config, option, None)) + + return config + def write(self, stream=sys.stdout): """ Write out config to stream. diff --git a/pylint/lint.py b/pylint/lint.py index 131a07e0c..80430e3a0 100644 --- a/pylint/lint.py +++ b/pylint/lint.py @@ -421,13 +421,16 @@ class PyLinter(utils.MessagesHandlerMixIn, checkers.BaseTokenChecker): ( "enable", { - "type": "csv", + "type": "_msg_on", "metavar": "<msg ids>", + "dest": "msg_toggles", + "action": "append", "short": "e", + "default": [], "group": "Messages control", "help": "Enable the message, report, category or checker with the " - "given id(s). You can either give multiple identifier " - "separated by comma (,) or put this option multiple time " + "given id(s). You can either give multiple identifiers " + "separated by comma (,) or put this option multiple times " "(only on the command line, not in the configuration file " "where it should appear only once). " 'See also the "--disable" option for examples. ', @@ -436,9 +439,12 @@ class PyLinter(utils.MessagesHandlerMixIn, checkers.BaseTokenChecker): ( "disable", { - "type": "csv", + "type": "_msg_off", "metavar": "<msg ids>", + "dest": "msg_toggles", + "action": "append", "short": "d", + "default": [], "group": "Messages control", "help": "Disable the message, report, category or checker " "with the given id(s). You can either give multiple identifiers" @@ -610,10 +616,6 @@ class PyLinter(utils.MessagesHandlerMixIn, checkers.BaseTokenChecker): :raises ValueError: If `scope` is anything other than "module". """ - if scope != "module": - msg = "Messages can be configured on only a module level" - raise ValueError(msg) - self._set_msg_status( msgid, enable=False, scope=scope, line=line, ignore_unknown=ignore_unknown ) @@ -638,13 +640,7 @@ class PyLinter(utils.MessagesHandlerMixIn, checkers.BaseTokenChecker): given ID cannot be found. If this is True, the exception is not raised. :param ignore_unknown: bool - - :raises ValueError: If `scope` is anything other than "module". """ - if scope != "module": - msg = "Messages can be configured on only a module level" - raise ValueError(msg) - self._set_msg_status( msgid, enable=True, scope=scope, line=line, ignore_unknown=ignore_unknown ) @@ -1022,10 +1018,6 @@ class PluginRegistry(utils.MessagesHandlerMixIn, ReportRegistry): :raises ValueError: If `scope` is anything other than "package". """ - if scope != "package": - msg = "Messages can be configured on only a package level" - raise ValueError(msg) - self._set_msg_status( msgid, enable=False, scope=scope, line=line, ignore_unknown=ignore_unknown ) @@ -1054,10 +1046,6 @@ class PluginRegistry(utils.MessagesHandlerMixIn, ReportRegistry): :raises ValueError: If `scope` is anything other than "package". """ - if scope != "package": - msg = "Messages can be configured on only a package level" - raise ValueError(msg) - self._set_msg_status( msgid, enable=True, scope=scope, line=line, ignore_unknown=ignore_unknown ) @@ -1286,15 +1274,7 @@ group are mutually exclusive.", self._global_config.add_options(option_definitions) - parsed = parser.preprocess( - args, - "init_hook", - "rcfile", - "load_plugins", - "ignore", - "ignore_patterns", - "version", - ) + parsed = parser.preprocess(args, "init_hook", "rcfile", "load_plugins") # Call init-hook if parsed.init_hook: @@ -1305,7 +1285,12 @@ group are mutually exclusive.", file_parser.add_option_definitions(PyLinter.options) rcfile = parsed.rcfile or config.PYLINTRC if rcfile: - file_parser.parse(rcfile, self._global_config) + file_parsed = file_parser.preprocess(rcfile, "init_hook", "load_plugins") + if file_parsed.init_hook: + exec(file_parsed.init_hook) + if file_parsed.load_plugins: + old_value = getattr(parsed, "load_plugins", []) + parsed.load_plugins = old_value + file_parsed.load_plugins def register_options(options): self._global_config.add_options(options) @@ -1386,9 +1371,7 @@ group are mutually exclusive.", with fix_import_path(self._global_config.module_or_package): assert self._global_config.jobs == 1 - base_name, status_code = self.check( - self._global_config.module_or_package, self.prepare_checkers() - ) + base_name, status_code = self.check(self._global_config.module_or_package) self.generate_reports(base_name) @@ -1549,15 +1532,13 @@ group are mutually exclusive.", """return all available checkers as a list""" return [c for c in self._plugin_registry.for_all_checkers()] - def prepare_checkers(self): + def prepare_checkers(self, linter): """return checkers needed for activated messages and reports""" # get needed checkers neededcheckers = [] for checker in self.get_checkers()[1:]: messages = set( - msg - for msg in checker.msgs - if self._plugin_registry.is_message_enabled(msg) + msg for msg in checker.msgs if linter.is_message_enabled(msg) ) if messages or any( self._plugin_registry.report_is_enabled(r[0]) for r in checker.reports @@ -1602,7 +1583,7 @@ group are mutually exclusive.", self._global_config.extension_pkg_whitelist ) - def check(self, files_or_modules, checkers_): + def check(self, files_or_modules): """main checking entry: check a list of files or modules from their name. """ @@ -1622,15 +1603,28 @@ group are mutually exclusive.", self._global_config.black_list_re, ) for module_desc in expanded_files: + modname = module_desc.name + filepath = module_desc.path + if not module_desc.isarg and not self.should_analyze_file( + modname, filepath + ): + continue + linter = PyLinter(self._global_config) linter.msgs_store = self._plugin_registry.msgs_store + for msg_ids, enable in self._global_config.msg_toggles: + for msg_id in msg_ids: + if enable: + linter.enable(msg_id, scope="directory") + else: + linter.disable(msg_id, scope="directory") linter.open() walker = utils.PyLintASTWalker(self._plugin_registry) allcheckers = [] tokencheckers = [linter] rawcheckers = [] - for checker_cls in checkers_: + for checker_cls in self.prepare_checkers(linter): checker = checker_cls(linter) checker.linter = linter checker.open() @@ -1642,13 +1636,6 @@ group are mutually exclusive.", if interfaces.implements(checker, interfaces.IAstroidChecker): walker.add_checker(checker) - modname = module_desc.name - filepath = module_desc.path - if not module_desc.isarg and not self.should_analyze_file( - modname, filepath - ): - continue - linter.reporter = self._reporter linter.check(module_desc, walker, rawcheckers, tokencheckers) self._plugin_registry.stats["statement"] += walker.nbstatements diff --git a/pylint/utils.py b/pylint/utils.py index 9c32546cd..676840215 100644 --- a/pylint/utils.py +++ b/pylint/utils.py @@ -337,7 +337,8 @@ class MessagesHandlerMixIn: def _set_msg_status( self, msgid, enable, scope="package", line=None, ignore_unknown=False ): - assert scope in ("package", "module") + # "package" is poorly named. Really it should be "global". + assert scope in ("package", "module", "directory") if msgid == "all": for _msgid in MSG_TYPES: @@ -385,15 +386,18 @@ class MessagesHandlerMixIn: else: msgs = self._msgs_state msgs[msg.msgid] = enable - # sync configuration object - self.config.enable = [ - self._message_symbol(mid) for mid, val in sorted(msgs.items()) if val - ] - self.config.disable = [ - self._message_symbol(mid) - for mid, val in sorted(msgs.items()) - if not val - ] + if scope != "directory": + # sync configuration object + self.config.enable = [ + self._message_symbol(mid) + for mid, val in sorted(msgs.items()) + if val + ] + self.config.disable = [ + self._message_symbol(mid) + for mid, val in sorted(msgs.items()) + if not val + ] def _message_symbol(self, msgid): """Get the message symbol of the given message id |