A bare raise statement, i.e. a raise with no exception provided, will re-raise the last active exception in the current
scope. If the "raise" statement is not in an except or finally block, no exception is active and a RuntimeError
is raised instead.
If the bare raise statement is in a function called in an except statement, the exception caught by the
except will be raised. This works but is hard to understand and maintain. Nothing indicates in the parent except that the
exception will be reraised, and nothing prevents a developer from calling the function in another context.
Note also that using a bare raise in a finally block only works when an exception is active, i.e. when an exception from
the try block is not caught or when an exception is raised by an except block. It will fail in any other case and should not
be relied upon. This code smell is handled by rule S5704.
This rule raises an exception when a bare raise statement is not in an except or finally block.
raise # Noncompliant
def foo():
raise # Noncompliant
try:
raise # Noncompliant
except ValueError as e:
handle_error()
except:
raise
else:
raise # Noncompliant
finally:
raise
def handle_error():
raise # Noncompliant. This works but is hard to understand.
raise ValueError()
def foo():
raise ValueError()
try:
raise ValueError()
except:
raise
else:
raise ValueError()
finally:
raise
raise statement