#23641: Apps.set_installed_apps causes signals registered with apps as senders 
not
to be received
------------------------------+------------------------------------
     Reporter:  wrwrwr        |                    Owner:  nobody
         Type:  Bug           |                   Status:  new
    Component:  Core (Other)  |                  Version:  master
     Severity:  Normal        |               Resolution:
     Keywords:                |             Triage Stage:  Accepted
    Has patch:  1             |      Needs documentation:  0
  Needs tests:  0             |  Patch needs improvement:  0
Easy pickings:  0             |                    UI/UX:  0
------------------------------+------------------------------------
Changes (by wrwrwr):

 * has_patch:  0 => 1


Old description:

> Calling `Apps.set_installed_apps` before `DiscoverRunner.setup_databases`
> causes pre/post_migrate signal handlers registered on module import with
> app configs as senders not to be executed for the test database.
>
> The signal dispatcher stores `id()` of the  sender argument provided to
> `connect` to identify the sender that we're interested in receiving the
> signals from, in case of `post_migrate` signals this is often an id of an
> `AppConfig` for the registering app. When `set_installed_apps` is called
> it reinstantiates all app configs. If afterwards you send a signal using
> app config from the global app registry as the sender (as is the case in
> `emit_post_migrate_signal` when setting up test databases), its id won't
> match the one stored by the dispatcher, thus signal handlers won't get
> executed.
>
> [https://github.com/wrwrwr/django/tree/fix/missing-default-site-with-set-
> installed-apps A branch] with an example test case and a possible partial
> fix (that in full would be moving all module-level signal registration to
> `AppConfig.ready`).
>
> [https://github.com/wrwrwr/mezzanine/blob/maintenance/1.8-discover-test-
> runner/mezzanine/utils/tests.py#L117 A sketch] of a possible more general
> solution / workaround (this Mezzanine wrapper for `DiscoverRunner` turned
> out pretty involved, you're welcome to suggest a cleaner implementation
> :-)
>
> See also #22688: AppConfig.ready is going to get called for every
> instance, so should be a good place to put these signal registrations.

New description:

 Calling `Apps.set_installed_apps` before `DiscoverRunner.setup_databases`
 causes pre/post_migrate signal handlers registered on module import with
 app configs as senders not to be executed for the test database.

 The signal dispatcher stores `id()` of the  sender argument provided to
 `connect` to identify the sender that we're interested in receiving the
 signals from, in case of `post_migrate` signals this is often an id of an
 `AppConfig` for the registering app. When `set_installed_apps` is called
 it reinstantiates all app configs. If afterwards you send a signal using
 app config from the global app registry as the sender (as is the case in
 `emit_post_migrate_signal` when setting up test databases), its id won't
 match the one stored by the dispatcher, thus signal handlers won't get
 executed.

 [https://github.com/wrwrwr/django/compare/ticket_23641 A branch] with an
 example test case and a possible fix.

 [https://github.com/wrwrwr/mezzanine/blob/maintenance/1.8-discover-test-
 runner/mezzanine/utils/tests.py#L117 A sketch] of a possible more general
 solution / workaround (this Mezzanine wrapper for `DiscoverRunner` turned
 out pretty involved, you're welcome to suggest a cleaner implementation
 :-)

 See also #22688: AppConfig.ready is going to get called for every
 instance, so should be a good place to put these signal registrations.

--

Comment:

 Cleaned up and rebased
 [https://github.com/wrwrwr/django/compare/ticket_23641 branch] moving the
 `post_migrate` signal registration for `auth`, `contenttypes` and `sites`
 to `ready` and adding two notes to the docs (in short: -- registering
 signals in `ready` may require a `dispatch_uid`, -- signals using app
 config as a `sender` should only be registered in `ready`). I may be
 overdoing the documentation, so please consider if it wouldn't be better
 to just skip the notes.

--
Ticket URL: <https://code.djangoproject.com/ticket/23641#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/064.bdaa698b23d6d5deab21a6dfa45d27f8%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to