Skip to content

Commit

Permalink
Added return value to Signal.disconnect().
Browse files Browse the repository at this point in the history
  • Loading branch information
Andriy Sokolovskiy authored and timgraham committed Jan 2, 2015
1 parent 937fab0 commit 23f1a8d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
3 changes: 3 additions & 0 deletions django/dispatch/dispatcher.py
Expand Up @@ -160,14 +160,17 @@ def disconnect(self, receiver=None, sender=None, weak=True, dispatch_uid=None):
else:
lookup_key = (_make_id(receiver), _make_id(sender))

disconnected = False
with self.lock:
self._clear_dead_receivers()
for index in range(len(self.receivers)):
(r_key, _) = self.receivers[index]
if r_key == lookup_key:
disconnected = True
del self.receivers[index]
break
self.sender_receivers_cache.clear()
return disconnected

def has_listeners(self, sender=None):
return bool(self._live_receivers(sender))
Expand Down
11 changes: 8 additions & 3 deletions docs/topics/signals.txt
Expand Up @@ -278,7 +278,12 @@ Disconnecting signals
.. method:: Signal.disconnect([receiver=None, sender=None, weak=True, dispatch_uid=None])

To disconnect a receiver from a signal, call :meth:`Signal.disconnect`. The
arguments are as described in :meth:`.Signal.connect`.
arguments are as described in :meth:`.Signal.connect`. The method returns
``True`` if a receiver was disconnected and ``False`` if not.

The *receiver* argument indicates the registered receiver to disconnect. It may
be ``None`` if ``dispatch_uid`` is used to identify the receiver.
The ``receiver`` argument indicates the registered receiver to disconnect. It
may be ``None`` if ``dispatch_uid`` is used to identify the receiver.

.. versionchanged:: 1.8

The boolean return value was added.
10 changes: 10 additions & 0 deletions tests/dispatch/tests.py
Expand Up @@ -153,6 +153,16 @@ def test_disconnection(self):
a_signal.disconnect(receiver_3)
self.assertTestIsClean(a_signal)

def test_values_returned_by_disconnection(self):
receiver_1 = Callable()
receiver_2 = Callable()
a_signal.connect(receiver_1)
receiver_1_disconnected = a_signal.disconnect(receiver_1)
receiver_2_disconnected = a_signal.disconnect(receiver_2)
self.assertTrue(receiver_1_disconnected)
self.assertFalse(receiver_2_disconnected)
self.assertTestIsClean(a_signal)

def test_has_listeners(self):
self.assertFalse(a_signal.has_listeners())
self.assertFalse(a_signal.has_listeners(sender=object()))
Expand Down

0 comments on commit 23f1a8d

Please sign in to comment.