changeset 3215:bfa1bde97f48

core (tools/utils): new `asDeferred` function: asDeferred is similar to defer.maybeCoroutine, and also handles coroutine.
author Goffi <goffi@goffi.org>
date Fri, 13 Mar 2020 17:46:27 +0100
parents 8d92d4d829fb
children 8418e0c83ed7
files sat/tools/utils.py
diffstat 1 files changed, 24 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/sat/tools/utils.py	Wed Mar 11 20:44:49 2020 +0100
+++ b/sat/tools/utils.py	Fri Mar 13 17:46:27 2020 +0100
@@ -29,7 +29,9 @@
 import inspect
 import textwrap
 import functools
-from twisted.python import procutils
+from asyncio import iscoroutine
+from twisted.python import procutils, failure
+from twisted.internet import defer
 from sat.core.constants import Const as C
 from sat.core.log import getLogger
 
@@ -90,6 +92,27 @@
     return method
 
 
+def asDeferred(func, *args, **kwargs):
+    """Call a method and return a Deferred
+
+    the method can be a simple callable, a Deferred or a coroutine.
+    It is similar to defer.maybeDeferred, but also handles coroutines
+    """
+    try:
+        ret = func(*args, **kwargs)
+    except Exception as e:
+        return defer.fail(failure.Failure(e))
+    else:
+        if iscoroutine(ret):
+            return defer.ensureDeferred(ret)
+        elif isinstance(ret, defer.Deferred):
+            return ret
+        elif isinstance(ret, failure.Failure):
+            return defer.fail(ret)
+        else:
+            return ret
+
+
 def xmpp_date(timestamp=None, with_time=True):
     """Return date according to XEP-0082 specification