Skip to content

Commit

Permalink
pythongh-111058: Change coro.cr_frame to be None for a closed coroutine
Browse files Browse the repository at this point in the history
  • Loading branch information
iritkatriel committed Nov 26, 2023
1 parent fb202af commit 3dbe4c8
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Lib/test/test_coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -2216,6 +2216,14 @@ async def f():
gen.cr_frame.clear()
gen.close()

def test_cr_frame_after_close(self):
async def f():
pass
gen = f()
self.assertIsNotNone(gen.cr_frame)
gen.close()
self.assertIsNone(gen.cr_frame)

def test_stack_in_coroutine_throw(self):
# Regression test for https://github.com/python/cpython/issues/93592
async def a():
Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2493,6 +2493,10 @@ def test_closed_after_immediate_exception(self):
self.coroutine.throw(RuntimeError)
self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)

def test_closed_after_close(self):
self.coroutine.close()
self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)

def test_easy_debugging(self):
# repr() and str() of a coroutine state should contain the state name
names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Change coro.cr_frame to return ``None`` after the coroutine has been closed.
This fixes a bug where :func:`~inspect.getcoroutinestate` returns the wrong
state for a closed coroutine.
2 changes: 1 addition & 1 deletion Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ _gen_getframe(PyGenObject *gen, const char *const name)
if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) {
return NULL;
}
if (gen->gi_frame_state == FRAME_CLEARED) {
if (FRAME_STATE_FINISHED(gen->gi_frame_state)) {
Py_RETURN_NONE;
}
return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe));
Expand Down

0 comments on commit 3dbe4c8

Please sign in to comment.