Created
March 30, 2015 16:45
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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