]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #28372: Fix asyncio to support formatting of non-python coroutines
authorYury Selivanov <yury@magic.io>
Wed, 5 Oct 2016 23:32:49 +0000 (19:32 -0400)
committerYury Selivanov <yury@magic.io>
Wed, 5 Oct 2016 23:32:49 +0000 (19:32 -0400)
Lib/asyncio/coroutines.py
Lib/test/test_asyncio/test_events.py
Misc/NEWS

index 5cecc762df97995d8de9a9467480eb2a903c030c..1db7030205dc26d3c8e0f90848c35140da4ea42f 100644 (file)
@@ -261,6 +261,25 @@ def iscoroutine(obj):
 def _format_coroutine(coro):
     assert iscoroutine(coro)
 
+    if not hasattr(coro, 'cr_code') and not hasattr(coro, 'gi_code'):
+        # Most likely a Cython coroutine.
+        coro_name = getattr(coro, '__qualname__', coro.__name__)
+        coro_name = '{}()'.format(coro_name)
+
+        running = False
+        try:
+            running = coro.cr_running
+        except AttributeError:
+            try:
+                running = coro.gi_running
+            except AttributeError:
+                pass
+
+        if running:
+            return '{} running'.format(coro_name)
+        else:
+            return coro_name
+
     coro_name = None
     if isinstance(coro, CoroWrapper):
         func = coro.func
index b3f35ceba6429d149b4ce1a91a625669606ead34..7df926f191dd29d36d08ed51db55c158c8ee0aca 100644 (file)
@@ -1,5 +1,6 @@
 """Tests for events.py."""
 
+import collections.abc
 import functools
 import gc
 import io
@@ -25,6 +26,7 @@ if sys.platform != 'win32':
     import tty
 
 import asyncio
+from asyncio import coroutines
 from asyncio import proactor_events
 from asyncio import selector_events
 from asyncio import sslproto
@@ -2380,6 +2382,38 @@ class HandleTests(test_utils.TestCase):
         h = loop.call_later(0, noop)
         check_source_traceback(h)
 
+    @unittest.skipUnless(hasattr(collections.abc, 'Coroutine'),
+                         'No collections.abc.Coroutine')
+    def test_coroutine_like_object_debug_formatting(self):
+        # Test that asyncio can format coroutines that are instances of
+        # collections.abc.Coroutine, but lack cr_core or gi_code attributes
+        # (such as ones compiled with Cython).
+
+        class Coro:
+            __name__ = 'AAA'
+
+            def send(self, v):
+                pass
+
+            def throw(self, *exc):
+                pass
+
+            def close(self):
+                pass
+
+            def __await__(self):
+                pass
+
+        coro = Coro()
+        self.assertTrue(asyncio.iscoroutine(coro))
+        self.assertEqual(coroutines._format_coroutine(coro), 'AAA()')
+
+        coro.__qualname__ = 'BBB'
+        self.assertEqual(coroutines._format_coroutine(coro), 'BBB()')
+
+        coro.cr_running = True
+        self.assertEqual(coroutines._format_coroutine(coro), 'BBB() running')
+
 
 class TimerTests(unittest.TestCase):
 
index 0a92e6a47c9fd3077357d8c0fd481699e5af7709..9be8c8a5a63620bcd5e219b47a6b7e107f9e85b2 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -358,6 +358,8 @@ Library
 
 - Issue #28371: Deprecate passing asyncio.Handles to run_in_executor.
 
+- Issue #28372: Fix asyncio to support formatting of non-python coroutines.
+
 IDLE
 ----