Fixed #8285: signal handlers that aren't functions work under DEBUG. This slightly loosens the sanity check, but things that are valid under production shouldn't fail under debug.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8546 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2008-08-25 18:24:05 +00:00
parent 1aa4889808
commit 0a6314f249
2 changed files with 25 additions and 5 deletions

View File

@ -63,9 +63,25 @@ class Signal(object):
"""
from django.conf import settings
# If DEBUG is on, check that we got a good receiver
if settings.DEBUG:
import inspect
assert inspect.getargspec(receiver)[2] is not None, \
assert callable(receiver), "Signal receivers must be callable."
# Check for **kwargs
# Not all callables are inspectable with getargspec, so we'll
# try a couple different ways but in the end fall back on assuming
# it is -- we don't want to prevent registration of valid but weird
# callables.
try:
argspec = inspect.getargspec(receiver)
except TypeError:
try:
argspec = inspect.getargspec(receiver.__call__)
except (TypeError, AttributeError):
argspec = None
if argspec:
assert argspec[2] is not None, \
"Signal receivers must accept keyword arguments (**kwargs)."
if dispatch_uid:

View File

@ -30,10 +30,14 @@ def pre_delete_test(signal, sender, instance, **kwargs):
print 'pre_delete signal,', instance
print 'instance.id is not None: %s' % (instance.id != None)
def post_delete_test(signal, sender, instance, **kwargs):
# #8285: signals can be any callable
class PostDeleteHandler(object):
def __call__(self, signal, sender, instance, **kwargs):
print 'post_delete signal,', instance
print 'instance.id is None: %s' % (instance.id == None)
post_delete_test = PostDeleteHandler()
__test__ = {'API_TESTS':"""
>>> models.signals.pre_save.connect(pre_save_test)
>>> models.signals.post_save.connect(post_save_test)