Repository: jd/tenacity

Issue:
Asyncio: iscoroutinefunction does not work with tenacity
When decorating an `async` function with `@retry`, `asyncio.iscoroutinefunction(f)` unexpectedly returns `False`, because the wrapping function, in fact, is no coroutine.

This is a problem in some libraries that are using this way of determining if they are handling an async function or not (in my case: trafaret).

Discussion:

Patch:
diff --git a/tenacity/_asyncio.py b/tenacity/_asyncio.py
index f93bf0f..035699d 100644
--- a/tenacity/_asyncio.py
+++ b/tenacity/_asyncio.py
@@ -38,6 +38,12 @@ if asyncio:
             super(AsyncRetrying, self).__init__(**kwargs)
             self.sleep = sleep
 
+        def wraps(self, fn):
+            fn = super().wraps(fn)
+            # Ensure wrapper is recognized as a coroutine function.
+            fn._is_coroutine = asyncio.coroutines._is_coroutine
+            return fn
+
         @asyncio.coroutine
         def call(self, fn, *args, **kwargs):
             self.begin(fn)


Test patch:
diff --git a/tenacity/tests/test_asyncio.py b/tenacity/tests/test_asyncio.py
index 6937511..8a8d3ce 100644
--- a/tenacity/tests/test_asyncio.py
+++ b/tenacity/tests/test_asyncio.py
@@ -36,9 +36,8 @@ def asynctest(callable_):
 
 
 @retry
-@asyncio.coroutine
-def _retryable_coroutine(thing):
-    yield from asyncio.sleep(0.00001)
+async def _retryable_coroutine(thing):
+    await asyncio.sleep(0.00001)
     return thing.go()