Skip to content

Commit bf5a967

Browse files
Move frame->previous=NULL
1 parent f0ab07f commit bf5a967

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

Lib/test/test_generators.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,20 @@ def gen():
134134
self.assertEqual(len(resurrected), 1)
135135
self.assertIsInstance(resurrected[0].gi_code, types.CodeType)
136136

137+
def test_exhausted_generator_frame_cycle(self):
138+
# gh-100964: Ensure that exhausted generator frames don't create
139+
# reference cycles through f_back when the frame is accessed.
140+
def g():
141+
yield
142+
143+
generator = g()
144+
frame = generator.gi_frame
145+
self.assertIsNone(frame.f_back)
146+
next(generator)
147+
self.assertIsNone(frame.f_back)
148+
next(generator, None)
149+
self.assertIsNone(frame.f_back)
150+
137151

138152
class GeneratorTest(unittest.TestCase):
139153

Python/ceval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1842,9 +1842,9 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
18421842
tstate->exc_info = gen->gi_exc_state.previous_item;
18431843
gen->gi_exc_state.previous_item = NULL;
18441844
assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame);
1845+
frame->previous = NULL;
18451846
_PyFrame_ClearExceptCode(frame);
18461847
_PyErr_ClearExcState(&gen->gi_exc_state);
1847-
frame->previous = NULL;
18481848
}
18491849

18501850
void

0 commit comments

Comments
 (0)