summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Jones <philip.graham.jones@googlemail.com>2023-01-23 23:00:32 +0000
committerGitHub <noreply@github.com>2023-01-24 00:00:32 +0100
commitd06b2416ea43c535b907b7d0a2b72fff3b2f3a0f (patch)
tree566da903678855496ab9d691f229edc2bf89c917
parent9c2f289f024e7aac20bf3dbdebfc4ec279df3458 (diff)
downloadblinker-d06b2416ea43c535b907b7d0a2b72fff3b2f3a0f.tar.gz
Added `muted` context manager for temproary switching signal off (#84)
This is useful whilst testing to remove a signal's affects. Co-authored-by: Michael Elovskikh <wronglink@yandex-team.ru>
-rw-r--r--docs/index.rst13
-rw-r--r--src/blinker/base.py26
-rw-r--r--tests/test_signals.py17
3 files changed, 52 insertions, 4 deletions
diff --git a/docs/index.rst b/docs/index.rst
index 92b89ba..9c733bb 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -157,6 +157,19 @@ value``) pairs:
[(<function receive_data at 0x...>, 'received!')]
+Muting signals
+--------------
+
+To mute a signal, as may be required when testing, the
+:meth:`~Signal.muted` can be used as a context decorator:
+
+.. code-block:: python
+
+ sig = signal('send-data')
+ with sig.muted():
+ ...
+
+
Anonymous Signals
-----------------
diff --git a/src/blinker/base.py b/src/blinker/base.py
index 2b87cb9..f80750c 100644
--- a/src/blinker/base.py
+++ b/src/blinker/base.py
@@ -82,6 +82,7 @@ class Signal:
#: of the mapping is useful as an extremely efficient check to see if
#: any receivers are connected to the signal.
self.receivers = {}
+ self.is_muted = False
self._by_receiver = defaultdict(set)
self._by_sender = defaultdict(set)
self._weak_senders = {}
@@ -209,6 +210,19 @@ class Signal:
else:
self.disconnect(receiver)
+ @contextmanager
+ def muted(self):
+ """Context manager for temporarily disabling signal.
+ Useful for test purposes.
+ """
+ self.is_muted = True
+ try:
+ yield None
+ except Exception as e:
+ raise e
+ finally:
+ self.is_muted = False
+
def temporarily_connected_to(self, receiver, sender=ANY):
"""An alias for :meth:`connected_to`.
@@ -259,10 +273,14 @@ class Signal:
)
else:
sender = sender[0]
- return [
- (receiver, receiver(sender, **kwargs))
- for receiver in self.receivers_for(sender)
- ]
+
+ if self.is_muted:
+ return []
+ else:
+ return [
+ (receiver, receiver(sender, **kwargs))
+ for receiver in self.receivers_for(sender)
+ ]
def has_receivers_for(self, sender):
"""True if there is probably a receiver for *sender*.
diff --git a/tests/test_signals.py b/tests/test_signals.py
index 0879b5c..e79ff7f 100644
--- a/tests/test_signals.py
+++ b/tests/test_signals.py
@@ -512,6 +512,23 @@ def test_named_blinker():
assert "squiznart" in repr(sig)
+def test_mute_signal():
+ sentinel = []
+
+ def received(sender):
+ sentinel.append(sender)
+
+ sig = blinker.Signal()
+ sig.connect(received)
+
+ sig.send(123)
+ assert 123 in sentinel
+
+ with sig.muted():
+ sig.send(456)
+ assert 456 not in sentinel
+
+
def values_are_empty_sets_(dictionary):
for val in dictionary.values():
assert val == set()