|
15 | 15 |
|
16 | 16 | from pylint import checkers
|
17 | 17 | from pylint.checkers import utils
|
| 18 | +from pylint.interfaces import HIGH |
18 | 19 | from pylint.typing import MessageDefinitionTuple
|
19 | 20 |
|
20 | 21 | if TYPE_CHECKING:
|
@@ -131,7 +132,7 @@ def _is_raising(body: list) -> bool:
|
131 | 132 | "try-except-raise block!",
|
132 | 133 | ),
|
133 | 134 | "W0707": (
|
134 |
| - "Consider explicitly re-raising using 'raise NewError(...) from old_error'", |
| 135 | + "Consider explicitly re-raising using %s'%s from %s'", |
135 | 136 | "raise-missing-from",
|
136 | 137 | "Python 3's exception chaining means it shows the traceback of the "
|
137 | 138 | "current exception, but also the original exception. Not using `raise "
|
@@ -333,19 +334,39 @@ def _check_raise_missing_from(self, node: nodes.Raise) -> None:
|
333 | 334 | # like `exc.with_traceback(whatever)`. We won't analyze these, we'll just assume
|
334 | 335 | # there's a violation on two simple cases: `raise SomeException(whatever)` and `raise
|
335 | 336 | # SomeException`.
|
| 337 | + |
| 338 | + need_to_raise = False |
| 339 | + except_as_exc = "" |
| 340 | + exception_name = "exc" |
336 | 341 | if containing_except_node.name is None:
|
337 | 342 | # The `except` doesn't have an `as exception:` part, meaning there's no way that
|
338 | 343 | # the `raise` is raising the same exception.
|
339 |
| - self.add_message("raise-missing-from", node=node) |
340 |
| - elif isinstance(node.exc, nodes.Call) and isinstance(node.exc.func, nodes.Name): |
341 |
| - # We have a `raise SomeException(whatever)`. |
342 |
| - self.add_message("raise-missing-from", node=node) |
| 344 | + if isinstance(containing_except_node.type, nodes.Name): |
| 345 | + class_of_old_error = containing_except_node.type.name |
| 346 | + elif isinstance(containing_except_node.type, nodes.Tuple): |
| 347 | + class_of_old_error = ", ".join( |
| 348 | + n.name for n in containing_except_node.type.elts |
| 349 | + ) |
| 350 | + except_as_exc = f"'except {class_of_old_error} as {exception_name}' and " |
| 351 | + need_to_raise = True |
343 | 352 | elif (
|
344 |
| - isinstance(node.exc, nodes.Name) |
345 |
| - and node.exc.name != containing_except_node.name.name |
| 353 | + isinstance(node.exc, nodes.Call) |
| 354 | + and isinstance(node.exc.func, nodes.Name) |
| 355 | + or ( |
| 356 | + isinstance(node.exc, nodes.Name) |
| 357 | + and node.exc.name != containing_except_node.name.name |
| 358 | + ) |
346 | 359 | ):
|
347 |
| - # We have a `raise SomeException`. |
348 |
| - self.add_message("raise-missing-from", node=node) |
| 360 | + # We have a `raise SomeException(whatever)` or a `raise SomeException` |
| 361 | + exception_name = containing_except_node.name.name |
| 362 | + need_to_raise = True |
| 363 | + if need_to_raise: |
| 364 | + self.add_message( |
| 365 | + "raise-missing-from", |
| 366 | + node=node, |
| 367 | + args=(except_as_exc, node.as_string(), exception_name), |
| 368 | + confidence=HIGH, |
| 369 | + ) |
349 | 370 |
|
350 | 371 | def _check_catching_non_exception(self, handler, exc, part):
|
351 | 372 | if isinstance(exc, nodes.Tuple):
|
|
0 commit comments