]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] GH-100964: Fix reference cycle in exhausted generator frames (GH-141112) ...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 17 Dec 2025 19:48:18 +0000 (20:48 +0100)
committerGitHub <noreply@github.com>
Wed, 17 Dec 2025 19:48:18 +0000 (19:48 +0000)
GH-100964: Fix reference cycle in exhausted generator frames (GH-141112)
(cherry picked from commit 92243dc62ce10715ab0d9074b23dea5a1bfa9dcc)

Co-authored-by: Savannah Ostrowski <savannah@python.org>
Lib/test/test_generators.py
Misc/NEWS.d/next/Core_and_Builtins/2025-11-06-05-21-25.gh-issue-100964.TxPf1b.rst [new file with mode: 0644]
Python/ceval.c

index b71c4d1c81951b818402f9cdadfb937fe7eb876e..97f14314459a3c7406865ecb7b50044f80a22ce7 100644 (file)
@@ -134,6 +134,18 @@ class FinalizationTest(unittest.TestCase):
         self.assertEqual(len(resurrected), 1)
         self.assertIsInstance(resurrected[0].gi_code, types.CodeType)
 
+    def test_exhausted_generator_frame_cycle(self):
+        def g():
+            yield
+
+        generator = g()
+        frame = generator.gi_frame
+        self.assertIsNone(frame.f_back)
+        next(generator)
+        self.assertIsNone(frame.f_back)
+        next(generator, None)
+        self.assertIsNone(frame.f_back)
+
 
 class GeneratorTest(unittest.TestCase):
 
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-06-05-21-25.gh-issue-100964.TxPf1b.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-06-05-21-25.gh-issue-100964.TxPf1b.rst
new file mode 100644 (file)
index 0000000..7c554cf
--- /dev/null
@@ -0,0 +1 @@
+Fix reference cycle in exhausted generator frames. Patch by Savannah Ostrowski.
index faca6fe81b977ad88766e70ceeef2ad48271a7f8..87cf01730b472e3c67420ac72ee2a42944e6e906 100644 (file)
@@ -1920,9 +1920,9 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
     tstate->exc_info = gen->gi_exc_state.previous_item;
     gen->gi_exc_state.previous_item = NULL;
     assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame);
+    frame->previous = NULL;
     _PyFrame_ClearExceptCode(frame);
     _PyErr_ClearExcState(&gen->gi_exc_state);
-    frame->previous = NULL;
 }
 
 void