diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | pylint/checkers/exceptions.py | 27 | ||||
-rw-r--r-- | pylint/test/functional/wrong_exception_operation.py | 18 | ||||
-rw-r--r-- | pylint/test/functional/wrong_exception_operation.txt | 3 |
4 files changed, 57 insertions, 1 deletions
@@ -5,7 +5,7 @@ Pylint's ChangeLog What's New in Pylint 2.3.0? =========================== -Release date: TB +Release date: TBA * Refactor ``bad-reversed-sequence`` to account for more objects that can define ``__reversed__`` @@ -15,6 +15,14 @@ Release date: TB Close #2598 +* Added ``wrong-exception-operation`` + + Used when an operation is done against an exception, but the operation + is not valid for the exception in question. Usually emitted when having + binary operations between exceptions in except handlers. + + Close #2494 + What's New in Pylint 2.2.2? =========================== diff --git a/pylint/checkers/exceptions.py b/pylint/checkers/exceptions.py index e0a449ca8..80ea98ae2 100644 --- a/pylint/checkers/exceptions.py +++ b/pylint/checkers/exceptions.py @@ -160,6 +160,13 @@ MSGS = { "constructor, the first of them a string literal containing what " "appears to be placeholders intended for formatting", ), + "W0716": ( + "Invalid exception operation. %s", + "wrong-exception-operation", + "Used when an operation is done against an exception, but the operation " + "is not valid for the exception in question. Usually emitted when having " + "binary operations between exceptions in except handlers.", + ), } @@ -448,6 +455,26 @@ class ExceptionsChecker(checkers.BaseChecker): if bare_raise: self.add_message("try-except-raise", node=handler_having_bare_raise) + @utils.check_messages("wrong-exception-operation") + def visit_binop(self, node): + if isinstance(node.parent, astroid.ExceptHandler): + # except (V | A) + suggestion = "Did you mean '(%s, %s)' instead?" % ( + node.left.as_string(), + node.right.as_string(), + ) + self.add_message("wrong-exception-operation", node=node, args=(suggestion,)) + + @utils.check_messages("wrong-exception-operation") + def visit_compare(self, node): + if isinstance(node.parent, astroid.ExceptHandler): + # except (V < A) + suggestion = "Did you mean '(%s, %s)' instead?" % ( + node.left.as_string(), + ", ".join(operand.as_string() for _, operand in node.ops), + ) + self.add_message("wrong-exception-operation", node=node, args=(suggestion,)) + @utils.check_messages( "bare-except", "broad-except", diff --git a/pylint/test/functional/wrong_exception_operation.py b/pylint/test/functional/wrong_exception_operation.py new file mode 100644 index 000000000..1c3c4e380 --- /dev/null +++ b/pylint/test/functional/wrong_exception_operation.py @@ -0,0 +1,18 @@ +# pylint: disable=missing-docstring, superfluous-parens + + +try: + 1/0 +except (ValueError | TypeError): # [wrong-exception-operation] + pass + +try: + 1/0 +except (ValueError + TypeError): # [wrong-exception-operation] + pass + + +try: + 1/0 +except (ValueError < TypeError): # [wrong-exception-operation] + pass diff --git a/pylint/test/functional/wrong_exception_operation.txt b/pylint/test/functional/wrong_exception_operation.txt new file mode 100644 index 000000000..61a2e179f --- /dev/null +++ b/pylint/test/functional/wrong_exception_operation.txt @@ -0,0 +1,3 @@ +wrong-exception-operation:6::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead? +wrong-exception-operation:11::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead? +wrong-exception-operation:17::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead? |