summaryrefslogtreecommitdiff
path: root/pylint
diff options
context:
space:
mode:
Diffstat (limited to 'pylint')
-rw-r--r--pylint/config/callback_actions.py10
-rw-r--r--pylint/config/config_initialization.py16
-rw-r--r--pylint/lint/message_state_handler.py12
-rw-r--r--pylint/lint/pylinter.py9
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)