summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshley Whetter <ashley@awhetter.co.uk>2018-07-29 15:47:22 -0700
committerAshley Whetter <ashley@awhetter.co.uk>2019-02-09 13:40:54 -0800
commitf19b9ff7c5a2363cbcaff1da350128c1435e092f (patch)
tree2cd800afeffdc346fac7f08c9721e64adca7720e
parent76b3e8ed90d9ecb6d8a59eaa0240b18622cdbe86 (diff)
downloadpylint-git-f19b9ff7c5a2363cbcaff1da350128c1435e092f.tar.gz
Fixed "enable" and "disable" options
-rw-r--r--pylint/config.py36
-rw-r--r--pylint/lint.py83
-rw-r--r--pylint/utils.py24
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