#33013: "AppConfig" subclass imports found in Django 3.2's automatic "AppConfig"
discovery
----------------------------------------+------------------------
Reporter: jwayodi | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
----------------------------------------+------------------------
We are in the process of adding support for Django 3.2 to
[https://github.com/django-oscar/django-oscar Oscar].
Oscar [https://github.com/django-oscar/django-
oscar/blob/04dd391c900537a61dbb0ae5250ca5c2df6bbc4b/src/oscar/core/application.py#L139
mixes in] its apps' configurations into Django's `AppConfig` class, and
developers using Oscar then subclass these, to make their own
modifications:
{{{
# my_app/apps.py
from oscar.core.application import OscarConfig
class MyAppConfig(OscarConfig):
# my app modifications
}}}
With Django 3.2, for apps added to `INSTALLED_APPS` using the dotted
Python path to the app package, Django finds all `AppConfig` subclasses in
the `apps.py` (using
[https://github.com/django/django/commit/3f2821af6bc48fa8e7970c1ce27bc54c3172545e
#diff-
0f8bc657bc27c9f80385c4814c2c2ebc033bda3e03285a7212965309a481cc70R110-R120
Python's] `inspect.getmembers`), including ones imported to be subclassed.
`django.apps.config.AppConfig` itself does get excluded, but this is not
sufficient, as we and the developers using Oscar do a lot of sub classing
of these classes.
To solve this, we would have have to do:
{{{
# my_app/apps.py
from oscar.core import application
class MyAppConfig(application.OscarConfig):
# my app modifications
}}}
And then ask the developers using Oscar to also do the same.
The problem with this is:
- it is not intuitive - Python developers would not typically expect
imports to cause side effects like this, which creates the potential for
confusing and hard-to-debug issues
- it is flaky - a new developer may innocently refactor imports not
realising why they were done that way, and then encounter the confusing
issues
- explicit class imports are normally preferred in Python, unless they
cause local name clashes, so requiring them for this reason is a bit odd
- Django itself
[https://github.com/django/django/commit/3f2821af6bc48fa8e7970c1ce27bc54c3172545e
#diff-
0f8bc657bc27c9f80385c4814c2c2ebc033bda3e03285a7212965309a481cc70R110-R120
does a check] to exclude `django.apps.config.AppConfig` from being
detected, which is indicative of the fundamental issue which remains
It would be nice if Django could mitigate this by having a mechanism for
deciding which classes are considered (e.g. using something like the
`abstract` metadata option used for models). In the short term,
restricting the scanning for `AppConfig` subclasses to those named in the
`app.py`'s `__all__` variable, if it has one (by e.g.
[https://github.com/django/django/commit/3f2821af6bc48fa8e7970c1ce27bc54c3172545e
#diff-
0f8bc657bc27c9f80385c4814c2c2ebc033bda3e03285a7212965309a481cc70R110-R120
adding the filter] `(not hasattr(mod, "__all__") or candidate.__name__ in
mod.__all__)`), would work, and is a bit more intuitive.
--
Ticket URL: <https://code.djangoproject.com/ticket/33013>
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 view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/050.495b7bf4403fd0579ea5ed412f63e575%40djangoproject.com.