[Python-checkins] cpython (3.4): Issue #24400: Fix CoroWrapper for 'async def' coroutines

yury.selivanov python-checkins at python.org
Wed Jun 24 16:48:35 CEST 2015


https://hg.python.org/cpython/rev/3a78be4bcbde
changeset:   96655:3a78be4bcbde
branch:      3.4
parent:      96652:f4b702672beb
user:        Yury Selivanov <yselivanov at sprymix.com>
date:        Wed Jun 24 10:30:14 2015 -0400
summary:
  Issue #24400: Fix CoroWrapper for 'async def' coroutines

files:
  Lib/asyncio/coroutines.py           |  50 +++++++++++++---
  Lib/test/test_asyncio/test_tasks.py |   3 +-
  2 files changed, 42 insertions(+), 11 deletions(-)


diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py
--- a/Lib/asyncio/coroutines.py
+++ b/Lib/asyncio/coroutines.py
@@ -103,9 +103,6 @@
     def __iter__(self):
         return self
 
-    if _PY35:
-        __await__ = __iter__ # make compatible with 'await' expression
-
     def __next__(self):
         return self.gen.send(None)
 
@@ -143,10 +140,28 @@
     def gi_code(self):
         return self.gen.gi_code
 
+    if _PY35:
+
+        __await__ = __iter__ # make compatible with 'await' expression
+
+        @property
+        def cr_running(self):
+            return self.gen.cr_running
+
+        @property
+        def cr_code(self):
+            return self.gen.cr_code
+
+        @property
+        def cr_frame(self):
+            return self.gen.cr_frame
+
     def __del__(self):
         # Be careful accessing self.gen.frame -- self.gen might not exist.
         gen = getattr(self, 'gen', None)
         frame = getattr(gen, 'gi_frame', None)
+        if frame is None:
+            frame = getattr(gen, 'cr_frame', None)
         if frame is not None and frame.f_lasti == -1:
             msg = '%r was never yielded from' % self
             tb = getattr(self, '_source_traceback', ())
@@ -233,28 +248,43 @@
 def _format_coroutine(coro):
     assert iscoroutine(coro)
 
+    coro_name = None
     if isinstance(coro, CoroWrapper):
         func = coro.func
+        coro_name = coro.__qualname__
     else:
         func = coro
-    coro_name = events._format_callback(func, ())
 
-    filename = coro.gi_code.co_filename
+    if coro_name is None:
+        coro_name = events._format_callback(func, ())
+
+    try:
+        coro_code = coro.gi_code
+    except AttributeError:
+        coro_code = coro.cr_code
+
+    try:
+        coro_frame = coro.gi_frame
+    except AttributeError:
+        coro_frame = coro.cr_frame
+
+    filename = coro_code.co_filename
     if (isinstance(coro, CoroWrapper)
-    and not inspect.isgeneratorfunction(coro.func)):
+    and not inspect.isgeneratorfunction(coro.func)
+    and coro.func is not None):
         filename, lineno = events._get_function_source(coro.func)
-        if coro.gi_frame is None:
+        if coro_frame is None:
             coro_repr = ('%s done, defined at %s:%s'
                          % (coro_name, filename, lineno))
         else:
             coro_repr = ('%s running, defined at %s:%s'
                          % (coro_name, filename, lineno))
-    elif coro.gi_frame is not None:
-        lineno = coro.gi_frame.f_lineno
+    elif coro_frame is not None:
+        lineno = coro_frame.f_lineno
         coro_repr = ('%s running at %s:%s'
                      % (coro_name, filename, lineno))
     else:
-        lineno = coro.gi_code.co_firstlineno
+        lineno = coro_code.co_firstlineno
         coro_repr = ('%s done, defined at %s:%s'
                      % (coro_name, filename, lineno))
 
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -1715,7 +1715,8 @@
         self.assertTrue(m_log.error.called)
         message = m_log.error.call_args[0][0]
         func_filename, func_lineno = test_utils.get_function_source(coro_noop)
-        regex = (r'^<CoroWrapper %s\(\) .* at %s:%s, .*> '
+
+        regex = (r'^<CoroWrapper %s\(?\)? .* at %s:%s, .*> '
                     r'was never yielded from\n'
                  r'Coroutine object created at \(most recent call last\):\n'
                  r'.*\n'

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list