← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Context Managers & with Statement

Python Python 2.5+ Intermediate
debt(d3/e1/b3/t5)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3) — pylint/ruff/flake8 flag bare open() without with (e.g. ruff SIM115, pylint consider-using-with).

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch' (e1) — quick_fix is literally wrapping in 'with open(path) as f:', a single-line replacement per occurrence.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3) — resource management pattern applies wherever resources are acquired, but each use is self-contained; doesn't shape architecture.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5) — the misconception that context managers are only for files, plus the contextlib.contextmanager try/finally gotcha, are documented traps most Python devs learn over time.

About DEBT scoring →

Also Known As

Python with statement context manager __enter__ __exit__

TL;DR

The with statement guarantees __exit__ runs even on exception — used for file handles, locks, transactions, and any resource needing cleanup.

Explanation

Context managers implement __enter__ (setup, returns the resource) and __exit__ (cleanup, always called) — or use @contextlib.contextmanager with yield. with open('file') as f: closes the file whether the body succeeds or raises. Multiple resources: with open(a) as f, open(b) as g. Custom managers: @contextlib.contextmanager def db_transaction(conn): try: yield conn; conn.commit() except: conn.rollback(). contextlib.suppress(FileNotFoundError) silently ignores specific exceptions. contextlib.ExitStack manages a dynamic number of resources. The PHP equivalent is try/finally blocks or RAII patterns — Python's with is more ergonomic and prevents resource leaks idiomatically.

Diagram

flowchart TD
    WITH[with statement] --> ENTER[__enter__ called<br/>acquire resource]
    ENTER --> BODY[Execute body]
    BODY -->|normal exit| EXIT[__exit__ called<br/>release resource]
    BODY -->|exception| EXIT2[__exit__ called<br/>even on exception]
    EXIT & EXIT2 --> CLEAN[Resource always cleaned up]
    subgraph Examples
        FILE2[with open file as f<br/>auto close]
        LOCK2[with lock:<br/>auto release]
        DB2[with db.transaction:<br/>auto commit or rollback]
        MOCK2[with patch target:<br/>auto unpatch]
    end
style CLEAN fill:#238636,color:#fff
style EXIT2 fill:#d29922,color:#fff

Common Misconception

Context managers are only for file handling. Any resource that needs guaranteed cleanup — database connections, locks, network sockets, temporary directories — benefits from a context manager. The with statement guarantees __exit__ is called even if an exception occurs.

Why It Matters

Context managers (with statements) guarantee cleanup code runs even when exceptions occur — replacing try/finally patterns with a reusable, readable protocol.

Common Mistakes

  • Not using with for file operations — files are not closed on exception without it.
  • Not implementing __exit__ to handle exceptions — a context manager that re-raises is fine, but it must return False.
  • Using contextlib.contextmanager without wrapping the yield in try/finally — cleanup skipped on exception.
  • Nested with statements instead of a single with statement with multiple context managers.

Code Examples

✗ Vulnerable
# File not closed on exception:
f = open('data.txt')
data = f.read()  # Exception here leaves file open
f.close()        # Never reached

# Context manager — always closes:
with open('data.txt') as f:
    data = f.read()  # Exception here still closes the file
✓ Fixed
from contextlib import contextmanager

@contextmanager
def managed_transaction(conn):
    try:
        yield conn
        conn.commit()
    except Exception:
        conn.rollback()
        raise

with managed_transaction(db) as conn:
    conn.execute('INSERT ...')

Added 15 Mar 2026
Edited 22 Mar 2026
Views 68
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 3 pings F 3 pings S 3 pings S 2 pings M 2 pings T 2 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 2 pings S 1 ping S 1 ping M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Scrapy 12 Amazonbot 11 Perplexity 6 Google 5 Ahrefs 4 PetalBot 3 Claude 2 SEMrush 2 ChatGPT 1 Unknown AI 1 Bing 1 Meta AI 1 Sogou 1
crawler 48 crawler_json 2
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Use 'with open(path) as f:' for all file operations — the context manager guarantees the file is closed even if an exception occurs
📦 Applies To
python 2.5 web cli
🔗 Prerequisites
🔍 Detection Hints
f = open() without 'with' statement; database connection not in context manager; lock acquired without guaranteed release
Auto-detectable: ✓ Yes pylint ruff flake8
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Function Tests: Update
CWE-404


✓ schema.org compliant