From 2ea3405c512226c2fceb2a4c14fe23013e4a27c5 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Thu, 16 May 2024 22:19:47 +0200 Subject: [PATCH] [trailing-comma-tuple] Properly emit when disabled globally and enabled locally --- .pyenchant_pylint_custom_dict.txt | 1 + doc/whatsnew/fragments/9608.bugfix | 4 ++++ .../refactoring/refactoring_checker.py | 24 ++++++++++++++++--- pylint/lint/message_state_handler.py | 12 ++++++---- tests/functional/t/trailing_comma_tuple.py | 10 ++++++++ tests/functional/t/trailing_comma_tuple.txt | 2 ++ .../functional/t/trailing_comma_tuple_9608.py | 24 +++++++++++++++++++ .../functional/t/trailing_comma_tuple_9608.rc | 5 ++++ .../t/trailing_comma_tuple_9608.txt | 3 +++ 9 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 doc/whatsnew/fragments/9608.bugfix create mode 100644 tests/functional/t/trailing_comma_tuple_9608.py create mode 100644 tests/functional/t/trailing_comma_tuple_9608.rc create mode 100644 tests/functional/t/trailing_comma_tuple_9608.txt diff --git a/.pyenchant_pylint_custom_dict.txt b/.pyenchant_pylint_custom_dict.txt index 4bcff9c9317..78d861aea35 100644 --- a/.pyenchant_pylint_custom_dict.txt +++ b/.pyenchant_pylint_custom_dict.txt @@ -336,6 +336,7 @@ testoptions tmp tokencheckers tokeninfo +tokenization tokenize tokenizer toml diff --git a/doc/whatsnew/fragments/9608.bugfix b/doc/whatsnew/fragments/9608.bugfix new file mode 100644 index 00000000000..badcf32d197 --- /dev/null +++ b/doc/whatsnew/fragments/9608.bugfix @@ -0,0 +1,4 @@ +``trailing-comma-tuple`` should now be correctly emitted when it was disabled globally +but enabled via local message control, after removal of an over-optimisation. + +Refs #9608. diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py index fd3f8bafb0b..c2db7152d9f 100644 --- a/pylint/checkers/refactoring/refactoring_checker.py +++ b/pylint/checkers/refactoring/refactoring_checker.py @@ -652,9 +652,22 @@ def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None: trailing_comma_tuple_enabled_for_file = self.linter.is_message_enabled( "trailing-comma-tuple" ) + trailing_comma_tuple_enabled_once: bool = trailing_comma_tuple_enabled_for_file # Process tokens and look for 'if' or 'elif' for index, token in enumerate(tokens): token_string = token[1] + if ( + not trailing_comma_tuple_enabled_once + and token_string.startswith("#") + and all(c in token_string for c in ("pylint:", "enable")) + and any(c in token_string for c in ("trailing-comma-tuple", "R1707")) + ): + # Way to not have to check if "trailing-comma-tuple" is enabled or + # disabled on each line: Any enable for it during tokenization and + # we'll start using the costly '_is_trailing_comma' to check if we + # need to raise the message. We still won't raise if it's disabled + # again due to the usual generic message control handling later. + trailing_comma_tuple_enabled_once = True if token_string == "elif": # AST exists by the time process_tokens is called, so # it's safe to assume tokens[index+1] exists. @@ -663,9 +676,14 @@ def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None: # token[2] is the actual position and also is # reported by IronPython. self._elifs.extend([token[2], tokens[index + 1][2]]) - elif trailing_comma_tuple_enabled_for_file and _is_trailing_comma( - tokens, index - ): + elif ( + trailing_comma_tuple_enabled_for_file + or trailing_comma_tuple_enabled_once + ) and _is_trailing_comma(tokens, index): + # If "trailing-comma-tuple" is enabled globally we always check _is_trailing_comma + # it might be for nothing if there's a local disable, or if the message control is + # not enabling 'trailing-comma-tuple', but the alternative is having to check if + # it's enabled for a line each line (just to avoid calling '_is_trailing_comma'). self.add_message( "trailing-comma-tuple", line=token.start[0], confidence=HIGH ) diff --git a/pylint/lint/message_state_handler.py b/pylint/lint/message_state_handler.py index 26028f0fab5..2ddd7d4db3c 100644 --- a/pylint/lint/message_state_handler.py +++ b/pylint/lint/message_state_handler.py @@ -305,12 +305,14 @@ def is_message_enabled( line: int | None = None, confidence: interfaces.Confidence | None = None, ) -> bool: - """Return whether this message is enabled for the current file, line and - confidence level. + """Is this message enabled for the current file ? - This function can't be cached right now as the line is the line of - the currently analysed file (self.file_state), if it changes, then the - result for the same msg_descr/line might need to change. + Optionally, is it enabled for this line and confidence level ? + + The current file is implicit and mandatory. As a result this function + can't be cached right now as the line is the line of the currently + analysed file (self.file_state), if it changes, then the result for + the same msg_descr/line might need to change. :param msg_descr: Either the msgid or the symbol for a MessageDefinition :param line: The line of the currently analysed file diff --git a/tests/functional/t/trailing_comma_tuple.py b/tests/functional/t/trailing_comma_tuple.py index de60184cab3..8effe475ec6 100644 --- a/tests/functional/t/trailing_comma_tuple.py +++ b/tests/functional/t/trailing_comma_tuple.py @@ -48,3 +48,13 @@ def some_other_func(): JJJ = some_func(0, 0) + +# pylint: disable-next=trailing-comma-tuple +AAA = 1, +BBB = "aaaa", # [trailing-comma-tuple] +# pylint: disable=trailing-comma-tuple +CCC="aaa", +III = some_func(0, + 0), +# pylint: enable=trailing-comma-tuple +FFF=['f'], # [trailing-comma-tuple] diff --git a/tests/functional/t/trailing_comma_tuple.txt b/tests/functional/t/trailing_comma_tuple.txt index 9b2dddb6814..d65ad72ed85 100644 --- a/tests/functional/t/trailing_comma_tuple.txt +++ b/tests/functional/t/trailing_comma_tuple.txt @@ -7,3 +7,5 @@ trailing-comma-tuple:34:0:None:None::Disallow trailing comma tuple:HIGH trailing-comma-tuple:38:0:None:None::Disallow trailing comma tuple:HIGH trailing-comma-tuple:41:0:None:None::Disallow trailing comma tuple:HIGH trailing-comma-tuple:47:0:None:None::Disallow trailing comma tuple:HIGH +trailing-comma-tuple:54:0:None:None::Disallow trailing comma tuple:HIGH +trailing-comma-tuple:60:0:None:None::Disallow trailing comma tuple:HIGH diff --git a/tests/functional/t/trailing_comma_tuple_9608.py b/tests/functional/t/trailing_comma_tuple_9608.py new file mode 100644 index 00000000000..6e9581f96e2 --- /dev/null +++ b/tests/functional/t/trailing_comma_tuple_9608.py @@ -0,0 +1,24 @@ +"""Check trailing comma tuple optimization.""" +# pylint: disable=missing-docstring + +AAA = 1, +BBB = "aaaa", +CCC="aaa", +FFF=['f'], + +def some_func(first, second): + if first: + return first, + if second: + return (first, second,) + return first, second, + +# pylint: enable=trailing-comma-tuple +AAA = 1, # [trailing-comma-tuple] +BBB = "aaaa", # [trailing-comma-tuple] +# pylint: disable=trailing-comma-tuple +CCC="aaa", +III = some_func(0, + 0), +# pylint: enable=trailing-comma-tuple +FFF=['f'], # [trailing-comma-tuple] diff --git a/tests/functional/t/trailing_comma_tuple_9608.rc b/tests/functional/t/trailing_comma_tuple_9608.rc new file mode 100644 index 00000000000..80157090eb4 --- /dev/null +++ b/tests/functional/t/trailing_comma_tuple_9608.rc @@ -0,0 +1,5 @@ +[MAIN] +disable=trailing-comma-tuple + +[testoptions] +exclude_from_minimal_messages_config=True diff --git a/tests/functional/t/trailing_comma_tuple_9608.txt b/tests/functional/t/trailing_comma_tuple_9608.txt new file mode 100644 index 00000000000..b6ea91784bf --- /dev/null +++ b/tests/functional/t/trailing_comma_tuple_9608.txt @@ -0,0 +1,3 @@ +trailing-comma-tuple:17:0:None:None::Disallow trailing comma tuple:HIGH +trailing-comma-tuple:18:0:None:None::Disallow trailing comma tuple:HIGH +trailing-comma-tuple:24:0:None:None::Disallow trailing comma tuple:HIGH