#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
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