Commit 1e784ef4 authored by Stefan Behnel's avatar Stefan Behnel

make sure Cython's generator and coroutine types are registered with the...

make sure Cython's generator and coroutine types are registered with the Generator/Coroutine ABCs also in Py3.5
patch both types also into asyncio (in Py<3.5)
parent 449da847
...@@ -1267,7 +1267,8 @@ static int __Pyx_patch_abc(void); /*proto*/ ...@@ -1267,7 +1267,8 @@ static int __Pyx_patch_abc(void); /*proto*/
//@requires: PatchModuleWithCoroutine //@requires: PatchModuleWithCoroutine
static int __Pyx_patch_abc(void) { static int __Pyx_patch_abc(void) {
#if (defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)) && (!defined(CYTHON_PATCH_ABC) || CYTHON_PATCH_ABC) #if (defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)) && \
(!defined(CYTHON_PATCH_ABC) || CYTHON_PATCH_ABC)
static int abc_patched = 0; static int abc_patched = 0;
if (!abc_patched) { if (!abc_patched) {
PyObject *module; PyObject *module;
...@@ -1281,35 +1282,10 @@ static int __Pyx_patch_abc(void) { ...@@ -1281,35 +1282,10 @@ static int __Pyx_patch_abc(void) {
return -1; return -1;
} }
} else { } else {
PyObject *abc; module = __Pyx_Coroutine_patch_module(
int needs_generator = 1, needs_coroutine = 1; module,
#ifdef __Pyx_Generator_USED
abc = PyObject_GetAttrString(module, "Generator");
if (abc) {
needs_generator = 0;
Py_DECREF(abc);
} else {
PyErr_Clear();
}
#else
needs_generator = 0;
#endif
#ifdef __Pyx_Coroutine_USED
abc = PyObject_GetAttrString(module, "Coroutine");
if (abc) {
needs_coroutine = 0;
Py_DECREF(abc);
} else {
PyErr_Clear();
}
#else
needs_coroutine = 0;
#endif
if (needs_coroutine || needs_generator) {
module = __Pyx_Coroutine_patch_module(
module,
#ifdef __Pyx_Generator_USED #ifdef __Pyx_Generator_USED
CSTRING("""\ CSTRING("""\
def mk_gen(): def mk_gen():
from abc import abstractmethod from abc import abstractmethod
...@@ -1364,29 +1340,31 @@ def mk_gen(): ...@@ -1364,29 +1340,31 @@ def mk_gen():
generator = type((lambda: (yield))()) generator = type((lambda: (yield))())
Generator.register(generator) Generator.register(generator)
Generator.register(_cython_generator_type)
return Generator return Generator
_module.Generator = mk_gen() try:
Generator = _module.Generator
except AttributeError:
Generator = _module.Generator = mk_gen()
Generator.register(_cython_generator_type)
""") """)
#endif #endif
#ifdef __Pyx_Coroutine_USED #ifdef __Pyx_Coroutine_USED
CSTRING("""\ CSTRING("""\
def mk_coroutine(): def mk_coroutine():
from abc import abstractmethod, ABCMeta from abc import abstractmethod, ABCMeta
""") """)
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
CSTRING("""\ CSTRING("""\
class Coroutine(metaclass=ABCMeta): class Coroutine(metaclass=ABCMeta):
""") """)
#else #else
CSTRING("""\ CSTRING("""\
class Coroutine(object): class Coroutine(object):
__metaclass__ = ABCMeta __metaclass__ = ABCMeta
""") """)
#endif #endif
CSTRING("""\ CSTRING("""\
__slots__ = () __slots__ = ()
@abstractmethod @abstractmethod
...@@ -1419,18 +1397,28 @@ def mk_coroutine(): ...@@ -1419,18 +1397,28 @@ def mk_coroutine():
else: else:
raise RuntimeError('coroutine ignored GeneratorExit') raise RuntimeError('coroutine ignored GeneratorExit')
return Coroutine
try:
Coroutine = _module.Coroutine
except AttributeError:
Coroutine = _module.Coroutine = mk_coroutine()
Coroutine.register(_cython_coroutine_type)
def mk_awaitable():
from abc import abstractmethod, ABCMeta
""") """)
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
CSTRING("""\ CSTRING("""\
class Awaitable(metaclass=ABCMeta): class Awaitable(metaclass=ABCMeta):
""") """)
#else #else
CSTRING("""\ CSTRING("""\
class Awaitable(object): class Awaitable(object):
__metaclass__ = ABCMeta __metaclass__ = ABCMeta
""") """)
#endif #endif
CSTRING("""\ CSTRING("""\
__slots__ = () __slots__ = ()
@abstractmethod @abstractmethod
...@@ -1447,23 +1435,21 @@ def mk_coroutine(): ...@@ -1447,23 +1435,21 @@ def mk_coroutine():
break break
return NotImplemented return NotImplemented
try: return Awaitable
_module.Awaitable
except AttributeError:
Awaitable.register(Coroutine)
_module.Awaitable = Awaitable
Coroutine.register(_cython_coroutine_type) try:
return Coroutine Awaitable = _module.Awaitable
except AttributeError:
Awaitable = _module.Awaitable = mk_awaitable()
Awaitable.register(Coroutine)
_module.Coroutine = mk_coroutine() Awaitable.register(_cython_coroutine_type)
""") """)
#endif #endif
); );
abc_patched = 1; abc_patched = 1;
if (unlikely(!module)) if (unlikely(!module))
return -1; return -1;
}
Py_DECREF(module); Py_DECREF(module);
} }
} }
...@@ -1481,11 +1467,14 @@ _module.Coroutine = mk_coroutine() ...@@ -1481,11 +1467,14 @@ _module.Coroutine = mk_coroutine()
static PyObject* __Pyx_patch_asyncio(PyObject* module); /*proto*/ static PyObject* __Pyx_patch_asyncio(PyObject* module); /*proto*/
//////////////////// PatchAsyncIO //////////////////// //////////////////// PatchAsyncIO ////////////////////
//@requires: ImportExport.c::Import
//@requires: PatchModuleWithCoroutine //@requires: PatchModuleWithCoroutine
//@requires: PatchInspect //@requires: PatchInspect
static PyObject* __Pyx_patch_asyncio(PyObject* module) { static PyObject* __Pyx_patch_asyncio(PyObject* module) {
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_ASYNCIO) || CYTHON_PATCH_ASYNCIO) #if PY_VERSION_HEX < 0x030500B1 && \
(defined(__Pyx_Coroutine_USED) || defined(__Pyx_Generator_USED)) && \
(!defined(CYTHON_PATCH_ASYNCIO) || CYTHON_PATCH_ASYNCIO)
PyObject *patch_module = NULL; PyObject *patch_module = NULL;
static int asyncio_patched = 0; static int asyncio_patched = 0;
if (unlikely((!asyncio_patched) && module)) { if (unlikely((!asyncio_patched) && module)) {
...@@ -1494,12 +1483,25 @@ static PyObject* __Pyx_patch_asyncio(PyObject* module) { ...@@ -1494,12 +1483,25 @@ static PyObject* __Pyx_patch_asyncio(PyObject* module) {
if (package) { if (package) {
patch_module = __Pyx_Coroutine_patch_module( patch_module = __Pyx_Coroutine_patch_module(
PyObject_GetAttrString(package, "coroutines"), CSTRING("""\ PyObject_GetAttrString(package, "coroutines"), CSTRING("""\
old_types = getattr(_module, '_COROUTINE_TYPES', None) coro_types = getattr(_module, '_COROUTINE_TYPES', None)
if old_types is not None and _cython_generator_type not in old_types: """)
_module._COROUTINE_TYPES = type(old_types) (tuple(old_types) + (_cython_generator_type,)) #ifdef __Pyx_Coroutine_USED
CSTRING("""\
if coro_types is not None and _cython_coroutine_type not in coro_types:
coro_types = type(coro_types) (tuple(coro_types) + (_cython_coroutine_type,))
""")
#endif
#ifdef __Pyx_Generator_USED
CSTRING("""\
if coro_types is not None and _cython_generator_type not in coro_types:
coro_types = type(coro_types) (tuple(coro_types) + (_cython_generator_type,))
""")
#endif
CSTRING("""
_module._COROUTINE_TYPES = coro_types
""") """)
); );
#if PY_VERSION_HEX < 0x03050000 #if PY_VERSION_HEX < 0x03050000
} else { } else {
// Py3.4 used to have asyncio.tasks instead of asyncio.coroutines // Py3.4 used to have asyncio.tasks instead of asyncio.coroutines
PyErr_Clear(); PyErr_Clear();
...@@ -1507,14 +1509,26 @@ if old_types is not None and _cython_generator_type not in old_types: ...@@ -1507,14 +1509,26 @@ if old_types is not None and _cython_generator_type not in old_types:
if (unlikely(!package)) goto asyncio_done; if (unlikely(!package)) goto asyncio_done;
patch_module = __Pyx_Coroutine_patch_module( patch_module = __Pyx_Coroutine_patch_module(
PyObject_GetAttrString(package, "tasks"), CSTRING("""\ PyObject_GetAttrString(package, "tasks"), CSTRING("""\
if (hasattr(_module, 'iscoroutine') and if hasattr(_module, 'iscoroutine'):
getattr(_module.iscoroutine, '_cython_generator_type', None) is not _cython_generator_type): old_coroutine_types = getattr(_module.iscoroutine, '_cython_coroutine_types', None)
def cy_wrap(orig_func, cython_generator_type=_cython_generator_type, type=type): if old_coroutine_types is None or not isinstance(old_coroutine_types, list):
def cy_iscoroutine(obj): return type(obj) is cython_generator_type or orig_func(obj) old_coroutine_types = []
cy_iscoroutine._cython_generator_type = cython_generator_type def cy_wrap(orig_func, type=type, cython_coroutine_types=old_coroutine_types):
return cy_iscoroutine def cy_iscoroutine(obj): return type(obj) in cython_coroutine_types or orig_func(obj)
_module.iscoroutine = cy_wrap(_module.iscoroutine) cy_iscoroutine._cython_coroutine_types = cython_coroutine_types
return cy_iscoroutine
_module.iscoroutine = cy_wrap(_module.iscoroutine)
""")
#ifdef __Pyx_Coroutine_USED
CSTRING("""\
if _cython_coroutine_type not in old_coroutine_types: old_coroutine_types.append(_cython_coroutine_type)
""") """)
#endif
#ifdef __Pyx_Generator_USED
CSTRING("""\
if _cython_generator_type not in old_coroutine_types: old_coroutine_types.append(_cython_generator_type)
""")
#endif
); );
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment