Skip to content

Commit 7954ec4

Browse files
GH-133372: C implementation of types._GeneratorWrapper is added.
1 parent ac7d5ba commit 7954ec4

File tree

10 files changed

+362
-5
lines changed

10 files changed

+362
-5
lines changed

Include/internal/pycore_genobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ PyAPI_FUNC(PyObject *)_PyCoro_GetAwaitableIter(PyObject *o);
3434
extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *);
3535

3636
extern PyTypeObject _PyCoroWrapper_Type;
37+
extern PyTypeObject _PyGenWrapper_Type;
3738
extern PyTypeObject _PyAsyncGenWrappedValue_Type;
3839
extern PyTypeObject _PyAsyncGenAThrow_Type;
3940

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,11 @@ struct _Py_global_strings {
479479
STRUCT_FOR_ID(get_source)
480480
STRUCT_FOR_ID(getattr)
481481
STRUCT_FOR_ID(getstate)
482+
STRUCT_FOR_ID(gi_code)
483+
STRUCT_FOR_ID(gi_frame)
484+
STRUCT_FOR_ID(gi_running)
485+
STRUCT_FOR_ID(gi_suspended)
486+
STRUCT_FOR_ID(gi_yieldfrom)
482487
STRUCT_FOR_ID(gid)
483488
STRUCT_FOR_ID(globals)
484489
STRUCT_FOR_ID(groupindex)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_types.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,21 +2241,26 @@ def foo(): return gen
22412241
self.assertIs(wrapper.__name__, gen.__name__)
22422242

22432243
# Test AttributeErrors
2244-
for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
2245-
'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
2244+
for name in (
2245+
'gi_running', 'gi_suspended', 'gi_frame', 'gi_code', 'gi_yieldfrom',
2246+
'cr_running', 'cr_suspended', 'cr_frame', 'cr_code', 'cr_await'
2247+
):
22462248
with self.assertRaises(AttributeError):
22472249
getattr(wrapper, name)
22482250

22492251
# Test attributes pass-through
22502252
gen.gi_running = object()
2253+
gen.gi_suspended = object()
22512254
gen.gi_frame = object()
22522255
gen.gi_code = object()
22532256
gen.gi_yieldfrom = object()
22542257
self.assertIs(wrapper.gi_running, gen.gi_running)
2258+
self.assertIs(wrapper.gi_suspended, gen.gi_suspended)
22552259
self.assertIs(wrapper.gi_frame, gen.gi_frame)
22562260
self.assertIs(wrapper.gi_code, gen.gi_code)
22572261
self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
22582262
self.assertIs(wrapper.cr_running, gen.gi_running)
2263+
self.assertIs(wrapper.cr_suspended, gen.gi_suspended)
22592264
self.assertIs(wrapper.cr_frame, gen.gi_frame)
22602265
self.assertIs(wrapper.cr_code, gen.gi_code)
22612266
self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)

Lib/types.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def _g():
3333
async def _c(): pass
3434
_c = _c()
3535
CoroutineType = type(_c)
36-
_c.close() # Prevent ResourceWarning
36+
_c.close() # Prevent RuntimeWarning
3737

3838
async def _ag():
3939
yield
@@ -250,7 +250,6 @@ def deleter(self, fdel):
250250

251251

252252
class _GeneratorWrapper:
253-
# TODO: Implement this in C.
254253
def __init__(self, gen):
255254
self.__wrapped = gen
256255
self.__isgen = gen.__class__ is GeneratorType
@@ -272,11 +271,15 @@ def gi_frame(self):
272271
def gi_running(self):
273272
return self.__wrapped.gi_running
274273
@property
274+
def gi_suspended(self):
275+
return self.__wrapped.gi_suspended
276+
@property
275277
def gi_yieldfrom(self):
276278
return self.__wrapped.gi_yieldfrom
277279
cr_code = gi_code
278280
cr_frame = gi_frame
279281
cr_running = gi_running
282+
cr_suspended = gi_suspended
280283
cr_await = gi_yieldfrom
281284
def __next__(self):
282285
return next(self.__wrapped)
@@ -286,6 +289,12 @@ def __iter__(self):
286289
return self
287290
__await__ = __iter__
288291

292+
try:
293+
from _types import _GeneratorWrapper
294+
except ImportError:
295+
# Leave the pure Python version in place.
296+
pass
297+
289298
def coroutine(func):
290299
"""Convert regular generator function to a coroutine."""
291300

Modules/_typesmodule.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "pycore_namespace.h" // _PyNamespace_Type
66
#include "pycore_object.h" // _PyNone_Type, _PyNotImplemented_Type
77
#include "pycore_unionobject.h" // _PyUnion_Type
8+
#include "pycore_genobject.h" // _PyGenWrapper_Type
89

910
static int
1011
_types_exec(PyObject *m)
@@ -46,6 +47,7 @@ _types_exec(PyObject *m)
4647
EXPORT_STATIC_TYPE("TracebackType", PyTraceBack_Type);
4748
EXPORT_STATIC_TYPE("UnionType", _PyUnion_Type);
4849
EXPORT_STATIC_TYPE("WrapperDescriptorType", PyWrapperDescr_Type);
50+
EXPORT_STATIC_TYPE("_GeneratorWrapper", _PyGenWrapper_Type);
4951
#undef EXPORT_STATIC_TYPE
5052
return 0;
5153
}

0 commit comments

Comments
 (0)