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.

Noncompliant Code Example

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.

Compliant Solution

raise ValueError()

def foo():
    raise ValueError()
    try:
        raise ValueError()
    except:
        raise
    else:
        raise ValueError()
    finally:
        raise

See