diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 075e1802bebc3e..775b985a3cd1f9 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -2879,6 +2879,17 @@ def _coroutinestate(self): def test_created(self): self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED) + def test_generator_based_coroutine_introspection(self): + from inspect import getcoroutinestate + from types import coroutine + + @coroutine + def gen_coro(): + yield + + # Must not raise AttributeError + getcoroutinestate(gen_coro()) + def test_suspended(self): self.coroutine.send(None) self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED) @@ -2927,6 +2938,7 @@ async def func(a=None): {'a': None, 'gencoro': gencoro, 'b': 'spam'}) + @support.requires_working_socket() class TestGetAsyncGenState(unittest.IsolatedAsyncioTestCase): diff --git a/Objects/genobject.c b/Objects/genobject.c index 09407d60af62be..3b8d433c7c58d7 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -935,6 +935,36 @@ gen_getcode(PyObject *self, void *Py_UNUSED(ignored)) return _gen_getcode(gen, "gi_code"); } +static PyObject * +gen_get_cr_frame(PyObject *self, void *closure) +{ + return gen_getframe((PyObject *)self, closure); +} + +static PyObject * +gen_get_cr_code(PyObject *self, void *closure) +{ + return gen_getcode((PyObject *)self, closure); +} + +static PyObject * +gen_get_cr_running(PyObject *self, void *closure) +{ + return gen_getrunning((PyObject *)self, closure); +} + +static PyObject * +gen_get_cr_suspended(PyObject *self, void *closure) +{ + return gen_getsuspended((PyObject *)self, closure); +} + +static PyObject * +gen_get_cr_origin(PyObject *self, void *closure) +{ + Py_RETURN_NONE; +} + static PyGetSetDef gen_getsetlist[] = { {"__name__", gen_get_name, gen_set_name, PyDoc_STR("name of the generator")}, @@ -946,6 +976,11 @@ static PyGetSetDef gen_getsetlist[] = { {"gi_frame", gen_getframe, NULL, NULL}, {"gi_suspended", gen_getsuspended, NULL, NULL}, {"gi_code", gen_getcode, NULL, NULL}, + {"cr_running", gen_get_cr_running, NULL, NULL}, + {"cr_frame", gen_get_cr_frame, NULL, NULL}, + {"cr_code", gen_get_cr_code, NULL, NULL}, + {"cr_suspended", gen_get_cr_suspended, NULL, NULL}, + {"cr_origin", gen_get_cr_origin, NULL, NULL}, {NULL} /* Sentinel */ };