Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python ExitStack: unwind partially acquired resources

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

ExitStack records cleanup actions and runs them in reverse registration order when its context exits.

Download Python source kit

Operation contract

The import acquires two owned in-memory streams before a third acquisition fails. Previously acquired streams close through the stack even though the main import never starts. Register cleanup immediately after each successful acquisition. A separate close callback records order so the failure path can be inspected without using a real service.

Failure and ownership boundary

ExitStack.callback does not suppress an exception. Context managers entered through enter_context may have different exit behavior. A callback that raises can change the visible failure, so cleanup itself needs a failure policy. The stack does not close resources merely because it is garbage collected. Python context managers: clean up on success and failure and Python exceptions: translate an input error without hiding its cause supply the underlying rules.

Working program

python
from contextlib import ExitStack
from io import StringIO

closed = []
def release(stream, label):
    stream.close()
    closed.append(label)

streams = []
try:
    with ExitStack() as stack:
        for label in ("receipts", "prices"):
            stream = StringIO(label)
            streams.append(stream)
            stack.callback(release, stream, label)
        raise OSError("third input unavailable")
except OSError:
    print("acquisition failed")
print(closed)
print(all(stream.closed for stream in streams))

Output

Output
acquisition failed
['prices', 'receipts']
True

Costs and limits

Registering k callbacks retains O(k) cleanup state. Unwinding takes the sum of their costs. Resource acquisition and close latency are external to the stack bookkeeping and may block.

Common Mistakes

  • Register cleanup before attempting the next acquisition.
  • Do not depend on stack garbage collection to release resources.

Connected lessons

Python context managers: clean up on success and failure, Python pathlib files: specify encoding and close the resource owner, Python exceptions: translate an input error without hiding its cause.

Follow the ownership and update boundary

Python ExitStack pop_all: transfer cleanup without discarding it.

python
exit-stack
Storage details