Skip to content

Commit a924d31

Browse files
hyongtao-codemiss-islington
authored andcommitted
gh-143999: Fix: handle suspended state on types.coroutine wrappers (GH-144000)
(cherry picked from commit 76b484b) Co-authored-by: Yongtao Huang <yongtaoh2022@gmail.com>
1 parent 41f76ae commit a924d31

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

Lib/test/test_inspect/test_inspect.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,30 @@ def running_check_generator():
27572757
# Running after the first yield
27582758
next(self.generator)
27592759

2760+
def test_types_coroutine_wrapper_state(self):
2761+
def gen():
2762+
yield 1
2763+
yield 2
2764+
2765+
@types.coroutine
2766+
def wrapped_generator_coro():
2767+
# return a generator iterator so types.coroutine
2768+
# wraps it into types._GeneratorWrapper.
2769+
return gen()
2770+
2771+
g = wrapped_generator_coro()
2772+
self.addCleanup(g.close)
2773+
self.assertIs(type(g), types._GeneratorWrapper)
2774+
2775+
# _GeneratorWrapper must provide gi_suspended/cr_suspended
2776+
# so inspect.get*state() doesn't raise AttributeError.
2777+
self.assertEqual(inspect.getgeneratorstate(g), inspect.GEN_CREATED)
2778+
self.assertEqual(inspect.getcoroutinestate(g), inspect.CORO_CREATED)
2779+
2780+
next(g)
2781+
self.assertEqual(inspect.getgeneratorstate(g), inspect.GEN_SUSPENDED)
2782+
self.assertEqual(inspect.getcoroutinestate(g), inspect.CORO_SUSPENDED)
2783+
27602784
def test_easy_debugging(self):
27612785
# repr() and str() of a generator state should contain the state name
27622786
names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()

Lib/types.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,14 @@ def gi_running(self):
274274
@property
275275
def gi_yieldfrom(self):
276276
return self.__wrapped.gi_yieldfrom
277+
@property
278+
def gi_suspended(self):
279+
return self.__wrapped.gi_suspended
277280
cr_code = gi_code
278281
cr_frame = gi_frame
279282
cr_running = gi_running
280283
cr_await = gi_yieldfrom
284+
cr_suspended = gi_suspended
281285
def __next__(self):
282286
return next(self.__wrapped)
283287
def __iter__(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix an issue where :func:`inspect.getgeneratorstate` and :func:`inspect.getcoroutinestate` could fail for generators wrapped by :func:`types.coroutine` in the suspended state.

0 commit comments

Comments
 (0)