diff options
author | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2021-11-24 10:12:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-24 10:12:01 +0100 |
commit | e8fa46928d91893723a9a038fde2d274d535fd1f (patch) | |
tree | 9a8803b19061fe5d244f6fd34348bf9f838a0ed4 | |
parent | e3a1e359704a48d8bbe8ce00e54f4ddfebcf620e (diff) | |
download | pylint-git-e8fa46928d91893723a9a038fde2d274d535fd1f.tar.gz |
Fix a crash on psycopg2 for elif used (#5369)
* Fix a crash in the ``check_elif`` extensions where an undetected if in a comprehension
with an if statement within a f-string resulted in an out of range error. The checker no
longer relies on counting if statements anymore and uses known if statements locations instead.
It should not crash on badly parsed if statements anymore. specify the confidence of the message
* Remove disable for else-if-used in pylint/checkers/classes.py
Co-authored-by: Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | pylint/checkers/classes.py | 26 | ||||
-rw-r--r-- | pylint/extensions/check_elif.py | 38 | ||||
-rw-r--r-- | tests/functional/ext/check_elif/check_elif.py | 23 | ||||
-rw-r--r-- | tests/functional/ext/check_elif/check_elif.txt | 6 |
5 files changed, 57 insertions, 41 deletions
@@ -17,6 +17,11 @@ Release date: TBA * Fix ``install graphiz`` message which isn't needed for puml output format. +* Fix a crash in the ``check_elif`` extensions where an undetected if in a comprehension + with an if statement within a f-string resulted in an out of range error. The checker no + longer relies on counting if statements anymore and uses known if statements locations instead. + It should not crash on badly parsed if statements anymore. + * Fix ``simplify-boolean-expression`` when condition can be inferred as False. Closes #5200 diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py index 319a37f73..37651cdfd 100644 --- a/pylint/checkers/classes.py +++ b/pylint/checkers/classes.py @@ -1848,20 +1848,18 @@ a metaclass class method.", "bad-mcs-method-argument", node.name, ) - # regular class - else: # pylint: disable=else-if-used - # class method - if node.type == "classmethod" or node.name == "__class_getitem__": - self._check_first_arg_config( - first, - self.config.valid_classmethod_first_arg, - node, - "bad-classmethod-argument", - node.name, - ) - # regular method without self as argument - elif first != "self": - self.add_message("no-self-argument", node=node) + # regular class with class method + elif node.type == "classmethod" or node.name == "__class_getitem__": + self._check_first_arg_config( + first, + self.config.valid_classmethod_first_arg, + node, + "bad-classmethod-argument", + node.name, + ) + # regular class with regular method without self as argument + elif first != "self": + self.add_message("no-self-argument", node=node) def _check_first_arg_config(self, first, config, node, message, method_name): if first not in config: diff --git a/pylint/extensions/check_elif.py b/pylint/extensions/check_elif.py index 8dcfb74b3..aa4457748 100644 --- a/pylint/extensions/check_elif.py +++ b/pylint/extensions/check_elif.py @@ -15,7 +15,7 @@ from astroid import nodes from pylint.checkers import BaseTokenChecker from pylint.checkers.utils import check_messages -from pylint.interfaces import IAstroidChecker, ITokenChecker +from pylint.interfaces import HIGH, IAstroidChecker, ITokenChecker class ElseifUsedChecker(BaseTokenChecker): @@ -38,37 +38,27 @@ class ElseifUsedChecker(BaseTokenChecker): self._init() def _init(self): - self._elifs = [] - self._if_counter = 0 + self._elifs = {} def process_tokens(self, tokens): - # Process tokens and look for 'if' or 'elif' - for _, token, _, _, _ in tokens: - if token == "elif": - self._elifs.append(True) - elif token == "if": - self._elifs.append(False) + """Process tokens and look for 'if' or 'elif'""" + self._elifs = { + begin: token for _, token, begin, _, _ in tokens if token in {"elif", "if"} + } def leave_module(self, _: nodes.Module) -> None: self._init() - def visit_ifexp(self, node: nodes.IfExp) -> None: - if isinstance(node.parent, nodes.FormattedValue): - return - self._if_counter += 1 - - def visit_comprehension(self, node: nodes.Comprehension) -> None: - self._if_counter += len(node.ifs) - @check_messages("else-if-used") def visit_if(self, node: nodes.If) -> None: - if isinstance(node.parent, nodes.If): - orelse = node.parent.orelse - # current if node must directly follow an "else" - if orelse and orelse == [node]: - if not self._elifs[self._if_counter]: - self.add_message("else-if-used", node=node) - self._if_counter += 1 + """Current if node must directly follow an 'else'""" + if ( + isinstance(node.parent, nodes.If) + and node.parent.orelse == [node] + and (node.lineno, node.col_offset) in self._elifs + and self._elifs[(node.lineno, node.col_offset)] == "if" + ): + self.add_message("else-if-used", node=node, confidence=HIGH) def register(linter): diff --git a/tests/functional/ext/check_elif/check_elif.py b/tests/functional/ext/check_elif/check_elif.py index b9722f349..f03c76839 100644 --- a/tests/functional/ext/check_elif/check_elif.py +++ b/tests/functional/ext/check_elif/check_elif.py @@ -1,4 +1,7 @@ +# pylint: disable=no-else-raise,unsupported-membership-test,using-constant-test + """Checks use of "else if" triggers a refactor message""" +from typing import Union, Sequence, Any, Mapping def my_function(): @@ -7,7 +10,7 @@ def my_function(): if myint > 5: pass else: - if myint <= 5: # [else-if-used] + if myint <= 5: # [else-if-used] pass else: myint = 3 @@ -25,3 +28,21 @@ def my_function(): if myint: pass myint = 4 + + +def _if_in_fstring_comprehension_with_elif( + params: Union[Sequence[Any], Mapping[str, Any]] +): + order = {} + if "z" not in "false": + raise TypeError( + f" {', '.join(sorted(i for i in order or () if i not in params))}" + ) + elif "z" not in "true": + pass + else: + if "t" not in "false": # [else-if-used] + raise TypeError("d") + else: + if "y" in "life": # [else-if-used] + print("e") diff --git a/tests/functional/ext/check_elif/check_elif.txt b/tests/functional/ext/check_elif/check_elif.txt index 43d1e3b1e..88853eb95 100644 --- a/tests/functional/ext/check_elif/check_elif.txt +++ b/tests/functional/ext/check_elif/check_elif.txt @@ -1,2 +1,4 @@ -else-if-used:10:8:my_function:"Consider using ""elif"" instead of ""else if""":HIGH -else-if-used:22:20:my_function:"Consider using ""elif"" instead of ""else if""":HIGH +else-if-used:13:8:my_function:"Consider using ""elif"" instead of ""else if""":HIGH +else-if-used:25:20:my_function:"Consider using ""elif"" instead of ""else if""":HIGH +else-if-used:44:8:_if_in_fstring_comprehension_with_elif:"Consider using ""elif"" instead of ""else if""":HIGH +else-if-used:47:12:_if_in_fstring_comprehension_with_elif:"Consider using ""elif"" instead of ""else if""":HIGH |