Skip to content

Instantly share code, notes, and snippets.

@wolever
Created March 30, 2015 16:45
Show Gist options
  • Save wolever/adb4ee8307e5971bf718 to your computer and use it in GitHub Desktop.
Save wolever/adb4ee8307e5971bf718 to your computer and use it in GitHub Desktop.
Django signal handlers are stored as weak refs and should *not* be added inside closures.
# BAD: Signal receivers will not be executed because, when the function
# returns, all references to them will be lost and they will be GC'd.
from django.db.models.signals import pre_delete
from django.dispatch import receiver
def add_signal_receivers_unsafe():
@receiver(pre_delete)
def receive_pre_delete(sender, **kwargs):
print "pre_delete received!"
print "receviers inside add_signal_receivers_unsafe:", pre_delete.receivers
print "receivers before:", pre_delete.receivers
add_signal_receivers_unsafe()
print "receivers after:", pre_delete.receivers
# Prints:
# $ python manage.py script signal-handlers-example.py
# receivers before: []
# receviers inside add_signal_receivers_unsafe: [((4396463960, 4371124552), <weakref at 0x1096cfba8; to 'function' at 0x1060cb758 (receive_pre_delete)>)]
# receivers after: []
# GOOD: store a reference to the receiver before connecting it:
_strongref_receivers = []
def receiver_strongref(*args, **kwargs):
def receiver_strongref_helper(f):
_strongref_receivers.append(f)
return receiver(*args, **kwargs)(f)
return receiver_strongref_helper
def add_signal_receivers_safe():
@receiver_strongref(pre_delete)
def receive_pre_delete(sender, **kwargs):
print "pre_delete received!"
print "receviers inside add_signal_receivers:", pre_delete.receivers
print "receivers before:", pre_delete.receivers
add_signal_receivers_safe()
print "receivers after:", pre_delete.receivers
# Prints:
# $ python manage.py script signal-handlers-example.py
# receivers before: []
# receviers inside add_signal_receivers_safe: [((4396463960, 4371124552), <weakref at 0x1096cfba8; to 'function' at 0x1060cb758 (receive_pre_delete)>)]
# receivers after: [[((4396463960, 4371124552), <weakref at 0x1096cfba8; to 'function' at 0x1060cb758 (receive_pre_delete)>)]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment