#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.