Generator's close() method was called
Raised when a generator or coroutine is closed by calling its `close()` method. This is a signal for the generator to perform any cleanup, like closing files or releasing resources.
- 1Explicitly calling `.close()` on a generator object.
- 2The generator object being garbage collected, which implicitly calls `.close()`.
- 3An external control flow change, like breaking out of a loop that is driving the generator.
This exception is raised inside a generator when its `close()` method is invoked from outside.
def my_generator():
try:
print("Generator started")
yield 1
except GeneratorExit:
print("Generator closing!")
g = my_generator()
print(next(g))
g.close() # This triggers the GeneratorExit
expected output
Generator started 1 Generator closing!
Fix 1
Use a `try...finally` block for cleanup
WHEN A generator needs to guarantee that a resource is released, regardless of how it exits.
def file_reader_gen(path):
f = open(path, 'r')
try:
for line in f:
yield line
finally:
print("Closing file.")
f.close()
Why this works
The `finally` block is guaranteed to execute whether the generator is exhausted normally, closed with `.close()`, or garbage collected. This makes it the ideal place for cleanup code.
Fix 2
Use a `with` statement inside the generator
WHEN The resource you are managing is a context manager (like a file).
def file_reader_gen_with(path):
with open(path, 'r') as f:
for line in f:
yield line
print("File automatically closed.")
Why this works
The `with` statement automatically handles entering and exiting the context, which includes closing the file. This happens correctly even when `GeneratorExit` is raised.
def gen():
yield 1
g = gen()
next(g)
g.close() # sends GeneratorExit into generatordef resource_gen():
r = acquire()
try:
while True:
yield r.next()
except GeneratorExit:
r.close()
raisefrom contextlib import contextmanager
@contextmanager
def managed():
r = acquire()
try:
yield r
finally:
r.close()✕ Yielding another value after catching `GeneratorExit`
After a generator has been signaled to close, it must not yield any more values. Doing so will result in a `RuntimeError`.
cpython/Objects/genobject.c
Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev