1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #29768 -- Improved error message when an AppConfig has a typo in INSTALLED_APPS.

This commit is contained in:
Marten Kenbeek 2018-09-18 18:19:18 +02:00 committed by Tim Graham
parent 2349cbd909
commit 40c8ffad72
2 changed files with 27 additions and 6 deletions

View File

@ -118,8 +118,21 @@ class AppConfig:
cls = getattr(mod, cls_name) cls = getattr(mod, cls_name)
except AttributeError: except AttributeError:
if module is None: if module is None:
# If importing as an app module failed, that error probably # If importing as an app module failed, check if the module
# contains the most informative traceback. Trigger it again. # contains any valid AppConfigs and show them as choices.
# Otherwise, that error probably contains the most informative
# traceback, so trigger it again.
candidates = sorted(
repr(name) for name, candidate in mod.__dict__.items()
if isinstance(candidate, type) and
issubclass(candidate, AppConfig) and
candidate is not AppConfig
)
if candidates:
raise ImproperlyConfigured(
"'%s' does not contain a class '%s'. Choices are: %s."
% (mod_path, cls_name, ', '.join(candidates))
)
import_module(entry) import_module(entry)
else: else:
raise raise

View File

@ -81,10 +81,18 @@ class AppsTests(SimpleTestCase):
pass pass
def test_no_such_app_config(self): def test_no_such_app_config(self):
""" msg = "No module named 'apps.NoSuchConfig'"
Tests when INSTALLED_APPS contains an entry that doesn't exist. with self.assertRaisesMessage(ImportError, msg):
""" with self.settings(INSTALLED_APPS=['apps.NoSuchConfig']):
with self.assertRaises(ImportError): pass
def test_no_such_app_config_with_choices(self):
msg = (
"'apps.apps' does not contain a class 'NoSuchConfig'. Choices are: "
"'BadConfig', 'MyAdmin', 'MyAuth', 'NoSuchApp', 'PlainAppsConfig', "
"'RelabeledAppsConfig'."
)
with self.assertRaisesMessage(ImproperlyConfigured, msg):
with self.settings(INSTALLED_APPS=['apps.apps.NoSuchConfig']): with self.settings(INSTALLED_APPS=['apps.apps.NoSuchConfig']):
pass pass