summaryrefslogtreecommitdiff
path: root/django/apps
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2013-12-26 19:05:45 +0100
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-12-26 19:25:09 +0100
commitb355e98a5091a76ad4b8657a6a971e7e0595aa26 (patch)
tree0700bc90fe81618ad3522ab20a1b7a4984f86ff5 /django/apps
parentce1bc2c94b30a42a2c7c0d58e6cb6d8875cadf60 (diff)
Normalized exceptions raised by AppConfig.create.
It raises ImportError whenever an entry in INSTALLED_APPS points (directly or indirectly via AppConfig.name) to a non-existing module and ImproperlyConfigured in all other cases. Catching ImportError and re-raising ImproperlyConfigured tends to make circular imports more difficult to diagnose.
Diffstat (limited to 'django/apps')
-rw-r--r--django/apps/base.py21
1 files changed, 16 insertions, 5 deletions
diff --git a/django/apps/base.py b/django/apps/base.py
index 3f9f2d9bcd..4102780560 100644
--- a/django/apps/base.py
+++ b/django/apps/base.py
@@ -1,7 +1,7 @@
from importlib import import_module
from django.core.exceptions import ImproperlyConfigured
-from django.utils.module_loading import import_by_path, module_has_submodule
+from django.utils.module_loading import module_has_submodule
from django.utils._os import upath
@@ -66,13 +66,24 @@ class AppConfig(object):
module = import_module(entry)
except ImportError:
+ # Avoid django.utils.module_loading.import_by_path because it
+ # masks errors -- it reraises ImportError as ImproperlyConfigured.
+ mod_path, _, cls_name = entry.rpartition('.')
+
# Raise the original exception when entry cannot be a path to an
- # app config class. Since module names are allowable here, the
- # standard exception message from import_by_path is unsuitable.
- if '.' not in entry:
+ # app config class.
+ if not mod_path:
raise
- cls = import_by_path(entry)
+ mod = import_module(mod_path)
+ try:
+ cls = getattr(mod, cls_name)
+ except AttributeError:
+ # Emulate the error that "from <mod_path> import <cls_name>"
+ # would raise when <mod_path> exists but not <cls_name>, with
+ # more context (Python just says "cannot import name ...").
+ raise ImportError(
+ "cannot import name %r from %r" % (cls_name, mod_path))
# Check for obvious errors. (This check prevents duck typing, but
# it could be removed if it became a problem in practice.)