Skip to content

Commit

Permalink
[bad-option-value] Add a 'useless-option-value' message
Browse files Browse the repository at this point in the history
So it's possible to to distinguish between genuine typoes and old
configuration that could be cleaned.

We use old_names to decrease message type to warning
  • Loading branch information
Pierre-Sassoulas committed Jun 6, 2022
1 parent 7643fd1 commit d7aca42
Show file tree
Hide file tree
Showing 30 changed files with 100 additions and 63 deletions.
2 changes: 0 additions & 2 deletions doc/data/messages/b/bad-option-value/bad.py

This file was deleted.

2 changes: 0 additions & 2 deletions doc/data/messages/b/bad-option-value/good.py

This file was deleted.

1 change: 1 addition & 0 deletions doc/data/messages/u/unknown-option-value/bad.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# pylint: disable=missnig-docstring # [unknown-option-value]
1 change: 1 addition & 0 deletions doc/data/messages/u/unknown-option-value/good.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# pylint: disable=missing-docstring
3 changes: 3 additions & 0 deletions doc/data/messages/u/useless-option-value/bad.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""'bad-continuation' was removed from pylint in https://github.com/PyCQA/pylint/pull/3571"""

# pylint: disable=bad-continuation # [useless-option-value]
1 change: 1 addition & 0 deletions doc/data/messages/u/useless-option-value/details.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You can disable this check if you don't want to cleanup your configuration of old messages.
1 change: 1 addition & 0 deletions doc/data/messages/u/useless-option-value/good.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""'bad-continuation' was removed from pylint in https://github.com/PyCQA/pylint/pull/3571"""
4 changes: 3 additions & 1 deletion doc/user_guide/messages/messages_overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ All messages in the error category:
error/bad-except-order
error/bad-exception-context
error/bad-format-character
error/bad-option-value
error/bad-plugin-value
error/bad-reversed-sequence
error/bad-str-strip-call
Expand Down Expand Up @@ -178,6 +177,7 @@ All renamed messages in the error category:
:titlesonly:

error/bad-context-manager
error/bad-option-value
error/maybe-no-member
error/old-non-iterator-returned-2
error/old-unbalanced-tuple-unpacking
Expand Down Expand Up @@ -306,6 +306,7 @@ All messages in the warning category:
warning/try-except-raise
warning/unbalanced-tuple-unpacking
warning/undefined-loop-variable
warning/unknown-option-value
warning/unnecessary-ellipsis
warning/unnecessary-lambda
warning/unnecessary-pass
Expand Down Expand Up @@ -507,6 +508,7 @@ All messages in the refactor category:
refactor/use-list-literal
refactor/use-set-for-membership
refactor/useless-object-inheritance
refactor/useless-option-value
refactor/useless-return

All renamed messages in the refactor category:
Expand Down
7 changes: 7 additions & 0 deletions doc/whatsnew/2/2.14/full.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ Release date: TBA

Closes #6624

* ``bad-option-value`` (E0012) is now a warning ``unknown-option-value`` (W0012). Deleted messages that do not exist
anymore in pylint now raise ``useless-option-value`` (R0022) instead of ``bad-option-value``. This allows to
distinguish between genuine typos and configuration that could be cleaned up. Existing message disables for
``bad-option-value`` will still work on both new messages.

Refs #6794


What's New in Pylint 2.14.0?
----------------------------
Expand Down
10 changes: 7 additions & 3 deletions pylint/config/callback_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,14 @@ def _call(
for msgid in utils._check_csv(values[0]):
try:
xabling_function(msgid)
except exceptions.DeletedMessageError as e:
self.linter._stashed_messages[
(self.linter.current_name, "useless-option-value")
].append((option_string, str(e)))
except exceptions.UnknownMessageError:
self.linter._stashed_messages[self.linter.current_name].append(
(option_string, msgid)
)
self.linter._stashed_messages[
(self.linter.current_name, "unknown-option-value")
].append((option_string, msgid))

@abc.abstractmethod
def __call__(
Expand Down
12 changes: 10 additions & 2 deletions pylint/lint/message_state_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def __init__(self, linter: PyLinter) -> None:
self._pragma_lineno: dict[str, int] = {}
# TODO: 3.0: Update key type to str when current_name is always str
self._stashed_messages: defaultdict[
str | None, list[tuple[str | None, str]]
tuple[str | None, str], list[tuple[str | None, str]]
] = defaultdict(list)
"""Some messages in the options (for --enable and --disable) are encountered
too early to warn about them.
Expand Down Expand Up @@ -410,13 +410,21 @@ def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None:
l_start -= 1
try:
meth(msgid, "module", l_start)
except exceptions.DeletedMessageError as e:
self.linter.add_message(
"useless-option-value",
args=(pragma_repr.action, e),
line=start[0],
confidence=HIGH,
)
except exceptions.UnknownMessageError:
self.linter.add_message(
"bad-option-value",
"unknown-option-value",
args=(pragma_repr.action, msgid),
line=start[0],
confidence=HIGH,
)

except UnRecognizedOptionError as err:
self.linter.add_message(
"unrecognized-inline-option", args=err.token, line=start[0]
Expand Down
32 changes: 23 additions & 9 deletions pylint/lint/pylinter.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,24 @@ def _load_reporter_by_class(reporter_class: str) -> type[BaseReporter]:
"Used when an unknown inline option is encountered.",
{"scope": WarningScope.LINE},
),
"E0012": (
"Bad option value for '%s', expected a valid pylint message and got '%s'",
"bad-option-value",
"Used when a bad value for an option is encountered.",
{"scope": WarningScope.LINE},
"W0012": (
"Unknown option value for '%s', expected a valid pylint message and got '%s'",
"unknown-option-value",
"Used when an unknown value is encountered for an option.",
{
"scope": WarningScope.LINE,
"old_names": [("E0012", "bad-option-value")],
},
),
"R0022": (
"Useless option value for '%s', %s",
"useless-option-value",
"Used when a value for an option that is now deleted from pylint"
" is encountered.",
{
"scope": WarningScope.LINE,
"old_names": [("E0012", "bad-option-value")],
},
),
"E0013": (
"Plugin '%s' is impossible to load, is it installed ? ('%s')",
Expand Down Expand Up @@ -1203,12 +1216,13 @@ def add_ignored_message(
)

def _emit_stashed_messages(self) -> None:
for modname, values in self._stashed_messages.items():
for keys, values in self._stashed_messages.items():
modname, symbol = keys
self.linter.set_current_module(modname)
for option_string, msgid in values:
for args in values:
self.add_message(
"bad-option-value",
args=(option_string, msgid),
symbol,
args=args,
line=0,
confidence=HIGH,
)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
************* Module {abspath}
{relpath}:1:0: R0022: Useless option value for '--disable', 'buffer-builtin' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942. (useless-option-value)
{relpath}:1:0: R0022: Useless option value for '--enable', 'cmp-builtin' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942. (useless-option-value)
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"functional_append": {
"disable": ["logging-not-lazy"],
"enable": ["locally-disabled"]
"enable": ["locally-disabled", "useless-option-value"]
},
"functional_remove": {
"disable": ["locally-disabled"],
"disable": ["locally-disabled", "useless-option-value"],
"enable": ["logging-not-lazy"]
},
"jobs": 10,
Expand Down
3 changes: 0 additions & 3 deletions tests/config/functional/ini/pylintrc_with_missing_comma.2.out

This file was deleted.

3 changes: 3 additions & 0 deletions tests/config/functional/ini/pylintrc_with_missing_comma.4.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
************* Module {abspath}
{relpath}:1:0: W0012: Unknown option value for '--disable', expected a valid pylint message and got 'logging-not-lazylogging-format-interpolation' (unknown-option-value)
{relpath}:1:0: W0012: Unknown option value for '--enable', expected a valid pylint message and got 'locally-disabledsuppressed-message' (unknown-option-value)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
************* Module {abspath}
{relpath}:1:0: W0012: Unknown option value for '--enable', expected a valid pylint message and got 'useless-supression' (unknown-option-value)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
************* Module {abspath}
{relpath}:1:0: W0012: Unknown option value for '--disable', expected a valid pylint message and got 'logging-not-lazylogging-format-interpolation' (unknown-option-value)
{relpath}:1:0: W0012: Unknown option value for '--enable', expected a valid pylint message and got 'locally-disabledsuppressed-message' (unknown-option-value)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
************* Module {abspath}
{relpath}:1:0: W0012: Unknown option value for '--disable', expected a valid pylint message and got 'logging-not-layzy' (unknown-option-value)
{relpath}:1:0: W0012: Unknown option value for '--enable', expected a valid pylint message and got 'C00000' (unknown-option-value)
2 changes: 1 addition & 1 deletion tests/config/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_unknown_message_id(capsys: CaptureFixture) -> None:
"""Check that we correctly raise a message on an unknown id."""
Run([str(EMPTY_MODULE), "--disable=12345"], exit=False)
output = capsys.readouterr()
assert "Command line:1:0: E0012: Bad option value for '--disable'" in output.out
assert "Command line:1:0: W0012: Unknown option value for '--disable'" in output.out


def test_unknown_option_name(capsys: CaptureFixture) -> None:
Expand Down
22 changes: 11 additions & 11 deletions tests/functional/b/bad_option_value.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
"""Check unknown or deleted option. """

# Standard disable with unknown value
# pylint: disable=C05048 # [bad-option-value]
# pylint: disable=C05048 # [unknown-option-value]
# Standard disable with deleted symbol
# pylint: disable=execfile-builtin # [bad-option-value]
# pylint: disable=execfile-builtin # [useless-option-value]
# Standard disable with deleted msgid
# pylint: disable=W1656 # [bad-option-value]
# pylint: disable=W1656 # [useless-option-value]
# disable-next with unknown value
# pylint: disable-next=R78948 # [bad-option-value]
# pylint: disable-next=R78948 # [unknown-option-value]
# disable-next with deleted symbol
# pylint: disable-next=deprecated-types-field # [bad-option-value]
# pylint: disable-next=deprecated-types-field # [useless-option-value]
# disable-next with deleted msgid
# pylint: disable-next=W1634 # [bad-option-value]
# pylint: disable-next=W1634 # [useless-option-value]

# enable with unknown value
# pylint:enable=W04044 # [bad-option-value]
# pylint:enable=W04044 # [unknown-option-value]
# enable with deleted symbol
# pylint:enable=no-space-after-comma # [bad-option-value]
# pylint:enable=dict-values-not-iterating # [useless-option-value]
# enable with deleted msgid
# pylint:enable=W1622 # [bad-option-value]
# pylint:enable=W1622 # [useless-option-value]

# Standard disable with deleted old name symbol of deleted message
# pylint: disable=no-space-after-operator # [bad-option-value]
# pylint: disable=no-space-after-operator # [bad-option-value] <= This is wrong
# Standard disable with deleted old name msgid of deleted message
# pylint: disable=C0323 # [bad-option-value]
# pylint: disable=C0323 # [bad-option-value] <= This is wrong
18 changes: 9 additions & 9 deletions tests/functional/b/bad_option_value.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
bad-option-value:4:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'C05048':HIGH
bad-option-value:6:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'execfile-builtin':HIGH
bad-option-value:8:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'W1656':HIGH
bad-option-value:10:0:None:None::Bad option value for 'disable-next', expected a valid pylint message and got 'R78948':HIGH
bad-option-value:12:0:None:None::Bad option value for 'disable-next', expected a valid pylint message and got 'deprecated-types-field':HIGH
bad-option-value:14:0:None:None::Bad option value for 'disable-next', expected a valid pylint message and got 'W1634':HIGH
bad-option-value:17:0:None:None::Bad option value for 'enable', expected a valid pylint message and got 'W04044':HIGH
bad-option-value:19:0:None:None::Bad option value for 'enable', expected a valid pylint message and got 'no-space-after-comma':HIGH
bad-option-value:21:0:None:None::Bad option value for 'enable', expected a valid pylint message and got 'W1622':HIGH
unknown-option-value:4:0:None:None::Unknown option value for 'disable', expected a valid pylint message and got 'C05048':HIGH
useless-option-value:6:0:None:None::"Useless option value for 'disable', 'execfile-builtin' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
useless-option-value:8:0:None:None::"Useless option value for 'disable', 'W1656' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
unknown-option-value:10:0:None:None::Unknown option value for 'disable-next', expected a valid pylint message and got 'R78948':HIGH
useless-option-value:12:0:None:None::"Useless option value for 'disable-next', 'deprecated-types-field' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
useless-option-value:14:0:None:None::"Useless option value for 'disable-next', 'W1634' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
unknown-option-value:17:0:None:None::Unknown option value for 'enable', expected a valid pylint message and got 'W04044':HIGH
useless-option-value:19:0:None:None::"Useless option value for 'enable', 'dict-values-not-iterating' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
useless-option-value:21:0:None:None::"Useless option value for 'enable', 'W1622' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
bad-option-value:24:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'no-space-after-operator':HIGH
bad-option-value:26:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'C0323':HIGH
4 changes: 2 additions & 2 deletions tests/functional/b/bad_option_value_disable.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

# pylint: enable=bad-option-value

var = 1 # pylint: disable=a-removed-option # [bad-option-value]
var = 1 # pylint: disable=a-removed-option # [unknown-option-value]

# bad-option-value needs to be disabled before the bad option
var = 1 # pylint: disable=a-removed-option, bad-option-value # [bad-option-value]
var = 1 # pylint: disable=a-removed-option, bad-option-value # [unknown-option-value]
var = 1 # pylint: disable=bad-option-value, a-removed-option
4 changes: 2 additions & 2 deletions tests/functional/b/bad_option_value_disable.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
bad-option-value:10:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'a-removed-option':HIGH
bad-option-value:13:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'a-removed-option':HIGH
unknown-option-value:10:0:None:None::Unknown option value for 'disable', expected a valid pylint message and got 'a-removed-option':HIGH
unknown-option-value:13:0:None:None::Unknown option value for 'disable', expected a valid pylint message and got 'a-removed-option':HIGH
2 changes: 1 addition & 1 deletion tests/functional/u/use/use_symbolic_message_instead.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# pylint: disable=C0111,R0903,T1234 # [bad-option-value,use-symbolic-message-instead,use-symbolic-message-instead]
# pylint: disable=C0111,R0903,T1234 # [unknown-option-value,use-symbolic-message-instead,use-symbolic-message-instead]
# pylint: enable=c0111,w0223 # [use-symbolic-message-instead,use-symbolic-message-instead]

def my_function(arg): # [missing-function-docstring]
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/u/use/use_symbolic_message_instead.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
bad-option-value:1:0:None:None::Bad option value for 'disable', expected a valid pylint message and got 'T1234':HIGH
unknown-option-value:1:0:None:None::Unknown option value for 'disable', expected a valid pylint message and got 'T1234':HIGH
use-symbolic-message-instead:1:0:None:None::"'C0111' is cryptic: use '# pylint: disable=missing-docstring' instead":UNDEFINED
use-symbolic-message-instead:1:0:None:None::"'R0903' is cryptic: use '# pylint: disable=too-few-public-methods' instead":UNDEFINED
use-symbolic-message-instead:2:0:None:None::"'c0111' is cryptic: use '# pylint: enable=missing-docstring' instead":UNDEFINED
Expand Down

0 comments on commit d7aca42

Please sign in to comment.