8000 GH-133372: C implementation of types._GeneratorWrapper is added. by efimov-mikhail · Pull Request #133373 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

GH-133372: C implementation of types._GeneratorWrapper is added. #133373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Include/internal/pycore_genobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ PyAPI_FUNC(PyObject *)_PyCoro_GetAwaitableIter(PyObject *o);
extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *);

extern PyTypeObject _PyCoroWrapper_Type;
extern PyTypeObject _PyGenWrapper_Type;
extern PyTypeObject _PyAsyncGenWrappedValue_Type;
extern PyTypeObject _PyAsyncGenAThrow_Type;

Expand Down
5 changes: 5 additions & 0 deletions Include/internal/pycore_global_objects_fini_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Include/internal/pycore_global_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,11 @@ struct _Py_global_strings {
STRUCT_FOR_ID(get_source)
STRUCT_FOR_ID(getattr)
STRUCT_FOR_ID(getstate)
STRUCT_FOR_ID(gi_code)
STRUCT_FOR_ID(gi_frame)
STRUCT_FOR_ID(gi_running)
STRUCT_FOR_ID(gi_suspended)
STRUCT_FOR_ID(gi_yieldfrom)
STRUCT_FOR_ID(gid)
STRUCT_FOR_ID(globals)
STRUCT_FOR_ID(groupindex)
Expand Down
5 changes: 5 additions & 0 deletions Include/internal/pycore_runtime_init_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions Include/internal/pycore_unicodeobject_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2241,21 +2241,26 @@ def foo(): return gen
self.assertIs(wrapper.__name__, gen.__name__)

# Test AttributeErrors
for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
for name in (
'gi_running', 'gi_suspended', 'gi_frame', 'gi_code', 'gi_yieldfrom',
'cr_running', 'cr_suspended', 'cr_frame', 'cr_code', 'cr_await'
):
with self.assertRaises(AttributeError):
getattr(wrapper, name)

# Test attributes pass-through
gen.gi_running = object()
gen.gi_suspended = object()
gen.gi_frame = object()
gen.gi_code = object()
gen.gi_yieldfrom = object()
self.assertIs(wrapper.gi_running, gen.gi_running)
self.assertIs(wrapper.gi_suspended, gen.gi_suspended)
self.assertIs(wrapper.gi_frame, gen.gi_frame)
self.assertIs(wrapper.gi_code, gen.gi_code)
self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
self.assertIs(wrapper.cr_running, gen.gi_running)
self.assertIs(wrapper.cr_suspended, gen.gi_suspended)
self.assertIs(wrapper.cr_frame, gen.gi_frame)
self.assertIs(wrapper.cr_code, gen.gi_code)
self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
Expand Down
13 changes: 11 additions & 2 deletions Lib/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def _g():
async def _c(): pass
_c = _c()
CoroutineType = type(_c)
_c.close() # Prevent ResourceWarning
_c.close() # Prevent RuntimeWarning

async def _ag():
yield
Expand Down Expand Up @@ -250,7 +250,6 @@ def deleter(self, fdel):


class _GeneratorWrapper:
# TODO: Implement this in C.
def __init__(self, gen):
self.__wrapped = gen
self.__isgen = gen.__class__ is GeneratorType
Expand All @@ -272,11 +271,15 @@ def gi_frame(self):
def gi_running(self):
return self.__wrapped.gi_running
@property
def gi_suspended(self):
return self.__wrapped.gi_suspended
@property
def gi_yieldfrom(self):
return self.__wrapped.gi_yieldfrom
cr_code = gi_code
cr_frame = gi_frame
cr_running = gi_running
cr_suspended = gi_suspended
cr_await = gi_yieldfrom
def __next__(self):
return next(self.__wrapped)
Expand All @@ -286,6 +289,12 @@ def __iter__(self):
return self
__await__ = __iter__

try:
from _types import _GeneratorWrapper
except ImportError:
# Leave the pure Python version in place.
pass

def coroutine(func):
"""Convert regular generator function to a coroutine."""

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a C implementation of :class:`~types._GeneratorWrapper`.
2 changes: 2 additions & 0 deletions Modules/_typesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "pycore_namespace.h" // _PyNamespace_Type
#include "pycore_object.h" // _PyNone_Type, _PyNotImplemented_Type
#include "pycore_unionobject.h" // _PyUnion_Type
#include "pycore_genobject.h" // _PyGenWrapper_Type

static int
_types_exec(PyObject *m)
Expand Down Expand Up @@ -46,6 +47,7 @@ _types_exec(PyObject *m)
EXPORT_STATIC_TYPE("TracebackType", PyTraceBack_Type);
EXPORT_STATIC_TYPE("UnionType", _PyUnion_Type);
EXPORT_STATIC_TYPE("WrapperDescriptorType", PyWrapperDescr_Type);
EXPORT_STATIC_TYPE("_GeneratorWrapper", _PyGenWrapper_Type);
#undef EXPORT_STATIC_TYPE
return 0;
}
Expand Down
Loading
Loading
0