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

Python generator send and close: suspension retains state until cleanup

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

A generator preserves a suspended frame between yields, and send supplies the value received by its current yield expression.

Download Python source kit

Operation contract

The running-total generator emits its current total before accepting another amount. next primes the first suspension point; send then validates and incorporates the received amount before yielding again. An invalid amount exits the generator through ValueError and executes its finally block. A second generator is closed explicitly after priming. Neither path publishes the partially accepted state to an external ledger.

Failure and ownership boundary

A non-None value cannot be sent into a generator that has not reached its first yield. close requests termination at the suspension point; cleanup must not try to yield another value in response. Python generators: lazy iteration does not make retained output free, Python context managers: clean up on success and failure and Python async generators: close a suspended producer when leaving early use related lifetime rules, but they are not interchangeable APIs.

Working program

python
closed = []
def running_total():
    total = 0
    try:
        while True:
            amount = yield total
            if type(amount) is not int or not 0 <= amount <= 1000:
                raise ValueError("bounded exact amount required")
            total += amount
    finally:
        closed.append("released")

producer = running_total()
print("initial:", next(producer))
print("accepted:", producer.send(125))
try:
    producer.send(True)
except ValueError:
    print("invalid send rejected")
print("closed:", closed)
second = running_total()
next(second)
second.close()
print("explicit closes:", len(closed))

Output

Output
initial: 0
accepted: 125
invalid send rejected
closed: ['released']
explicit closes: 2

Costs and limits

A suspended frame retains its locals and reachable objects. This generator has constant-sized application state, except for growing integer digit length and the demonstration cleanup list. A producer owning a file or cursor needs explicit caller cleanup when iteration ends early.

Common Mistakes

  • Prime a generator before sending a non-None value.
  • Do not assume an early loop break closes a retained generator.

Connected lessons

Python generators: lazy iteration does not make retained output free, Python iterators: exhaustion and repeatable collection ownership, Python async generators: close a suspended producer when leaving early.

python
generator-control
Storage details