Author: Ronan Lamy <[email protected]>
Branch: py3.5
Changeset: r92453:ce24631719e2
Date: 2017-09-24 19:27 +0100
http://bitbucket.org/pypy/pypy/changeset/ce24631719e2/
Log: Implement PyGenObject so that C code can recognize @types.coroutine
old-style generator-coroutines
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -12,7 +12,8 @@
from pypy.interpreter.gateway import unwrap_spec
from pypy.interpreter.astcompiler.consts import (
CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
- CO_GENERATOR, CO_COROUTINE, CO_KILL_DOCSTRING, CO_YIELD_INSIDE_TRY)
+ CO_GENERATOR, CO_COROUTINE, CO_KILL_DOCSTRING, CO_YIELD_INSIDE_TRY,
+ CO_ITERABLE_COROUTINE)
from pypy.tool import dis3
from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT
from rpython.rlib.rarithmetic import intmask
diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py
--- a/pypy/module/cpyext/funcobject.py
+++ b/pypy/module/cpyext/funcobject.py
@@ -18,6 +18,8 @@
CO_VARKEYWORDS = 0x0008,
CO_NESTED = 0x0010,
CO_GENERATOR = 0x0020,
+ CO_COROUTINE=0x0080,
+ CO_ITERABLE_COROUTINE=0x0100,
)
ALL_CODE_FLAGS = unrolling_iterable(CODE_FLAGS.items())
diff --git a/pypy/module/cpyext/genobject.py b/pypy/module/cpyext/genobject.py
--- a/pypy/module/cpyext/genobject.py
+++ b/pypy/module/cpyext/genobject.py
@@ -1,7 +1,29 @@
from pypy.interpreter.generator import GeneratorIterator, Coroutine
-from pypy.module.cpyext.api import build_type_checkers
+from pypy.module.cpyext.api import (
+ build_type_checkers, cts, parse_dir, bootstrap_function)
+from pypy.module.cpyext.pyobject import make_typedescr, as_pyobj
+from pypy.module.cpyext.object import _dealloc
+
+cts.parse_header(parse_dir / 'cpyext_genobject.h')
+
+@bootstrap_function
+def init_genobject(space):
+ make_typedescr(GeneratorIterator.typedef,
+ basestruct=cts.gettype('PyGenObject'),
+ attach=gi_attach,
+ dealloc=_dealloc)
PyGen_Check, PyGen_CheckExact = build_type_checkers("Gen", GeneratorIterator)
_, PyCoro_CheckExact = build_type_checkers("Coro", Coroutine)
+
+def gi_attach(space, py_obj, w_obj, w_userdata=None):
+ py_obj.c_gi_code = as_pyobj(space, w_obj.pycode)
+
+def gi_realize(space, py_obj):
+ raise NotImplementedError(
+ "PyPy doesn't support creation of generators from the C-API.")
+
+def gi_dealloc(space, py_obj):
+ _dealloc(space, py_obj)
diff --git a/pypy/module/cpyext/include/code.h
b/pypy/module/cpyext/include/code.h
--- a/pypy/module/cpyext/include/code.h
+++ b/pypy/module/cpyext/include/code.h
@@ -20,6 +20,11 @@
#define CO_VARKEYWORDS 0x0008
#define CO_NESTED 0x0010
#define CO_GENERATOR 0x0020
+
+/* The CO_COROUTINE flag is set for coroutine functions (defined with
+ ``async def`` keywords) */
+#define CO_COROUTINE 0x0080
+#define CO_ITERABLE_COROUTINE 0x0100
#define CO_FUTURE_DIVISION 0x02000
#define CO_FUTURE_ABSOLUTE_IMPORT 0x04000
diff --git a/pypy/module/cpyext/test/test_genobject.py
b/pypy/module/cpyext/test/test_genobject.py
--- a/pypy/module/cpyext/test/test_genobject.py
+++ b/pypy/module/cpyext/test/test_genobject.py
@@ -28,7 +28,28 @@
assert PyCoro_CheckExact(space, w_coroutine)
class AppTestCoroutine(AppTestCpythonExtensionBase):
- def test_simple(self):
+ def test_generator_coroutine(self):
+ module = self.import_extension('test_gen', [
+ ('is_coroutine', 'METH_O',
+ '''
+ if (!PyGen_CheckExact(args))
+ Py_RETURN_NONE;
+ PyObject* co = ((PyGenObject*)args)->gi_code;
+ if (((PyCodeObject*)co)->co_flags & CO_ITERABLE_COROUTINE)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ ''')])
+ def it():
+ yield 42
+
+ print(module.is_coroutine(it()))
+ assert module.is_coroutine(it()) is False
+ from types import coroutine
+ assert module.is_coroutine(coroutine(it)()) is True
+
+
+ def test_await(self):
"""
module = self.import_extension('test_coroutine', [
('await_', 'METH_O',
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit