Skip to content

Commit

Permalink
Keep dynamically added model receivers at the end when unmuting signals
Browse files Browse the repository at this point in the history
Receiver order is somewhat important and packages like `django-dirtyfields` adds
receivers dynamically where it can reset the model state. This change restores
the original receivers first then appends any new dynamically added receivers.
  • Loading branch information
shosca committed Jun 9, 2022
1 parent 869e1b0 commit da1425e
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion factory/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,13 @@ def __exit__(self, exc_type, exc_value, traceback):
logger.debug('mute_signals: Restoring signal handlers %r',
receivers)

signal.receivers += receivers
with signal.lock:
new_receivers = signal.receivers
signal.receivers = receivers
for lookup_key, receiver in new_receivers:
# add dynamic receivers same way django signal adds them
if all(r_key != lookup_key for r_key, _ in signal.receivers):
signal.receivers.append((lookup_key, receiver))
# Django uses some caching for its signals.
# Since we're bypassing signal.connect and signal.disconnect,
# we have to keep messing with django's internals.
Expand Down

0 comments on commit da1425e

Please sign in to comment.