Sometimes it's useful to test if a function is a coroutine function,
so implement a version of asyncio.iscoroutinefunction that works
with asyncio.coroutine as well as compat_coroutine.coroutine (since
both kinds of coroutine functions behave identically for our
purposes).
---
 lib/portage/util/futures/_asyncio/__init__.py | 14 ++++++++++++++
 lib/portage/util/futures/compat_coroutine.py  | 12 ++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/lib/portage/util/futures/_asyncio/__init__.py 
b/lib/portage/util/futures/_asyncio/__init__.py
index faab98e47..2a637624d 100644
--- a/lib/portage/util/futures/_asyncio/__init__.py
+++ b/lib/portage/util/futures/_asyncio/__init__.py
@@ -36,6 +36,7 @@ except ImportError:
 import portage
 portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util.futures.unix_events:_PortageEventLoopPolicy',
+       'portage.util.futures:compat_coroutine@_compat_coroutine',
 )
 from portage.util._eventloop.asyncio_event_loop import AsyncioEventLoop as 
_AsyncioEventLoop
 from portage.util._eventloop.global_event_loop import (
@@ -152,6 +153,19 @@ def create_subprocess_exec(*args, **kwargs):
        return result
 
 
+def iscoroutinefunction(func):
+       """
+       Return True if func is a decorated coroutine function,
+       supporting both asyncio.coroutine and compat_coroutine since
+       their behavior is identical for all practical purposes.
+       """
+       if _compat_coroutine._iscoroutinefunction(func):
+               return True
+       elif _real_asyncio is not None and 
_real_asyncio.iscoroutinefunction(func):
+               return True
+       return False
+
+
 class Task(Future):
        """
        Schedule the execution of a coroutine: wrap it in a future. A task
diff --git a/lib/portage/util/futures/compat_coroutine.py 
b/lib/portage/util/futures/compat_coroutine.py
index 59fdc31b6..be305c1b5 100644
--- a/lib/portage/util/futures/compat_coroutine.py
+++ b/lib/portage/util/futures/compat_coroutine.py
@@ -8,6 +8,17 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util.futures:asyncio',
 )
 
+# A marker for iscoroutinefunction.
+_is_coroutine = object()
+
+
+def _iscoroutinefunction(func):
+       """
+       Return True if func is a decorated coroutine function
+       created with the coroutine decorator for this module.
+       """
+       return getattr(func, '_is_coroutine', None) is _is_coroutine
+
 
 def coroutine(generator_func):
        """
@@ -34,6 +45,7 @@ def coroutine(generator_func):
        @functools.wraps(generator_func)
        def wrapped(*args, **kwargs):
                return _generator_future(generator_func, *args, **kwargs)
+       wrapped._is_coroutine = _is_coroutine
        return wrapped
 
 
-- 
2.16.4


Reply via email to