Repository: celery/celery

Issue:
RC3: django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
## Steps to reproduce
Django: 1.8.19
django-celery-beat: 1.1.1
django-celery-results: 1.0.1

While attempting to see if 4.2 fixes: https://github.com/celery/django-celery-beat/issues/7 (doesn't seem to)
I installed 4.2, RC1, 2 and then 3. When attempting to start RC3 in my test env, 
`celery -A proj worker -B -E -l info`
it fails to start with the `django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.` error.

## Expected behavior
RC2 starts.

## Actual behavior

`Traceback (most recent call last):
  File "/proj.env/bin/celery", line 11, in <module>
    sys.exit(main())
  File "/proj.env/lib/python2.7/site-packages/celery/__main__.py", line 16, in main
    _main()
  File "/proj.env/lib/python2.7/site-packages/celery/bin/celery.py", line 322, in main
    cmd.execute_from_commandline(argv)
  File "/proj.env/lib/python2.7/site-packages/celery/bin/celery.py", line 484, in execute_from_commandline
    super(CeleryCommand, self).execute_from_commandline(argv)))
  File "/proj.env/lib/python2.7/site-packages/celery/bin/base.py", line 275, in execute_from_commandline
    return self.handle_argv(self.prog_name, argv[1:])
  File "/proj.env/lib/python2.7/site-packages/celery/bin/celery.py", line 476, in handle_argv
    return self.execute(command, argv)
  File "/proj.env/lib/python2.7/site-packages/celery/bin/celery.py", line 408, in execute
    ).run_from_argv(self.prog_name, argv[1:], command=argv[0])
  File "/proj.env/lib/python2.7/site-packages/celery/bin/worker.py", line 223, in run_from_argv
    return self(*args, **options)
  File "/proj.env/lib/python2.7/site-packages/celery/bin/base.py", line 238, in __call__
    ret = self.run(*args, **kwargs)
  File "/proj.env/lib/python2.7/site-packages/celery/bin/worker.py", line 257, in run
    **kwargs)
  File "/proj.env/lib/python2.7/site-packages/celery/worker/worker.py", line 96, in __init__
    self.app.loader.init_worker()
  File "/proj.env/lib/python2.7/site-packages/celery/loaders/base.py", line 114, in init_worker
    self.import_default_modules()
  File "/proj.env/lib/python2.7/site-packages/celery/loaders/base.py", line 108, in import_default_modules
    raise response
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.`



Discussion:
Same exception for env:

Python: 3.6.5
Django: 2.0.5

Without any celery-beat | celery-results.

RC2 works fine.

Same problem.  Config is similar to friendka.


Resolving patch:
diff --git a/celery/utils/dispatch/signal.py b/celery/utils/dispatch/signal.py
--- a/celery/utils/dispatch/signal.py
+++ b/celery/utils/dispatch/signal.py
@@ -37,6 +37,28 @@ def _make_id(target):  # pragma: no cover
     return id(target)
 
 
+def _boundmethod_safe_weakref(obj):
+    """Get weakref constructor appropriate for `obj`.  `obj` may be a bound method.
+
+    Bound method objects must be special-cased because they're usually garbage
+    collected immediately, even if the instance they're bound to persists.
+
+    Returns:
+        a (weakref constructor, main object) tuple. `weakref constructor` is
+        either :class:`weakref.ref` or :class:`weakref.WeakMethod`.  `main
+        object` is the instance that `obj` is bound to if it is a bound method;
+        otherwise `main object` is simply `obj.
+    """
+    try:
+        obj.__func__
+        obj.__self__
+        # Bound method
+        return WeakMethod, obj.__self__
+    except AttributeError:
+        # Not a bound method
+        return weakref.ref, obj
+
+
 def _make_lookup_key(receiver, sender, dispatch_uid):
     if dispatch_uid:
         return (dispatch_uid, _make_id(sender))
@@ -183,8 +205,7 @@ def _connect_signal(self, receiver, sender, weak, dispatch_uid):
         lookup_key = _make_lookup_key(receiver, sender, dispatch_uid)
 
         if weak:
-            ref = weakref.ref
-            receiver_object = receiver
+            ref, receiver_object = _boundmethod_safe_weakref(receiver)
             if PY3:
                 receiver = ref(receiver)
                 weakref.finalize(receiver_object, self._remove_receiver)


Test patch:
diff --git a/t/unit/utils/test_dispatcher.py b/t/unit/utils/test_dispatcher.py
--- a/t/unit/utils/test_dispatcher.py
+++ b/t/unit/utils/test_dispatcher.py
@@ -173,3 +173,14 @@ def test_retry_with_dispatch_uid(self):
         assert a_signal.receivers[0][0][0] == uid
         a_signal.disconnect(receiver_1_arg, sender=self, dispatch_uid=uid)
         self._testIsClean(a_signal)
+
+    def test_boundmethod(self):
+        a = Callable()
+        a_signal.connect(a.a, sender=self)
+        expected = [(a.a, 'test')]
+        garbage_collect()
+        result = a_signal.send(sender=self, val='test')
+        assert result == expected
+        del a, result, expected
+        garbage_collect()
+        self._testIsClean(a_signal)