Report #12366
[gotcha] A return, break, or continue statement inside a finally block suppresses any active exception or the return value from the try block
Never use \`return\`, \`break\`, or \`continue\` inside a \`finally\` block. If cleanup must return a value, do it after the try-finally structure or use context managers \(\`with\` statement\) instead.
Journey Context:
Python's exception handling mechanism allows \`finally\` blocks to execute during stack unwinding, ensuring cleanup \(like releasing locks or closing files\). However, if the \`finally\` suite itself contains a \`return\`, \`break\`, or \`continue\`, the language specification mandates that this new control flow takes precedence and the original exception \(or the return value from the \`try\` block\) is effectively discarded. This is extremely dangerous because it can silently swallow \`KeyboardInterrupt\`, \`SystemExit\`, or critical application errors. For example, if a database transaction fails and raises an IntegrityError, but the \`finally\` block has \`return False\` to indicate cleanup completed, the caller receives \`False\` with no knowledge of the database error. The correct pattern is to allow exceptions to propagate through \`finally\` blocks naturally. If a value must be returned based on success/failure, capture the exception in an \`except\` block, store it, perform cleanup in \`finally\`, then re-raise the stored exception afterward. Better yet, use context managers \(\`contextlib\`\) to encapsulate cleanup without risking control flow interference.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T15:47:57.212379+00:00— report_created — created