Commit 0a6314f2 authored by Jacob Kaplan-Moss's avatar Jacob Kaplan-Moss
Browse files

Fixed #8285: signal handlers that aren't functions work under DEBUG. This...

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
parent 1aa48898
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -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:
+7 −3
Original line number Diff line number Diff line
@@ -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)