Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Commit d3e03c8

Browse files
committed
Fix formatting of coroutine-like objects (Cython coroutines etc)
1 parent 99ebe37 commit d3e03c8

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

asyncio/coroutines.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,25 @@ def iscoroutine(obj):
261261
def _format_coroutine(coro):
262262
assert iscoroutine(coro)
263263

264+
if not hasattr(coro, 'cr_code') and not hasattr(coro, 'gi_code'):
265+
# Most likely a Cython coroutine.
266+
coro_name = getattr(coro, '__qualname__', coro.__name__)
267+
coro_name = '{}()'.format(coro_name)
268+
269+
running = False
270+
try:
271+
running = coro.cr_running
272+
except AttributeError:
273+
try:
274+
running = coro.gi_running
275+
except AttributeError:
276+
pass
277+
278+
if running:
279+
return '{} running'.format(coro_name)
280+
else:
281+
return coro_name
282+
264283
coro_name = None
265284
if isinstance(coro, CoroWrapper):
266285
func = coro.func

tests/test_events.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import tty
2626

2727
import asyncio
28+
from asyncio import coroutines
2829
from asyncio import proactor_events
2930
from asyncio import selector_events
3031
from asyncio import sslproto
@@ -2380,6 +2381,36 @@ def check_source_traceback(h):
23802381
h = loop.call_later(0, noop)
23812382
check_source_traceback(h)
23822383

2384+
def test_coroutine_like_object_debug_formatting(self):
2385+
# Test that asyncio can format coroutines that are instances of
2386+
# collections.abc.Coroutine, but lack cr_core or gi_code attributes
2387+
# (such as ones compiled with Cython).
2388+
2389+
class Coro:
2390+
__name__ = 'AAA'
2391+
2392+
def send(self, v):
2393+
pass
2394+
2395+
def throw(self, *exc):
2396+
pass
2397+
2398+
def close(self):
2399+
pass
2400+
2401+
def __await__(self):
2402+
pass
2403+
2404+
coro = Coro()
2405+
self.assertTrue(asyncio.iscoroutine(coro))
2406+
self.assertEqual(coroutines._format_coroutine(coro), 'AAA()')
2407+
2408+
coro.__qualname__ = 'BBB'
2409+
self.assertEqual(coroutines._format_coroutine(coro), 'BBB()')
2410+
2411+
coro.cr_running = True
2412+
self.assertEqual(coroutines._format_coroutine(coro), 'BBB() running')
2413+
23832414

23842415
class TimerTests(unittest.TestCase):
23852416

0 commit comments

Comments
 (0)