]> granicus.if.org Git - python/commitdiff
Issue #28703: Fix asyncio.iscoroutinefunction to handle Mock objects.
authorYury Selivanov <yury@magic.io>
Tue, 15 Nov 2016 20:20:34 +0000 (15:20 -0500)
committerYury Selivanov <yury@magic.io>
Tue, 15 Nov 2016 20:20:34 +0000 (15:20 -0500)
Lib/asyncio/coroutines.py
Lib/test/test_asyncio/test_tasks.py
Misc/NEWS

index f46197dea6a391e2dc0273e6381cb72d9e913b68..5bdeceb9b117d79f9c0eaedb4aa9d67183232bfd 100644 (file)
@@ -33,12 +33,16 @@ _DEBUG = (not sys.flags.ignore_environment and
 
 try:
     _types_coroutine = types.coroutine
+    _types_CoroutineType = types.CoroutineType
 except AttributeError:
+    # Python 3.4
     _types_coroutine = None
+    _types_CoroutineType = None
 
 try:
     _inspect_iscoroutinefunction = inspect.iscoroutinefunction
 except AttributeError:
+    # Python 3.4
     _inspect_iscoroutinefunction = lambda func: False
 
 try:
@@ -238,19 +242,27 @@ def coroutine(func):
             w.__qualname__ = getattr(func, '__qualname__', None)
             return w
 
-    wrapper._is_coroutine = True  # For iscoroutinefunction().
+    wrapper._is_coroutine = _is_coroutine  # For iscoroutinefunction().
     return wrapper
 
 
+# A marker for iscoroutinefunction.
+_is_coroutine = object()
+
+
 def iscoroutinefunction(func):
     """Return True if func is a decorated coroutine function."""
-    return (getattr(func, '_is_coroutine', False) or
+    return (getattr(func, '_is_coroutine', None) is _is_coroutine or
             _inspect_iscoroutinefunction(func))
 
 
 _COROUTINE_TYPES = (types.GeneratorType, CoroWrapper)
 if _CoroutineABC is not None:
     _COROUTINE_TYPES += (_CoroutineABC,)
+if _types_CoroutineType is not None:
+    # Prioritize native coroutine check to speed-up
+    # asyncio.iscoroutine.
+    _COROUTINE_TYPES = (_types_CoroutineType,) + _COROUTINE_TYPES
 
 
 def iscoroutine(obj):
index 22accf5d1edaa1d94a2901c86eb05af2024e33fe..9872926739f01ce395f870a2e7805e832ef0a8f8 100644 (file)
@@ -1376,6 +1376,8 @@ class TaskTests(test_utils.TestCase):
             yield
         self.assertTrue(asyncio.iscoroutinefunction(fn2))
 
+        self.assertFalse(asyncio.iscoroutinefunction(mock.Mock()))
+
     def test_yield_vs_yield_from(self):
         fut = asyncio.Future(loop=self.loop)
 
index 989fa4446af916a1557e41d314bd79b76031555e..9e6e0de051223202b61cb6aed2a0e6178f059cf1 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -465,6 +465,8 @@ Library
 
 - Issue #28653: Fix a refleak in functools.lru_cache.
 
+- Issue #28703: Fix asyncio.iscoroutinefunction to handle Mock objects.
+
 IDLE
 ----