Skip to content

Commit 3d921c4

Browse files
committed
pythongh-111058: Change coro.cr_frame to be None for a closed coroutine
1 parent 8e15f08 commit 3d921c4

4 files changed

Lines changed: 16 additions & 1 deletion

File tree

‎Lib/test/test_coroutines.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,14 @@ async def f():
22162216
gen.cr_frame.clear()
22172217
gen.close()
22182218

2219+
def test_cr_frame_after_close(self):
2220+
async def f():
2221+
pass
2222+
gen = f()
2223+
self.assertIsNotNone(gen.cr_frame)
2224+
gen.close()
2225+
self.assertIsNone(gen.cr_frame)
2226+
22192227
def test_stack_in_coroutine_throw(self):
22202228
# Regression test for https://github.com/python/cpython/issues/93592
22212229
async def a():

‎Lib/test/test_inspect/test_inspect.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,6 +2493,10 @@ def test_closed_after_immediate_exception(self):
24932493
self.coroutine.throw(RuntimeError)
24942494
self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
24952495

2496+
def test_closed_after_close(self):
2497+
self.coroutine.close()
2498+
self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2499+
24962500
def test_easy_debugging(self):
24972501
# repr() and str() of a coroutine state should contain the state name
24982502
names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Change coro.cr_frame to return ``None`` after the coroutine has been closed.
2+
This fixes a bug where :func:`~inspect.getcoroutinestate` returns the wrong
3+
state for a closed coroutine.

‎Objects/genobject.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ _gen_getframe(PyGenObject *gen, const char *const name)
732732
if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) {
733733
return NULL;
734734
}
735-
if (gen->gi_frame_state == FRAME_CLEARED) {
735+
if (FRAME_STATE_FINISHED(gen->gi_frame_state)) {
736736
Py_RETURN_NONE;
737737
}
738738
return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe));

0 commit comments

Comments
 (0)