Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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
  • Loading branch information...
commit 0a6314f249f02d928bf5cf29def470e180898e0d 1 parent 1aa4889
@jacobian jacobian authored
View
20 django/dispatch/dispatcher.py
@@ -63,10 +63,26 @@ def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
"""
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, \
- "Signal receivers must accept keyword arguments (**kwargs)."
+ 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:
lookup_key = (dispatch_uid, _make_id(sender))
View
10 tests/modeltests/signals/models.py
@@ -30,9 +30,13 @@ 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):
- print 'post_delete signal,', instance
- print 'instance.id is None: %s' % (instance.id == None)
+# #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)
Please sign in to comment.
Something went wrong with that request. Please try again.