Browse Source

Fixed #32594 -- Doc'd and tested that Signal.disconnect() with lazy references returns None.

Hugo Cachitas 4 years ago
parent
commit
8f6a7a0e9e
2 changed files with 40 additions and 7 deletions
  1. 3 1
      docs/topics/signals.txt
  2. 37 6
      tests/signals/tests.py

+ 3 - 1
docs/topics/signals.txt

@@ -277,7 +277,9 @@ Disconnecting signals
 
 To disconnect a receiver from a signal, call :meth:`Signal.disconnect`. The
 arguments are as described in :meth:`.Signal.connect`. The method returns
-``True`` if a receiver was disconnected and ``False`` if not.
+``True`` if a receiver was disconnected and ``False`` if not. When ``sender``
+is passed as a lazy reference to ``<app label>.<model>``, this method always
+returns ``None``.
 
 The ``receiver`` argument indicates the registered receiver to disconnect. It
 may be ``None`` if ``dispatch_uid`` is used to identify the receiver.

+ 37 - 6
tests/signals/tests.py

@@ -351,20 +351,51 @@ class LazyModelRefTests(BaseSignalSetup, SimpleTestCase):
             signals.post_init.disconnect(self.receiver, sender=Created)
 
     @isolate_apps('signals', kwarg_name='apps')
-    def test_disconnect(self, apps):
+    def test_disconnect_registered_model(self, apps):
         received = []
 
         def receiver(**kwargs):
             received.append(kwargs)
 
-        signals.post_init.connect(receiver, sender='signals.Created', apps=apps)
-        signals.post_init.disconnect(receiver, sender='signals.Created', apps=apps)
-
         class Created(models.Model):
             pass
 
-        Created()
-        self.assertEqual(received, [])
+        signals.post_init.connect(receiver, sender='signals.Created', apps=apps)
+        try:
+            self.assertIsNone(
+                signals.post_init.disconnect(receiver, sender='signals.Created', apps=apps)
+            )
+            self.assertIsNone(
+                signals.post_init.disconnect(receiver, sender='signals.Created', apps=apps)
+            )
+            Created()
+            self.assertEqual(received, [])
+        finally:
+            signals.post_init.disconnect(receiver, sender='signals.Created')
+
+    @isolate_apps('signals', kwarg_name='apps')
+    def test_disconnect_unregistered_model(self, apps):
+        received = []
+
+        def receiver(**kwargs):
+            received.append(kwargs)
+
+        signals.post_init.connect(receiver, sender='signals.Created', apps=apps)
+        try:
+            self.assertIsNone(
+                signals.post_init.disconnect(receiver, sender='signals.Created', apps=apps)
+            )
+            self.assertIsNone(
+                signals.post_init.disconnect(receiver, sender='signals.Created', apps=apps)
+            )
+
+            class Created(models.Model):
+                pass
+
+            Created()
+            self.assertEqual(received, [])
+        finally:
+            signals.post_init.disconnect(receiver, sender='signals.Created')
 
     def test_register_model_class_senders_immediately(self):
         """