File tree
Lib/test
Misc/NEWS.d/next/Core_and_Builtins
Objects
Original file line numberDiff line numberDiff line change@@ -290,6 +290,33 @@ def __iter__(self):
290290291291self.assertEqual([1,2], list(iforiinC()))
292292293+deftest_close_clears_frame(self):
294+# gh-142766: Test that closing a generator clears its frame
295+classDetectDelete:
296+def__init__(self):
297+DetectDelete.deleted=False
298+299+def__del__(self):
300+DetectDelete.deleted=True
301+302+defgenerator(arg):
303+yield
304+305+# Test a freshly created generator (not suspended)
306+g=generator(DetectDelete())
307+g.close()
308+self.assertTrue(DetectDelete.deleted)
309+310+# Test a suspended generator
311+g=generator(DetectDelete())
312+next(g)
313+g.close()
314+self.assertTrue(DetectDelete.deleted)
315+316+# Clear via gi_frame.clear()
317+g=generator(DetectDelete())
318+g.gi_frame.clear()
319+self.assertTrue(DetectDelete.deleted)
293320294321classModifyUnderlyingIterableTest(unittest.TestCase):
295322iterables= [
Original file line numberDiff line numberDiff line change@@ -0,0 +1 @@
1+Clear the frame of a generator when :meth:`generator.close` is called.
Original file line numberDiff line numberDiff line change@@ -390,6 +390,7 @@ gen_close(PyObject *self, PyObject *args)
390390391391if (gen->gi_frame_state==FRAME_CREATED) {
392392gen->gi_frame_state=FRAME_COMPLETED;
393+gen_clear_frame(gen);
393394Py_RETURN_NONE;
394395 }
395396if (FRAME_STATE_FINISHED(gen->gi_frame_state)) {