﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
35801	Signals are dispatched to receivers associated with dead senders	bobince	Simon Charette	"django.dispatch.Signal.receivers is keyed on the id() of the receiver and sender (modulo a thing to make bound methods consistent).

If a sender connected to a signal is destroyed, and a new object is allocated with the same id() and then also connected as a sender to the signal, when the signal fires it will match the original sender and call the receiver that was connected for that sender (as well as the new one).

Signal works around the problem of re-used ids for the receiver by having a weakref to the receiver (since it needs a reference anyway to be able to call it), but it doesn't for sender.

In my case this resulted in post-migrate hooks for the wrong apps being occasionally called in migration tests that mutated INSTALLED_APPS causing AppConfig senders to be re-created, but it can be more simply provoked with:

{{{
from django.dispatch import Signal

receivers_called = []
def create_receiver(i):
    def receiver(**kwargs):
        receivers_called.append(i)
    return receiver

n = 100
receivers = [create_receiver(i) for i in range(n)]

signal = Signal()
for i in range(n):
    sender = object()
    signal.connect(receivers[i], sender=sender)
    receivers_called = []
    _ = signal.send(sender=sender)
    # only the receiver for the new sender object should be called
    assert receivers_called == [i], f'Expected [{i}], called {receivers_called}'
}}}

(how readily this explodes may depend on local memory allocation differences, but it dies pretty consistently for me on iteratio
n 3.)

Perhaps Signal should be keeping a weakref to each sender as well as receiver, and detecting when it has gone None? Does this need to participate in the _dead_receivers mechanism?"	Bug	closed	Core (Other)	5.1	Normal	fixed		bobince Simon Charette Lincoln	Ready for checkin	1	0	0	0	0	0
