python.correctness.suppressed-exception-handling-finally-break.suppressed-exception-handling-finally-break

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Having a break, continue, or return in a finally block will cause strange behaviors, like exceptions not being caught.

Run Locally

Run in CI

Defintion

rules:
  - id: suppressed-exception-handling-finally-break
    patterns:
      - pattern-either:
          - pattern: |
              try:
                ...
              except $EXCEPTION:
                ...
              finally:
                ...
                break
          - pattern: |
              try:
                ...
              except $EXCEPTION:
                ...
              finally:
                ...
                continue
          - pattern: |
              try:
                ...
              except $EXCEPTION:
                ...
              finally:
                ...
                return ...
          - pattern: |
              try:
                ...
                return ...
              finally:
                ...
                return ...
    message: Having a `break`, `continue`, or `return` in a `finally` block will
      cause strange behaviors, like exceptions not being caught.
    metadata:
      references:
        - https://docs.python.org/3/reference/compound_stmts.html#the-try-statement
        - https://www.python.org/dev/peps/pep-0601/#rejection-note
      category: correctness
      technology:
        - python
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
    languages:
      - python
    severity: WARNING

Examples

suppressed-exception-handling-finally-break.py

try:
  for i in range(3):
    # ruleid: suppressed-exception-handling-finally-break
    try:
      1 / 0
    except ZeroDivisionError:
      raise ZeroDivisionError("Error: you're trying to divide by zero!")
    finally:
      print("finally executed")
      break
except ZeroDivisionError:
  print("outer ZeroDivisionError caught")


try:
  for i in range(3):
    # ruleid: suppressed-exception-handling-finally-break
    try:
      1 / 0
    except ZeroDivisionError:
      raise ZeroDivisionError("Error: you're trying to divide by zero!")
    finally:
      print("finally executed")
      continue
except ZeroDivisionError:
  print("outer ZeroDivisionError caught")

try:
  for i in range(3):
    # ruleid: suppressed-exception-handling-finally-break
    try:
      1 / 0
    except ZeroDivisionError:
      raise ZeroDivisionError("Error: you're trying to divide by zero!")
    finally:
      print("finally executed")
      return None
except ZeroDivisionError:
  print("outer ZeroDivisionError caught")


try:
  for i in range(3):
    # ruleid: suppressed-exception-handling-finally-break
    try:
      1 / 0
    except ZeroDivisionError:
      raise ZeroDivisionError("Error: you're trying to divide by zero!")
    finally:
      print("finally executed")
      return
except ZeroDivisionError:
  print("outer ZeroDivisionError caught")


try:
  for i in range(3):
    # ok: suppressed-exception-handling-finally-break
    try:
      1 / 0
    except ZeroDivisionError:
      raise ZeroDivisionError("Error: you're trying to divide by zero!")
    finally:
      print("finally executed")
except ZeroDivisionError:
  print("outer ZeroDivisionError caught")

# ruleid: suppressed-exception-handling-finally-break
try:
  print("hi")
  return "hi"
finally:
  print("finally")
  return "finally"