diff options
Diffstat (limited to 'pylint')
-rw-r--r-- | pylint/config/callback_actions.py | 10 | ||||
-rw-r--r-- | pylint/config/config_initialization.py | 16 | ||||
-rw-r--r-- | pylint/lint/message_state_handler.py | 12 | ||||
-rw-r--r-- | pylint/lint/pylinter.py | 9 |
4 files changed, 40 insertions, 7 deletions
diff --git a/pylint/config/callback_actions.py b/pylint/config/callback_actions.py index 8ca2a2d6c..15a42daea 100644 --- a/pylint/config/callback_actions.py +++ b/pylint/config/callback_actions.py @@ -381,8 +381,9 @@ class _DisableAction(_AccessLinterObjectAction): try: self.linter.disable(msgid) except exceptions.UnknownMessageError: - msg = f"{option_string}. Don't recognize message {msgid}." - self.linter.add_message("bad-option-value", args=msg, line=0) + self.linter._stashed_bad_option_value_messages[ + self.linter.current_name + ].append((option_string, msgid)) class _EnableAction(_AccessLinterObjectAction): @@ -401,8 +402,9 @@ class _EnableAction(_AccessLinterObjectAction): try: self.linter.enable(msgid) except exceptions.UnknownMessageError: - msg = f"{option_string}. Don't recognize message {msgid}." - self.linter.add_message("bad-option-value", args=msg, line=0) + self.linter._stashed_bad_option_value_messages[ + self.linter.current_name + ].append((option_string, msgid)) class _OutputFormatAction(_AccessLinterObjectAction): diff --git a/pylint/config/config_initialization.py b/pylint/config/config_initialization.py index 49dfa24fd..b5bd31234 100644 --- a/pylint/config/config_initialization.py +++ b/pylint/config/config_initialization.py @@ -31,7 +31,7 @@ def _config_initialization( # Set the current module to the configuration file # to allow raising messages on the configuration file. - linter.set_current_module(str(config_file) if config_file else None) + linter.set_current_module(str(config_file) if config_file else "") # Read the configuration file config_file_parser = _ConfigurationFileParser(verbose_mode, linter) @@ -51,12 +51,12 @@ def _config_initialization( if "load-plugins" in config_data: linter.load_plugin_modules(utils._splitstrip(config_data["load-plugins"])) + unrecognized_options_message = None # First we parse any options from a configuration file try: linter._parse_configuration_file(config_args) except _UnrecognizedOptionError as exc: - msg = ", ".join(exc.options) - linter.add_message("unrecognized-option", line=0, args=msg) + unrecognized_options_message = ", ".join(exc.options) # Then, if a custom reporter is provided as argument, it may be overridden # by file parameters, so we re-set it here. We do this before command line @@ -83,6 +83,16 @@ def _config_initialization( msg = ", ".join(unrecognized_options) linter._arg_parser.error(f"Unrecognized option found: {msg}") + # Now that config file and command line options have been loaded + # with all disables, it is safe to emit messages + if unrecognized_options_message is not None: + linter.set_current_module(str(config_file) if config_file else "") + linter.add_message( + "unrecognized-option", args=unrecognized_options_message, line=0 + ) + + linter._emit_bad_option_value() + # Set the current module to configuration as we don't know where # the --load-plugins key is coming from linter.set_current_module("Command line or configuration file") diff --git a/pylint/lint/message_state_handler.py b/pylint/lint/message_state_handler.py index 2477502bd..31278dc59 100644 --- a/pylint/lint/message_state_handler.py +++ b/pylint/lint/message_state_handler.py @@ -6,6 +6,7 @@ from __future__ import annotations import sys import tokenize +from collections import defaultdict from typing import TYPE_CHECKING from pylint import exceptions, interfaces @@ -53,6 +54,17 @@ class _MessageStateHandler: "enable-msg": self._options_methods["enable"], } self._pragma_lineno: dict[str, int] = {} + # TODO: 3.0: Update key type to str when current_name is always str + self._stashed_bad_option_value_messages: defaultdict[ + str | None, list[tuple[str | None, str]] + ] = defaultdict(list) + """Bad option values for --enable and --disable are encountered too early to + warn about them, i.e. before all option providers have been fully parsed. + + Thus, + this dict stores option_value and msg_id needed to (later) emit the + bad-option-value messages keyed on module names. + """ def _set_one_msg_status( self, scope: str, msg: MessageDefinition, line: int | None, enable: bool diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py index 7ab822025..0dc9b8c0d 100644 --- a/pylint/lint/pylinter.py +++ b/pylint/lint/pylinter.py @@ -1196,3 +1196,12 @@ class PyLinter( message_definition.msgid, line, ) + + def _emit_bad_option_value(self) -> None: + for modname in self._stashed_bad_option_value_messages: + self.linter.set_current_module(modname) + values = self._stashed_bad_option_value_messages[modname] + for option_string, msg_id in values: + msg = f"{option_string}. Don't recognize message {msg_id}." + self.add_message("bad-option-value", args=msg, line=0) + self._stashed_bad_option_value_messages = collections.defaultdict(list) |