Fix another Cython bug; patch asyncio to work with Cython coroutines

This commit is contained in:
Yury Selivanov 2016-05-14 19:30:48 -04:00
parent e2cf01841b
commit 85a460566c
4 changed files with 44 additions and 0 deletions

View File

@ -101,6 +101,22 @@ src = re.sub(
src, flags=re.X)
src = re.sub(
r'''
\s* __Pyx_Coroutine_get_name\(__pyx_CoroutineObject\s+\*self\)
\s* {
\s* Py_INCREF\(self->gi_name\);
''',
r'''
__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self)
{
if (self->gi_name == NULL) { return __pyx_empty_unicode; }
Py_INCREF(self->gi_name);
''',
src, flags=re.X)
with open('uvloop/loop.c', 'wt') as f:
f.write(src)
endef

View File

@ -398,7 +398,13 @@ class _TestBase:
class TestBaseUV(_TestBase, UVTestCase):
def test_cython_coro_is_coroutine(self):
from asyncio.coroutines import _format_coroutine
coro = self.loop.create_server(object)
self.assertEqual(_format_coroutine(coro),
'Loop.create_server()')
self.assertEqual(self.loop.create_server.__qualname__,
'Loop.create_server')
self.assertEqual(self.loop.create_server.__name__,
@ -411,6 +417,8 @@ class TestBaseUV(_TestBase, UVTestCase):
self.loop.run_until_complete(fut)
except asyncio.CancelledError:
pass
_format_coroutine(coro) # This line checks against Cython segfault
coro.close()

View File

@ -3,6 +3,7 @@ import asyncio
from asyncio.events import BaseDefaultEventLoopPolicy as __BasePolicy
from . import includes as __includes
from . import _patch
from .loop import Loop as __BaseLoop

19
uvloop/_patch.py Normal file
View File

@ -0,0 +1,19 @@
import asyncio
from asyncio import coroutines
def _format_coroutine(coro):
if asyncio.iscoroutine(coro) and not hasattr(coro, 'cr_code'):
# Most likely a Cython coroutine
coro_name = '{}()'.format(coro.__qualname__ or coro.__name__)
if coro.cr_running:
return '{} running'.format(coro_name)
else:
return coro_name
return _old_format_coroutine(coro)
_old_format_coroutine = coroutines._format_coroutine
coroutines._format_coroutine = _format_coroutine