summaryrefslogtreecommitdiff
path: root/blinker
diff options
context:
space:
mode:
Diffstat (limited to 'blinker')
-rw-r--r--blinker/__init__.py5
-rw-r--r--blinker/_async.py28
-rw-r--r--blinker/base.py11
3 files changed, 44 insertions, 0 deletions
diff --git a/blinker/__init__.py b/blinker/__init__.py
index 57e1be8..a3251bd 100644
--- a/blinker/__init__.py
+++ b/blinker/__init__.py
@@ -20,3 +20,8 @@ __all__ = [
__version__ = '1.5dev'
+
+try:
+ import blinker._async
+except (ImportError, SyntaxError):
+ pass
diff --git a/blinker/_async.py b/blinker/_async.py
new file mode 100644
index 0000000..2b530e4
--- /dev/null
+++ b/blinker/_async.py
@@ -0,0 +1,28 @@
+import asyncio
+
+from blinker.base import Signal
+
+
+try:
+ schedule = asyncio.create_task
+except AttributeError:
+ schedule = asyncio.ensure_future
+
+
+@asyncio.coroutine
+def _wrap_plain_value(value):
+ """Pass through a coroutine *value* or wrap a plain value."""
+ if asyncio.iscoroutine(value):
+ value = yield from value
+ return value
+
+
+def send_async(self, *sender, **kwargs):
+ return [(receiver, schedule(_wrap_plain_value(value)))
+ for receiver, value
+ in self.send(*sender, **kwargs)]
+
+
+send_async.__doc__ = Signal.send_async.__doc__
+Signal.send_async = send_async
+
diff --git a/blinker/base.py b/blinker/base.py
index b68d8db..a2f22aa 100644
--- a/blinker/base.py
+++ b/blinker/base.py
@@ -271,6 +271,17 @@ class Signal(object):
return [(receiver, receiver(sender, **kwargs))
for receiver in self.receivers_for(sender)]
+ def send_async(self, *sender, **kwargs):
+ """Send and collect results from connected functions and coroutines.
+
+ As `Signal.send`, but also schedules any coroutines connected to the
+ signal, and uniformly presents all receiver return values as futures,
+ even if one or more receivers are regular functions.
+
+ Available only if asyncio and `yield from` are present.
+ """
+ raise NotImplementedError("asyncio support unavailable")
+
def has_receivers_for(self, sender):
"""True if there is probably a receiver for *sender*.