Skip to content

Commit db552dd

Browse files
authored
[3.13] gh-142766: Clear frame when generator.close() is called (gh-142838) (#142900)
(cherry picked from commit 25397f9)
1 parent 08d665d commit db552dd

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

Lib/test/test_generators.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,33 @@ def loop():
246246
#This should not raise
247247
loop()
248248

249+
def test_close_clears_frame(self):
250+
# gh-142766: Test that closing a generator clears its frame
251+
class DetectDelete:
252+
def __init__(self):
253+
DetectDelete.deleted = False
254+
255+
def __del__(self):
256+
DetectDelete.deleted = True
257+
258+
def generator(arg):
259+
yield
260+
261+
# Test a freshly created generator (not suspended)
262+
g = generator(DetectDelete())
263+
g.close()
264+
self.assertTrue(DetectDelete.deleted)
265+
266+
# Test a suspended generator
267+
g = generator(DetectDelete())
268+
next(g)
269+
g.close()
270+
self.assertTrue(DetectDelete.deleted)
271+
272+
# Clear via gi_frame.clear()
273+
g = generator(DetectDelete())
274+
g.gi_frame.clear()
275+
self.assertTrue(DetectDelete.deleted)
249276

250277
class ModifyUnderlyingIterableTest(unittest.TestCase):
251278
iterables = [
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Clear the frame of a generator when :meth:`generator.close` is called.

Objects/genobject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ gen_close(PyGenObject *gen, PyObject *args)
366366

367367
if (gen->gi_frame_state == FRAME_CREATED) {
368368
gen->gi_frame_state = FRAME_COMPLETED;
369+
gen_clear_frame(gen);
369370
Py_RETURN_NONE;
370371
}
371372
if (FRAME_STATE_FINISHED(gen->gi_frame_state)) {

0 commit comments

Comments
 (0)