Skip to content

Commit 98bdb55

Browse files
committed
Upgrade to Cython 0.28.2
Use new @cython.iterable_coroutine instead of patching the generated C code. Fixes issue #122.
1 parent 6128b96 commit 98bdb55

File tree

5 files changed

+23
-73
lines changed

5 files changed

+23
-73
lines changed

requirements.dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Cython==0.27.3
1+
Cython==0.28.2
22
Sphinx>=1.4.1

setup.py

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -139,80 +139,10 @@ def finalize_options(self):
139139
compiler_directives=directives,
140140
annotate=self.cython_annotate)
141141

142-
for cfile, timestamp in cfiles.items():
143-
if os.path.getmtime(cfile) != timestamp:
144-
# The file was recompiled, patch
145-
self._patch_cfile(cfile)
146-
147142
super().finalize_options()
148143

149144
self._initialized = True
150145

151-
def _patch_cfile(self, cfile):
152-
# Patch Cython 'async def' coroutines to have a 'tp_iter'
153-
# slot, which makes them compatible with 'yield from' without
154-
# the `asyncio.coroutine` decorator.
155-
156-
with open(cfile, 'rt') as f:
157-
src = f.read()
158-
159-
src = re.sub(
160-
r'''
161-
\s* offsetof\(__pyx_CoroutineObject,\s*gi_weakreflist\),
162-
\s* 0,
163-
\s* 0,
164-
\s* __pyx_Coroutine_methods,
165-
\s* __pyx_Coroutine_memberlist,
166-
\s* __pyx_Coroutine_getsets,
167-
''',
168-
169-
r'''
170-
offsetof(__pyx_CoroutineObject, gi_weakreflist),
171-
__Pyx_Coroutine_await, /* tp_iter */
172-
(iternextfunc) __Pyx_Generator_Next, /* tp_iternext */
173-
__pyx_Coroutine_methods,
174-
__pyx_Coroutine_memberlist,
175-
__pyx_Coroutine_getsets,
176-
''',
177-
178-
src, flags=re.X)
179-
180-
# Fix a segfault in Cython.
181-
src = re.sub(
182-
r'''
183-
\s* __Pyx_Coroutine_get_qualname\(__pyx_CoroutineObject\s+\*self\)
184-
\s* {
185-
\s* Py_INCREF\(self->gi_qualname\);
186-
''',
187-
188-
r'''
189-
__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self)
190-
{
191-
if (self->gi_qualname == NULL) { return __pyx_empty_unicode; }
192-
Py_INCREF(self->gi_qualname);
193-
''',
194-
195-
src, flags=re.X)
196-
197-
src = re.sub(
198-
r'''
199-
\s* __Pyx_Coroutine_get_name\(__pyx_CoroutineObject\s+\*self\)
200-
\s* {
201-
\s* Py_INCREF\(self->gi_name\);
202-
''',
203-
204-
r'''
205-
__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self)
206-
{
207-
if (self->gi_name == NULL) { return __pyx_empty_unicode; }
208-
Py_INCREF(self->gi_name);
209-
''',
210-
211-
src, flags=re.X)
212-
213-
with open(cfile, 'wt') as f:
214-
f.write(src)
215-
216146
def build_libuv(self):
217147
env = _libuv_build_env()
218148

tests/test_cython.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def test_cython_coro_is_coroutine(self):
1111

1212
coro = _test_coroutine_1()
1313

14-
self.assertEqual(_format_coroutine(coro), '_test_coroutine_1()')
14+
self.assertTrue(
15+
_format_coroutine(coro).startswith('_test_coroutine_1() done'))
1516
self.assertEqual(_test_coroutine_1.__qualname__, '_test_coroutine_1')
1617
self.assertEqual(_test_coroutine_1.__name__, '_test_coroutine_1')
1718
self.assertTrue(asyncio.iscoroutine(coro))
@@ -23,5 +24,9 @@ def test_cython_coro_is_coroutine(self):
2324
with self.assertRaises(asyncio.CancelledError):
2425
self.loop.run_until_complete(fut)
2526

26-
_format_coroutine(coro) # This line checks against Cython segfault
27+
try:
28+
_format_coroutine(coro) # This line checks against Cython segfault
29+
except TypeError:
30+
# TODO: Fix Cython to not reset __name__/__qualname__ to None
31+
pass
2732
coro.close()

uvloop/loop.pyx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,7 @@ cdef class Loop:
13751375

13761376
return self._getaddrinfo(host, port, family, type, proto, flags, 1)
13771377

1378+
@cython.iterable_coroutine
13781379
async def getnameinfo(self, sockaddr, int flags=0):
13791380
cdef:
13801381
AddrInfo ai_cnt
@@ -1432,6 +1433,7 @@ cdef class Loop:
14321433

14331434
return await self._getnameinfo(ai.ai_addr, flags)
14341435

1436+
@cython.iterable_coroutine
14351437
async def create_server(self, protocol_factory, host=None, port=None,
14361438
*,
14371439
int family=uv.AF_UNSPEC,
@@ -1563,6 +1565,7 @@ cdef class Loop:
15631565
server._ref()
15641566
return server
15651567

1568+
@cython.iterable_coroutine
15661569
async def create_connection(self, protocol_factory, host=None, port=None, *,
15671570
ssl=None, family=0, proto=0, flags=0, sock=None,
15681571
local_addr=None, server_hostname=None):
@@ -1771,6 +1774,7 @@ cdef class Loop:
17711774
else:
17721775
return tr, protocol
17731776

1777+
@cython.iterable_coroutine
17741778
async def create_unix_server(self, protocol_factory, path=None,
17751779
*, backlog=100, sock=None, ssl=None):
17761780
"""A coroutine which creates a UNIX Domain Socket server.
@@ -1882,6 +1886,7 @@ cdef class Loop:
18821886
server._add_server(pipe)
18831887
return server
18841888

1889+
@cython.iterable_coroutine
18851890
async def create_unix_connection(self, protocol_factory, path=None, *,
18861891
ssl=None, sock=None,
18871892
server_hostname=None):
@@ -2148,6 +2153,7 @@ cdef class Loop:
21482153
self._add_reader(sock, handle)
21492154
return fut
21502155

2156+
@cython.iterable_coroutine
21512157
async def sock_sendall(self, sock, data):
21522158
"""Send data to the socket.
21532159
@@ -2227,6 +2233,7 @@ cdef class Loop:
22272233
self._add_reader(sock, handle)
22282234
return fut
22292235

2236+
@cython.iterable_coroutine
22302237
async def sock_connect(self, sock, address):
22312238
"""Connect to a remote socket at address.
22322239
@@ -2247,6 +2254,7 @@ cdef class Loop:
22472254
finally:
22482255
socket_dec_io_ref(sock)
22492256

2257+
@cython.iterable_coroutine
22502258
async def connect_accepted_socket(self, protocol_factory, sock, *,
22512259
ssl=None):
22522260
"""Handle an accepted connection.
@@ -2320,6 +2328,7 @@ cdef class Loop:
23202328
def set_default_executor(self, executor):
23212329
self._default_executor = executor
23222330

2331+
@cython.iterable_coroutine
23232332
async def __subprocess_run(self, protocol_factory, args,
23242333
stdin=subprocess_PIPE,
23252334
stdout=subprocess_PIPE,
@@ -2406,6 +2415,7 @@ cdef class Loop:
24062415
return self.__subprocess_run(protocol_factory, args, shell=False,
24072416
**kwargs)
24082417

2418+
@cython.iterable_coroutine
24092419
async def connect_read_pipe(self, proto_factory, pipe):
24102420
"""Register read pipe in event loop. Set the pipe to non-blocking mode.
24112421
@@ -2430,6 +2440,7 @@ cdef class Loop:
24302440
transp._attach_fileobj(pipe)
24312441
return transp, proto
24322442

2443+
@cython.iterable_coroutine
24332444
async def connect_write_pipe(self, proto_factory, pipe):
24342445
"""Register write pipe in event loop.
24352446
@@ -2541,6 +2552,7 @@ cdef class Loop:
25412552

25422553
return True
25432554

2555+
@cython.iterable_coroutine
25442556
async def create_datagram_endpoint(self, protocol_factory,
25452557
local_addr=None, remote_addr=None, *,
25462558
family=0, proto=0, flags=0,
@@ -2701,6 +2713,7 @@ cdef class Loop:
27012713

27022714
self._asyncgens.add(agen)
27032715

2716+
@cython.iterable_coroutine
27042717
async def shutdown_asyncgens(self):
27052718
"""Shutdown all active asynchronous generators."""
27062719
self._asyncgens_shutdown_called = True
@@ -2831,5 +2844,6 @@ def _sighandler_noop(signum, frame):
28312844

28322845
########### Stuff for tests:
28332846

2847+
@cython.iterable_coroutine
28342848
async def _test_coroutine_1():
28352849
return 42

uvloop/server.pyx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ cdef class Server:
3939
def __repr__(self):
4040
return '<%s sockets=%r>' % (self.__class__.__name__, self.sockets)
4141

42+
@cython.iterable_coroutine
4243
async def wait_closed(self):
4344
if self._servers is None or self._waiters is None:
4445
return

0 commit comments

Comments
 (0)