diff options
author | Phil Jones <philip.graham.jones@googlemail.com> | 2023-01-23 23:00:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-24 00:00:32 +0100 |
commit | d06b2416ea43c535b907b7d0a2b72fff3b2f3a0f (patch) | |
tree | 566da903678855496ab9d691f229edc2bf89c917 | |
parent | 9c2f289f024e7aac20bf3dbdebfc4ec279df3458 (diff) | |
download | blinker-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.rst | 13 | ||||
-rw-r--r-- | src/blinker/base.py | 26 | ||||
-rw-r--r-- | tests/test_signals.py | 17 |
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() |