Opened 4 years ago
Closed 4 years ago
#32594 closed Bug (fixed)
Signal.disconnect() returns None when passing sender as string
Reported by: | Hugo Cachitas | Owned by: | Hugo Cachitas |
---|---|---|---|
Component: | Documentation | Version: | 4.0 |
Severity: | Normal | Keywords: | signals |
Cc: | Alex Hill | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
According to the documentation on Signal.disconnect(receiver=None, sender=None, dispatch_uid=None)
The method returns True if a receiver was disconnected and False if not.
I am having this issue where disconnect()
returns None
when I specify the sender as a string model reference, i.e., passing sender="myapp.MyModel"
instead of sender=MyModel
.
The sender may be lazily specified as a string as documented in django.db.models.signals.ModelSignal
.
To achieve this functionality, a _lazy_method
is implemented where we can find that the return value is not properly set.
if isinstance(sender, str): apps = apps or Options.default_apps apps.lazy_model_operation(partial_method, make_model_tuple(sender)) else: return partial_method(sender)
I already have a failing test at tests/signals/tests.py:LazyModelRefTests
that could use your input.
@isolate_apps('signals', kwarg_name='apps') def test_disconnect_return_value(self, apps): """ Signal.disconnect() return value should be consistent if we use the Model or its string reference. """ class Created(models.Model): pass def receiver(**kwargs): pass sender = Created signals.post_init.connect(receiver, sender=sender, apps=apps) self.assertTrue( signals.post_init.disconnect(receiver, sender=sender, apps=apps) ) self.assertFalse( signals.post_init.disconnect(receiver, sender=sender, apps=apps) ) sender = 'signals.Created' signals.post_init.connect(receiver, sender=sender, apps=apps) self.assertTrue( signals.post_init.disconnect(receiver, sender=sender, apps=apps) ) self.assertFalse( signals.post_init.disconnect(receiver, sender=sender, apps=apps) )
Change History (8)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
Has patch: | set |
---|
comment:3 by , 4 years ago
Keywords: | signals added |
---|
comment:4 by , 4 years ago
Cc: | added |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:6 by , 4 years ago
Component: | Database layer (models, ORM) → Documentation |
---|---|
Needs documentation: | set |
Patch needs improvement: | set |
I think we should document the current behavior.
comment:7 by , 4 years ago
Needs documentation: | unset |
---|---|
Patch needs improvement: | unset |
Triage Stage: | Accepted → Ready for checkin |
PR https://github.com/django/django/pull/14187
The solution involved touching the app registry.
Tests are passing, but I am not entirely sure of the implications the new intermediary returned values may have.