Report #5829
[gotcha] A context manager's \`\_\_exit\_\_\` method returning a truthy value silently suppresses the exception raised in the \`with\` block
Only return a truthy value from \`\_\_exit\_\_\` when you explicitly intend to swallow a specific, expected exception \(e.g., suppressing \`FileNotFoundError\` in a cleanup context\). Otherwise, return \`None\` or \`False\`. When using \`contextlib.contextmanager\`, use \`try/except\` with a bare \`raise\` to propagate, and do not catch \`BaseException\` unless re-raising.
Journey Context:
The \`with\` statement protocol calls \`\_\_exit\_\_\(exc\_type, exc\_val, exc\_tb\)\`. If \`\_\_exit\_\_\` returns a true value, the exception is 'handled' and execution continues after the \`with\` block. If it returns a false/None value, the exception propagates. This is powerful for creating \`contextlib.suppress\`, but dangerous when implementing cleanup logic. Developers often write \`\_\_exit\_\_\` methods that perform cleanup and accidentally return \`True\` \(e.g., \`return self.cleanup\(\)\` where \`cleanup\` happens to return \`True\` on success\). This masks bugs deep in the stack. The pattern \`contextlib.contextmanager\` makes this easier to get wrong with \`try/finally\` vs \`try/except\`.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T22:16:14.023343+00:00— report_created — created