Refs #31180 -- Removed default_app_config application configuration variable per deprecation timeline.
This commit is contained in:
parent
d25710a625
commit
75d6c4ae6d
|
@ -1,10 +1,8 @@
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
import warnings
|
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.utils.deprecation import RemovedInDjango41Warning
|
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.module_loading import import_string, module_has_submodule
|
from django.utils.module_loading import import_string, module_has_submodule
|
||||||
|
|
||||||
|
@ -102,7 +100,6 @@ class AppConfig:
|
||||||
"""
|
"""
|
||||||
# create() eventually returns app_config_class(app_name, app_module).
|
# create() eventually returns app_config_class(app_name, app_module).
|
||||||
app_config_class = None
|
app_config_class = None
|
||||||
app_config_name = None
|
|
||||||
app_name = None
|
app_name = None
|
||||||
app_module = None
|
app_module = None
|
||||||
|
|
||||||
|
@ -134,7 +131,6 @@ class AppConfig:
|
||||||
]
|
]
|
||||||
if len(app_configs) == 1:
|
if len(app_configs) == 1:
|
||||||
app_config_class = app_configs[0][1]
|
app_config_class = app_configs[0][1]
|
||||||
app_config_name = '%s.%s' % (mod_path, app_configs[0][0])
|
|
||||||
else:
|
else:
|
||||||
# Check if there's exactly one AppConfig subclass,
|
# Check if there's exactly one AppConfig subclass,
|
||||||
# among those that explicitly define default = True.
|
# among those that explicitly define default = True.
|
||||||
|
@ -151,43 +147,11 @@ class AppConfig:
|
||||||
)
|
)
|
||||||
elif len(app_configs) == 1:
|
elif len(app_configs) == 1:
|
||||||
app_config_class = app_configs[0][1]
|
app_config_class = app_configs[0][1]
|
||||||
app_config_name = '%s.%s' % (mod_path, app_configs[0][0])
|
|
||||||
|
|
||||||
# If app_module specifies a default_app_config, follow the link.
|
# Use the default app config class if we didn't find anything.
|
||||||
# default_app_config is deprecated, but still takes over the
|
if app_config_class is None:
|
||||||
# automatic detection for backwards compatibility during the
|
app_config_class = cls
|
||||||
# deprecation period.
|
app_name = entry
|
||||||
try:
|
|
||||||
new_entry = app_module.default_app_config
|
|
||||||
except AttributeError:
|
|
||||||
# Use the default app config class if we didn't find anything.
|
|
||||||
if app_config_class is None:
|
|
||||||
app_config_class = cls
|
|
||||||
app_name = entry
|
|
||||||
else:
|
|
||||||
message = (
|
|
||||||
'%r defines default_app_config = %r. ' % (entry, new_entry)
|
|
||||||
)
|
|
||||||
if new_entry == app_config_name:
|
|
||||||
message += (
|
|
||||||
'Django now detects this configuration automatically. '
|
|
||||||
'You can remove default_app_config.'
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
message += (
|
|
||||||
"However, Django's automatic detection %s. You should "
|
|
||||||
"move the default config class to the apps submodule "
|
|
||||||
"of your application and, if this module defines "
|
|
||||||
"several config classes, mark the default one with "
|
|
||||||
"default = True." % (
|
|
||||||
"picked another configuration, %r" % app_config_name
|
|
||||||
if app_config_name
|
|
||||||
else "did not find this configuration"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
warnings.warn(message, RemovedInDjango41Warning, stacklevel=2)
|
|
||||||
entry = new_entry
|
|
||||||
app_config_class = None
|
|
||||||
|
|
||||||
# If import_string succeeds, entry is an app config class.
|
# If import_string succeeds, entry is an app config class.
|
||||||
if app_config_class is None:
|
if app_config_class is None:
|
||||||
|
|
|
@ -255,3 +255,5 @@ to remove usage of these features.
|
||||||
|
|
||||||
* The ``whitelist`` argument and ``domain_whitelist`` attribute of
|
* The ``whitelist`` argument and ``domain_whitelist`` attribute of
|
||||||
``django.core.validators.EmailValidator`` are removed.
|
``django.core.validators.EmailValidator`` are removed.
|
||||||
|
|
||||||
|
* The ``default_app_config`` application configuration variable is removed.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
default_app_config = 'apps.explicit_default_config_app.apps.ExplicitDefaultConfig'
|
|
|
@ -1,5 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class ExplicitDefaultConfig(AppConfig):
|
|
||||||
name = 'apps.explicit_default_config_app'
|
|
|
@ -1,7 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
default_app_config = 'apps.explicit_default_config_empty_apps.ExplicitDefaultConfigEmptyApps'
|
|
||||||
|
|
||||||
|
|
||||||
class ExplicitDefaultConfigEmptyApps(AppConfig):
|
|
||||||
name = 'apps.explicit_default_config_empty_apps'
|
|
|
@ -1 +0,0 @@
|
||||||
default_app_config = 'apps.explicit_default_config_mismatch_app.not_apps.ExplicitDefaultConfigMismatch'
|
|
|
@ -1,5 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class ImplicitDefaultConfigMismatch(AppConfig):
|
|
||||||
name = 'apps.explicit_default_config_mismatch_app'
|
|
|
@ -1,5 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class ExplicitDefaultConfigMismatch(AppConfig):
|
|
||||||
name = 'apps.explicit_default_config_mismatch_app'
|
|
|
@ -1,7 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
default_app_config = 'apps.explicit_default_config_without_apps.ExplicitDefaultConfigWithoutApps'
|
|
||||||
|
|
||||||
|
|
||||||
class ExplicitDefaultConfigWithoutApps(AppConfig):
|
|
||||||
name = 'apps.explicit_default_config_without_apps'
|
|
|
@ -5,18 +5,9 @@ from django.apps.registry import Apps
|
||||||
from django.contrib.admin.models import LogEntry
|
from django.contrib.admin.models import LogEntry
|
||||||
from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured
|
from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import SimpleTestCase, ignore_warnings, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
from django.test.utils import extend_sys_path, isolate_apps
|
from django.test.utils import extend_sys_path, isolate_apps
|
||||||
from django.utils.deprecation import RemovedInDjango41Warning
|
|
||||||
|
|
||||||
from .explicit_default_config_app.apps import ExplicitDefaultConfig
|
|
||||||
from .explicit_default_config_empty_apps import ExplicitDefaultConfigEmptyApps
|
|
||||||
from .explicit_default_config_mismatch_app.not_apps import (
|
|
||||||
ExplicitDefaultConfigMismatch,
|
|
||||||
)
|
|
||||||
from .explicit_default_config_without_apps import (
|
|
||||||
ExplicitDefaultConfigWithoutApps,
|
|
||||||
)
|
|
||||||
from .models import SoAlternative, TotallyNormal, new_apps
|
from .models import SoAlternative, TotallyNormal, new_apps
|
||||||
from .one_config_app.apps import OneConfig
|
from .one_config_app.apps import OneConfig
|
||||||
from .two_configs_one_default_app.apps import TwoConfig
|
from .two_configs_one_default_app.apps import TwoConfig
|
||||||
|
@ -511,106 +502,3 @@ class NamespacePackageAppTests(SimpleTestCase):
|
||||||
with self.settings(INSTALLED_APPS=['nsapp.apps.NSAppConfig']):
|
with self.settings(INSTALLED_APPS=['nsapp.apps.NSAppConfig']):
|
||||||
app_config = apps.get_app_config('nsapp')
|
app_config = apps.get_app_config('nsapp')
|
||||||
self.assertEqual(app_config.path, self.app_path)
|
self.assertEqual(app_config.path, self.app_path)
|
||||||
|
|
||||||
|
|
||||||
class DeprecationTests(SimpleTestCase):
|
|
||||||
@ignore_warnings(category=RemovedInDjango41Warning)
|
|
||||||
def test_explicit_default_app_config(self):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_app']):
|
|
||||||
config = apps.get_app_config('explicit_default_config_app')
|
|
||||||
self.assertIsInstance(config, ExplicitDefaultConfig)
|
|
||||||
|
|
||||||
def test_explicit_default_app_config_warning(self):
|
|
||||||
"""
|
|
||||||
Load an app that specifies a default AppConfig class matching the
|
|
||||||
autodetected one.
|
|
||||||
"""
|
|
||||||
msg = (
|
|
||||||
"'apps.explicit_default_config_app' defines default_app_config = "
|
|
||||||
"'apps.explicit_default_config_app.apps.ExplicitDefaultConfig'. "
|
|
||||||
"Django now detects this configuration automatically. You can "
|
|
||||||
"remove default_app_config."
|
|
||||||
)
|
|
||||||
with self.assertRaisesMessage(RemovedInDjango41Warning, msg):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_app']):
|
|
||||||
pass
|
|
||||||
with ignore_warnings(category=RemovedInDjango41Warning):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_app']):
|
|
||||||
self.assertIsInstance(
|
|
||||||
apps.get_app_config('explicit_default_config_app'),
|
|
||||||
ExplicitDefaultConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_explicit_default_app_config_mismatch(self):
|
|
||||||
"""
|
|
||||||
Load an app that specifies a default AppConfig class not matching the
|
|
||||||
autodetected one.
|
|
||||||
"""
|
|
||||||
msg = (
|
|
||||||
"'apps.explicit_default_config_mismatch_app' defines "
|
|
||||||
"default_app_config = 'apps.explicit_default_config_mismatch_app."
|
|
||||||
"not_apps.ExplicitDefaultConfigMismatch'. However, Django's "
|
|
||||||
"automatic detection picked another configuration, 'apps."
|
|
||||||
"explicit_default_config_mismatch_app.apps."
|
|
||||||
"ImplicitDefaultConfigMismatch'. You should move the default "
|
|
||||||
"config class to the apps submodule of your application and, if "
|
|
||||||
"this module defines several config classes, mark the default one "
|
|
||||||
"with default = True."
|
|
||||||
)
|
|
||||||
with self.assertRaisesMessage(RemovedInDjango41Warning, msg):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_mismatch_app']):
|
|
||||||
pass
|
|
||||||
with ignore_warnings(category=RemovedInDjango41Warning):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_mismatch_app']):
|
|
||||||
self.assertIsInstance(
|
|
||||||
apps.get_app_config('explicit_default_config_mismatch_app'),
|
|
||||||
ExplicitDefaultConfigMismatch,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_explicit_default_app_config_empty_apps(self):
|
|
||||||
"""
|
|
||||||
Load an app that specifies a default AppConfig class in __init__ and
|
|
||||||
have an empty apps module.
|
|
||||||
"""
|
|
||||||
msg = (
|
|
||||||
"'apps.explicit_default_config_empty_apps' defines "
|
|
||||||
"default_app_config = 'apps.explicit_default_config_empty_apps."
|
|
||||||
"ExplicitDefaultConfigEmptyApps'. However, Django's automatic "
|
|
||||||
"detection did not find this configuration. You should move the "
|
|
||||||
"default config class to the apps submodule of your application "
|
|
||||||
"and, if this module defines several config classes, mark the "
|
|
||||||
"default one with default = True."
|
|
||||||
)
|
|
||||||
with self.assertRaisesMessage(RemovedInDjango41Warning, msg):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_empty_apps']):
|
|
||||||
pass
|
|
||||||
with ignore_warnings(category=RemovedInDjango41Warning):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_empty_apps']):
|
|
||||||
self.assertIsInstance(
|
|
||||||
apps.get_app_config('explicit_default_config_empty_apps'),
|
|
||||||
ExplicitDefaultConfigEmptyApps,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_explicit_default_app_config_without_apps(self):
|
|
||||||
"""
|
|
||||||
Load an app that specifies a default AppConfig class in __init__ and do
|
|
||||||
not have an apps module.
|
|
||||||
"""
|
|
||||||
msg = (
|
|
||||||
"'apps.explicit_default_config_without_apps' defines "
|
|
||||||
"default_app_config = 'apps.explicit_default_config_without_apps."
|
|
||||||
"ExplicitDefaultConfigWithoutApps'. However, Django's automatic "
|
|
||||||
"detection did not find this configuration. You should move the "
|
|
||||||
"default config class to the apps submodule of your application "
|
|
||||||
"and, if this module defines several config classes, mark the "
|
|
||||||
"default one with default = True."
|
|
||||||
)
|
|
||||||
with self.assertRaisesMessage(RemovedInDjango41Warning, msg):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_without_apps']):
|
|
||||||
pass
|
|
||||||
with ignore_warnings(category=RemovedInDjango41Warning):
|
|
||||||
with self.settings(INSTALLED_APPS=['apps.explicit_default_config_without_apps']):
|
|
||||||
self.assertIsInstance(
|
|
||||||
apps.get_app_config('explicit_default_config_without_apps'),
|
|
||||||
ExplicitDefaultConfigWithoutApps,
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in New Issue