-
diff --git a/django/conf/__init__.py b/django/conf/__init__.py
index bbcc16e..395db12 100644
a
|
b
|
from django.conf import global_settings
|
15 | 15 | from django.core.exceptions import ImproperlyConfigured |
16 | 16 | from django.utils.functional import LazyObject, empty |
17 | 17 | from django.utils import importlib |
| 18 | from django.utils.module_loading import import_module_from_path |
18 | 19 | from django.utils import six |
19 | 20 | |
20 | 21 | ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" |
… |
… |
class LazySettings(LazyObject):
|
68 | 69 | if self.LOGGING_CONFIG: |
69 | 70 | from django.utils.log import DEFAULT_LOGGING |
70 | 71 | # First find the logging configuration function ... |
71 | | logging_config_path, logging_config_func_name = self.LOGGING_CONFIG.rsplit('.', 1) |
72 | | logging_config_module = importlib.import_module(logging_config_path) |
73 | | logging_config_func = getattr(logging_config_module, logging_config_func_name) |
| 72 | logging_config_func = import_module_from_path(self.LOGGING_CONFIG) |
74 | 73 | |
75 | 74 | logging_config_func(DEFAULT_LOGGING) |
76 | 75 | |
-
diff --git a/django/contrib/admin/tests.py b/django/contrib/admin/tests.py
index 7c62c1a..9f20e59 100644
a
|
b
|
|
1 | 1 | from django.test import LiveServerTestCase |
2 | | from django.utils.importlib import import_module |
| 2 | from django.utils.module_loading import import_module_from_path |
3 | 3 | from django.utils.unittest import SkipTest |
4 | 4 | from django.utils.translation import ugettext as _ |
5 | 5 | |
… |
… |
class AdminSeleniumWebDriverTestCase(LiveServerTestCase):
|
9 | 9 | @classmethod |
10 | 10 | def setUpClass(cls): |
11 | 11 | try: |
12 | | # Import and start the WebDriver class. |
13 | | module, attr = cls.webdriver_class.rsplit('.', 1) |
14 | | mod = import_module(module) |
15 | | WebDriver = getattr(mod, attr) |
16 | | cls.selenium = WebDriver() |
| 12 | cls.selenium = import_module_from_path(cls.webdriver_class)() |
17 | 13 | except Exception as e: |
18 | 14 | raise SkipTest('Selenium webdriver "%s" not installed or not ' |
19 | 15 | 'operational: %s' % (cls.webdriver_class, str(e))) |
-
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
index 99348d3..e3b6796 100644
a
|
b
|
|
1 | 1 | import re |
2 | 2 | |
3 | | from django.core.exceptions import ImproperlyConfigured, PermissionDenied |
4 | | from django.utils.importlib import import_module |
5 | 3 | from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed |
| 4 | from django.core.exceptions import ImproperlyConfigured, PermissionDenied |
| 5 | from django.utils.module_loading import import_module_from_path |
6 | 6 | |
7 | 7 | SESSION_KEY = '_auth_user_id' |
8 | 8 | BACKEND_SESSION_KEY = '_auth_user_backend' |
… |
… |
REDIRECT_FIELD_NAME = 'next'
|
10 | 10 | |
11 | 11 | |
12 | 12 | def load_backend(path): |
13 | | i = path.rfind('.') |
14 | | module, attr = path[:i], path[i + 1:] |
15 | | try: |
16 | | mod = import_module(module) |
17 | | except ImportError as e: |
18 | | raise ImproperlyConfigured('Error importing authentication backend %s: "%s"' % (path, e)) |
19 | | except ValueError: |
20 | | raise ImproperlyConfigured('Error importing authentication backends. Is AUTHENTICATION_BACKENDS a correctly defined list or tuple?') |
21 | | try: |
22 | | cls = getattr(mod, attr) |
23 | | except AttributeError: |
24 | | raise ImproperlyConfigured('Module "%s" does not define a "%s" authentication backend' % (module, attr)) |
25 | | return cls() |
| 13 | return import_module_from_path(path)() |
26 | 14 | |
27 | 15 | |
28 | 16 | def get_backends(): |
-
diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py
index 0fd9144..e14de82 100644
a
|
b
|
from django.utils.encoding import force_bytes, force_str
|
12 | 12 | from django.core.exceptions import ImproperlyConfigured |
13 | 13 | from django.utils.crypto import ( |
14 | 14 | pbkdf2, constant_time_compare, get_random_string) |
| 15 | from django.utils.module_loading import import_module_from_path |
15 | 16 | from django.utils.translation import ugettext_noop as _ |
16 | 17 | |
17 | 18 | |
… |
… |
def load_hashers(password_hashers=None):
|
84 | 85 | if not password_hashers: |
85 | 86 | password_hashers = settings.PASSWORD_HASHERS |
86 | 87 | for backend in password_hashers: |
87 | | try: |
88 | | mod_path, cls_name = backend.rsplit('.', 1) |
89 | | mod = importlib.import_module(mod_path) |
90 | | hasher_cls = getattr(mod, cls_name) |
91 | | except (AttributeError, ImportError, ValueError): |
92 | | raise ImproperlyConfigured("hasher not found: %s" % backend) |
93 | | hasher = hasher_cls() |
| 88 | hasher = import_module_from_path(backend)() |
94 | 89 | if not getattr(hasher, 'algorithm'): |
95 | 90 | raise ImproperlyConfigured("hasher doesn't specify an " |
96 | 91 | "algorithm name: %s" % backend) |
-
diff --git a/django/contrib/formtools/tests/wizard/loadstorage.py b/django/contrib/formtools/tests/wizard/loadstorage.py
index 267dee0..bb0b06e 100644
a
|
b
|
|
1 | 1 | from django.test import TestCase |
2 | 2 | |
3 | | from django.contrib.formtools.wizard.storage import (get_storage, |
4 | | MissingStorageModule, |
5 | | MissingStorageClass) |
| 3 | from django.contrib.formtools.wizard.storage import get_storage, MissingStorage |
6 | 4 | from django.contrib.formtools.wizard.storage.base import BaseStorage |
7 | 5 | |
8 | 6 | |
… |
… |
class TestLoadStorage(TestCase):
|
12 | 10 | type(get_storage('django.contrib.formtools.wizard.storage.base.BaseStorage', 'wizard1')), |
13 | 11 | BaseStorage) |
14 | 12 | |
15 | | def test_missing_module(self): |
16 | | self.assertRaises(MissingStorageModule, get_storage, |
| 13 | def test_missing_storage(self): |
| 14 | self.assertRaises(MissingStorage, get_storage, |
17 | 15 | 'django.contrib.formtools.wizard.storage.idontexist.IDontExistStorage', 'wizard1') |
18 | | |
19 | | def test_missing_class(self): |
20 | | self.assertRaises(MissingStorageClass, get_storage, |
| 16 | self.assertRaises(MissingStorage, get_storage, |
21 | 17 | 'django.contrib.formtools.wizard.storage.base.IDontExistStorage', 'wizard1') |
22 | 18 | |
-
diff --git a/django/contrib/formtools/wizard/storage/__init__.py b/django/contrib/formtools/wizard/storage/__init__.py
index f2293c9..b30d1dc 100644
a
|
b
|
|
1 | | from django.utils.importlib import import_module |
| 1 | from django.core.exceptions import ImproperlyConfigured |
| 2 | from django.utils.module_loading import import_module_from_path |
2 | 3 | |
3 | 4 | from django.contrib.formtools.wizard.storage.base import BaseStorage |
4 | 5 | from django.contrib.formtools.wizard.storage.exceptions import ( |
5 | | MissingStorageModule, MissingStorageClass, NoFileStorageConfigured) |
| 6 | MissingStorage, NoFileStorageConfigured) |
6 | 7 | |
7 | 8 | |
8 | 9 | def get_storage(path, *args, **kwargs): |
9 | | i = path.rfind('.') |
10 | | module, attr = path[:i], path[i+1:] |
11 | 10 | try: |
12 | | mod = import_module(module) |
13 | | except ImportError as e: |
14 | | raise MissingStorageModule( |
15 | | 'Error loading storage %s: "%s"' % (module, e)) |
16 | | try: |
17 | | storage_class = getattr(mod, attr) |
18 | | except AttributeError: |
19 | | raise MissingStorageClass( |
20 | | 'Module "%s" does not define a storage named "%s"' % (module, attr)) |
| 11 | storage_class = import_module_from_path(path) |
| 12 | except ImproperlyConfigured as e: |
| 13 | raise MissingStorage('Error loading storage: %s' % e) |
21 | 14 | return storage_class(*args, **kwargs) |
22 | | |
-
diff --git a/django/contrib/formtools/wizard/storage/exceptions.py b/django/contrib/formtools/wizard/storage/exceptions.py
index eab9030..e273a86 100644
a
|
b
|
|
1 | 1 | from django.core.exceptions import ImproperlyConfigured |
2 | 2 | |
3 | | class MissingStorageModule(ImproperlyConfigured): |
4 | | pass |
5 | | |
6 | | class MissingStorageClass(ImproperlyConfigured): |
| 3 | class MissingStorage(ImproperlyConfigured): |
7 | 4 | pass |
8 | 5 | |
9 | 6 | class NoFileStorageConfigured(ImproperlyConfigured): |
-
diff --git a/django/contrib/messages/storage/__init__.py b/django/contrib/messages/storage/__init__.py
index a584acc..8f3142b 100644
a
|
b
|
|
1 | 1 | from django.conf import settings |
2 | | from django.core.exceptions import ImproperlyConfigured |
3 | | from django.utils.importlib import import_module |
4 | | |
5 | | |
6 | | def get_storage(import_path): |
7 | | """ |
8 | | Imports the message storage class described by import_path, where |
9 | | import_path is the full Python path to the class. |
10 | | """ |
11 | | try: |
12 | | dot = import_path.rindex('.') |
13 | | except ValueError: |
14 | | raise ImproperlyConfigured("%s isn't a Python path." % import_path) |
15 | | module, classname = import_path[:dot], import_path[dot + 1:] |
16 | | try: |
17 | | mod = import_module(module) |
18 | | except ImportError as e: |
19 | | raise ImproperlyConfigured('Error importing module %s: "%s"' % |
20 | | (module, e)) |
21 | | try: |
22 | | return getattr(mod, classname) |
23 | | except AttributeError: |
24 | | raise ImproperlyConfigured('Module "%s" does not define a "%s" ' |
25 | | 'class.' % (module, classname)) |
| 2 | from django.utils.module_loading import import_module_from_path as get_storage |
26 | 3 | |
27 | 4 | |
28 | 5 | # Callable with the same interface as the storage classes i.e. accepts a |
-
diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py
index 9b06c2c..685376e 100644
a
|
b
|
from django.core.exceptions import ImproperlyConfigured
|
4 | 4 | from django.core.files.storage import default_storage, Storage, FileSystemStorage |
5 | 5 | from django.utils.datastructures import SortedDict |
6 | 6 | from django.utils.functional import empty, memoize, LazyObject |
7 | | from django.utils.importlib import import_module |
| 7 | from django.utils.module_loading import import_module_from_path |
8 | 8 | from django.utils._os import safe_join |
9 | 9 | from django.utils import six |
10 | 10 | |
… |
… |
def _get_finder(import_path):
|
258 | 258 | Imports the staticfiles finder class described by import_path, where |
259 | 259 | import_path is the full Python path to the class. |
260 | 260 | """ |
261 | | module, attr = import_path.rsplit('.', 1) |
262 | | try: |
263 | | mod = import_module(module) |
264 | | except ImportError as e: |
265 | | raise ImproperlyConfigured('Error importing module %s: "%s"' % |
266 | | (module, e)) |
267 | | try: |
268 | | Finder = getattr(mod, attr) |
269 | | except AttributeError: |
270 | | raise ImproperlyConfigured('Module "%s" does not define a "%s" ' |
271 | | 'class.' % (module, attr)) |
| 261 | Finder = import_module_from_path(import_path) |
272 | 262 | if not issubclass(Finder, BaseFinder): |
273 | 263 | raise ImproperlyConfigured('Finder "%s" is not a subclass of "%s"' % |
274 | 264 | (Finder, BaseFinder)) |
-
diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py
index 562bcc2..d3a84fc 100644
a
|
b
|
from django.core.cache.backends.base import (
|
25 | 25 | InvalidCacheBackendError, CacheKeyWarning, BaseCache) |
26 | 26 | from django.core.exceptions import ImproperlyConfigured |
27 | 27 | from django.utils import importlib |
| 28 | from django.utils.module_loading import import_module_from_path |
| 29 | |
28 | 30 | |
29 | 31 | __all__ = [ |
30 | 32 | 'get_cache', 'cache', 'DEFAULT_CACHE_ALIAS' |
… |
… |
def parse_backend_conf(backend, **kwargs):
|
86 | 88 | else: |
87 | 89 | try: |
88 | 90 | # Trying to import the given backend, in case it's a dotted path |
89 | | mod_path, cls_name = backend.rsplit('.', 1) |
90 | | mod = importlib.import_module(mod_path) |
91 | | backend_cls = getattr(mod, cls_name) |
92 | | except (AttributeError, ImportError, ValueError): |
93 | | raise InvalidCacheBackendError("Could not find backend '%s'" % backend) |
| 91 | backend_cls = import_module_from_path(backend) |
| 92 | except ImproperlyConfigured as e: |
| 93 | raise InvalidCacheBackendError("Could not find backend '%s': %s" % ( |
| 94 | backend, e)) |
94 | 95 | location = kwargs.pop('LOCATION', '') |
95 | 96 | return backend, location, kwargs |
96 | 97 | |
… |
… |
def get_cache(backend, **kwargs):
|
126 | 127 | backend_cls = mod.CacheClass |
127 | 128 | else: |
128 | 129 | backend, location, params = parse_backend_conf(backend, **kwargs) |
129 | | mod_path, cls_name = backend.rsplit('.', 1) |
130 | | mod = importlib.import_module(mod_path) |
131 | | backend_cls = getattr(mod, cls_name) |
132 | | except (AttributeError, ImportError) as e: |
| 130 | backend_cls = import_module_from_path(backend) |
| 131 | except (AttributeError, ImportError, ImproperlyConfigured) as e: |
133 | 132 | raise InvalidCacheBackendError( |
134 | 133 | "Could not find backend '%s': %s" % (backend, e)) |
135 | 134 | cache = backend_cls(location, params) |
-
diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py
index 7234d3c..20c2993 100644
a
|
b
|
from __future__ import unicode_literals
|
4 | 4 | import warnings |
5 | 5 | |
6 | 6 | from django.core.exceptions import ImproperlyConfigured, DjangoRuntimeWarning |
7 | | from django.utils.importlib import import_module |
| 7 | from django.utils.module_loading import import_module_from_path |
8 | 8 | |
9 | 9 | |
10 | 10 | class InvalidCacheBackendError(ImproperlyConfigured): |
… |
… |
def get_key_func(key_func):
|
40 | 40 | if callable(key_func): |
41 | 41 | return key_func |
42 | 42 | else: |
43 | | key_func_module_path, key_func_name = key_func.rsplit('.', 1) |
44 | | key_func_module = import_module(key_func_module_path) |
45 | | return getattr(key_func_module, key_func_name) |
| 43 | return import_module_from_path(key_func) |
46 | 44 | return default_key_func |
47 | 45 | |
48 | 46 | |
-
diff --git a/django/core/files/storage.py b/django/core/files/storage.py
index 650373f..2e3f809 100644
a
|
b
|
import itertools
|
8 | 8 | from datetime import datetime |
9 | 9 | |
10 | 10 | from django.conf import settings |
11 | | from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation |
| 11 | from django.core.exceptions import SuspiciousOperation |
12 | 12 | from django.core.files import locks, File |
13 | 13 | from django.core.files.move import file_move_safe |
14 | 14 | from django.utils.encoding import force_text, filepath_to_uri |
15 | 15 | from django.utils.functional import LazyObject |
16 | | from django.utils.importlib import import_module |
| 16 | from django.utils.module_loading import import_module_from_path |
17 | 17 | from django.utils.text import get_valid_filename |
18 | 18 | from django.utils._os import safe_join, abspathu |
19 | 19 | |
… |
… |
class FileSystemStorage(Storage):
|
277 | 277 | return datetime.fromtimestamp(os.path.getmtime(self.path(name))) |
278 | 278 | |
279 | 279 | def get_storage_class(import_path=None): |
280 | | if import_path is None: |
281 | | import_path = settings.DEFAULT_FILE_STORAGE |
282 | | try: |
283 | | dot = import_path.rindex('.') |
284 | | except ValueError: |
285 | | raise ImproperlyConfigured("%s isn't a storage module." % import_path) |
286 | | module, classname = import_path[:dot], import_path[dot+1:] |
287 | | try: |
288 | | mod = import_module(module) |
289 | | except ImportError as e: |
290 | | raise ImproperlyConfigured('Error importing storage module %s: "%s"' % (module, e)) |
291 | | try: |
292 | | return getattr(mod, classname) |
293 | | except AttributeError: |
294 | | raise ImproperlyConfigured('Storage module "%s" does not define a "%s" class.' % (module, classname)) |
| 280 | return import_module_from_path(import_path or settings.DEFAULT_FILE_STORAGE) |
295 | 281 | |
296 | 282 | class DefaultStorage(LazyObject): |
297 | 283 | def _setup(self): |
-
diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py
index c422945..c3b7ec9 100644
a
|
b
|
from __future__ import unicode_literals
|
7 | 7 | from io import BytesIO |
8 | 8 | |
9 | 9 | from django.conf import settings |
10 | | from django.core.exceptions import ImproperlyConfigured |
11 | 10 | from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile |
12 | | from django.utils import importlib |
13 | 11 | from django.utils.encoding import python_2_unicode_compatible |
| 12 | from django.utils.module_loading import import_module_from_path |
14 | 13 | |
15 | 14 | __all__ = ['UploadFileException','StopUpload', 'SkipFile', 'FileUploadHandler', |
16 | 15 | 'TemporaryFileUploadHandler', 'MemoryFileUploadHandler', |
… |
… |
def load_handler(path, *args, **kwargs):
|
201 | 200 | <TemporaryFileUploadHandler object at 0x...> |
202 | 201 | |
203 | 202 | """ |
204 | | i = path.rfind('.') |
205 | | module, attr = path[:i], path[i+1:] |
206 | | try: |
207 | | mod = importlib.import_module(module) |
208 | | except ImportError as e: |
209 | | raise ImproperlyConfigured('Error importing upload handler module %s: "%s"' % (module, e)) |
210 | | except ValueError: |
211 | | raise ImproperlyConfigured('Error importing upload handler module.' |
212 | | 'Is FILE_UPLOAD_HANDLERS a correctly defined list or tuple?') |
213 | | try: |
214 | | cls = getattr(mod, attr) |
215 | | except AttributeError: |
216 | | raise ImproperlyConfigured('Module "%s" does not define a "%s" upload handler backend' % (module, attr)) |
217 | | return cls(*args, **kwargs) |
| 203 | return import_module_from_path(path)(*args, **kwargs) |
-
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index 0239475..2a49263 100644
a
|
b
|
from django.conf import settings
|
9 | 9 | from django.core import exceptions |
10 | 10 | from django.core import urlresolvers |
11 | 11 | from django.core import signals |
| 12 | from django.core.exceptions import MiddlewareNotUsed, PermissionDenied |
12 | 13 | from django.utils.encoding import force_text |
13 | | from django.utils.importlib import import_module |
| 14 | from django.utils.module_loading import import_module_from_path |
14 | 15 | from django.utils import six |
15 | 16 | from django.views import debug |
16 | 17 | |
… |
… |
class BaseHandler(object):
|
43 | 44 | |
44 | 45 | request_middleware = [] |
45 | 46 | for middleware_path in settings.MIDDLEWARE_CLASSES: |
46 | | try: |
47 | | mw_module, mw_classname = middleware_path.rsplit('.', 1) |
48 | | except ValueError: |
49 | | raise exceptions.ImproperlyConfigured('%s isn\'t a middleware module' % middleware_path) |
50 | | try: |
51 | | mod = import_module(mw_module) |
52 | | except ImportError as e: |
53 | | raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e)) |
54 | | try: |
55 | | mw_class = getattr(mod, mw_classname) |
56 | | except AttributeError: |
57 | | raise exceptions.ImproperlyConfigured('Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)) |
| 47 | mw_class = import_module_from_path(middleware_path) |
58 | 48 | try: |
59 | 49 | mw_instance = mw_class() |
60 | | except exceptions.MiddlewareNotUsed: |
| 50 | except MiddlewareNotUsed: |
61 | 51 | continue |
62 | 52 | |
63 | 53 | if hasattr(mw_instance, 'process_request'): |
… |
… |
class BaseHandler(object):
|
154 | 144 | except: |
155 | 145 | signals.got_request_exception.send(sender=self.__class__, request=request) |
156 | 146 | response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) |
157 | | except exceptions.PermissionDenied: |
| 147 | except PermissionDenied: |
158 | 148 | logger.warning( |
159 | 149 | 'Forbidden (Permission denied): %s', request.path, |
160 | 150 | extra={ |
-
diff --git a/django/core/mail/__init__.py b/django/core/mail/__init__.py
index 08f9702..51b9bf9 100644
a
|
b
|
Tools for sending email.
|
4 | 4 | from __future__ import unicode_literals |
5 | 5 | |
6 | 6 | from django.conf import settings |
7 | | from django.core.exceptions import ImproperlyConfigured |
8 | | from django.utils.importlib import import_module |
| 7 | from django.utils.module_loading import import_module_from_path |
9 | 8 | |
10 | 9 | # Imported for backwards compatibility, and for the sake |
11 | 10 | # of a cleaner namespace. These symbols used to be in |
… |
… |
def get_connection(backend=None, fail_silently=False, **kwds):
|
27 | 26 | Both fail_silently and other keyword arguments are used in the |
28 | 27 | constructor of the backend. |
29 | 28 | """ |
30 | | path = backend or settings.EMAIL_BACKEND |
31 | | try: |
32 | | mod_name, klass_name = path.rsplit('.', 1) |
33 | | mod = import_module(mod_name) |
34 | | except ImportError as e: |
35 | | raise ImproperlyConfigured(('Error importing email backend module %s: "%s"' |
36 | | % (mod_name, e))) |
37 | | try: |
38 | | klass = getattr(mod, klass_name) |
39 | | except AttributeError: |
40 | | raise ImproperlyConfigured(('Module "%s" does not define a ' |
41 | | '"%s" class' % (mod_name, klass_name))) |
| 29 | klass = import_module_from_path(backend or settings.EMAIL_BACKEND) |
42 | 30 | return klass(fail_silently=fail_silently, **kwds) |
43 | 31 | |
44 | 32 | |
-
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
index 68ca0c1..f4bd74b 100644
a
|
b
|
from django.utils.six.moves import socketserver
|
21 | 21 | from wsgiref import simple_server |
22 | 22 | from wsgiref.util import FileWrapper # for backwards compatibility |
23 | 23 | |
24 | | import django |
25 | | from django.core.exceptions import ImproperlyConfigured |
26 | 24 | from django.core.management.color import color_style |
27 | 25 | from django.core.wsgi import get_wsgi_application |
28 | | from django.utils.importlib import import_module |
| 26 | from django.utils.module_loading import import_module_from_path |
29 | 27 | |
30 | 28 | __all__ = ['WSGIServer', 'WSGIRequestHandler'] |
31 | 29 | |
… |
… |
def get_internal_wsgi_application():
|
49 | 47 | app_path = getattr(settings, 'WSGI_APPLICATION') |
50 | 48 | if app_path is None: |
51 | 49 | return get_wsgi_application() |
52 | | module_name, attr = app_path.rsplit('.', 1) |
53 | | try: |
54 | | mod = import_module(module_name) |
55 | | except ImportError as e: |
56 | | raise ImproperlyConfigured( |
57 | | "WSGI application '%s' could not be loaded; " |
58 | | "could not import module '%s': %s" % (app_path, module_name, e)) |
59 | | try: |
60 | | app = getattr(mod, attr) |
61 | | except AttributeError as e: |
62 | | raise ImproperlyConfigured( |
63 | | "WSGI application '%s' could not be loaded; " |
64 | | "can't find '%s' in module '%s': %s" |
65 | | % (app_path, attr, module_name, e)) |
66 | | |
67 | | return app |
| 50 | |
| 51 | return import_module_from_path( |
| 52 | app_path, |
| 53 | error_prefix="WSGI application '%s' could not be loaded; " % app_path |
| 54 | ) |
68 | 55 | |
69 | 56 | |
70 | 57 | class WSGIServerException(Exception): |
-
diff --git a/django/core/signing.py b/django/core/signing.py
index 92ab968..67c2770 100644
a
|
b
|
import time
|
41 | 41 | import zlib |
42 | 42 | |
43 | 43 | from django.conf import settings |
44 | | from django.core.exceptions import ImproperlyConfigured |
45 | 44 | from django.utils import baseconv |
46 | 45 | from django.utils.crypto import constant_time_compare, salted_hmac |
47 | 46 | from django.utils.encoding import force_bytes, force_str, force_text |
48 | | from django.utils.importlib import import_module |
| 47 | from django.utils.module_loading import import_module_from_path |
49 | 48 | |
50 | 49 | |
51 | 50 | class BadSignature(Exception): |
… |
… |
def base64_hmac(salt, value, key):
|
76 | 75 | |
77 | 76 | |
78 | 77 | def get_cookie_signer(salt='django.core.signing.get_cookie_signer'): |
79 | | modpath = settings.SIGNING_BACKEND |
80 | | module, attr = modpath.rsplit('.', 1) |
81 | | try: |
82 | | mod = import_module(module) |
83 | | except ImportError as e: |
84 | | raise ImproperlyConfigured( |
85 | | 'Error importing cookie signer %s: "%s"' % (modpath, e)) |
86 | | try: |
87 | | Signer = getattr(mod, attr) |
88 | | except AttributeError as e: |
89 | | raise ImproperlyConfigured( |
90 | | 'Error importing cookie signer %s: "%s"' % (modpath, e)) |
| 78 | Signer = import_module_from_path(settings.SIGNING_BACKEND) |
91 | 79 | return Signer('django.http.cookies' + settings.SECRET_KEY, salt=salt) |
92 | 80 | |
93 | 81 | |
-
diff --git a/django/db/utils.py b/django/db/utils.py
index 842fd35..8c34b77 100644
a
|
b
|
from threading import local
|
5 | 5 | from django.conf import settings |
6 | 6 | from django.core.exceptions import ImproperlyConfigured |
7 | 7 | from django.utils.importlib import import_module |
| 8 | from django.utils.module_loading import import_module_from_path |
8 | 9 | from django.utils._os import upath |
9 | 10 | from django.utils import six |
10 | 11 | |
… |
… |
class ConnectionRouter(object):
|
110 | 111 | self.routers = [] |
111 | 112 | for r in routers: |
112 | 113 | if isinstance(r, six.string_types): |
113 | | try: |
114 | | module_name, klass_name = r.rsplit('.', 1) |
115 | | module = import_module(module_name) |
116 | | except ImportError as e: |
117 | | raise ImproperlyConfigured('Error importing database router %s: "%s"' % (klass_name, e)) |
118 | | try: |
119 | | router_class = getattr(module, klass_name) |
120 | | except AttributeError: |
121 | | raise ImproperlyConfigured('Module "%s" does not define a database router name "%s"' % (module, klass_name)) |
122 | | else: |
123 | | router = router_class() |
| 114 | router = import_module_from_path(r)() |
124 | 115 | else: |
125 | 116 | router = r |
126 | 117 | self.routers.append(router) |
-
diff --git a/django/template/context.py b/django/template/context.py
index 81aa194..9b7dc93 100644
a
|
b
|
|
1 | 1 | from copy import copy |
2 | | from django.core.exceptions import ImproperlyConfigured |
3 | | from django.utils.importlib import import_module |
| 2 | from django.utils.module_loading import import_module_from_path |
4 | 3 | |
5 | 4 | # Cache of actual callables. |
6 | 5 | _standard_context_processors = None |
… |
… |
def get_standard_processors():
|
146 | 145 | collect.extend(_builtin_context_processors) |
147 | 146 | collect.extend(settings.TEMPLATE_CONTEXT_PROCESSORS) |
148 | 147 | for path in collect: |
149 | | i = path.rfind('.') |
150 | | module, attr = path[:i], path[i+1:] |
151 | | try: |
152 | | mod = import_module(module) |
153 | | except ImportError as e: |
154 | | raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e)) |
155 | | try: |
156 | | func = getattr(mod, attr) |
157 | | except AttributeError: |
158 | | raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr)) |
| 148 | func = import_module_from_path(path) |
159 | 149 | processors.append(func) |
160 | 150 | _standard_context_processors = tuple(processors) |
161 | 151 | return _standard_context_processors |
-
diff --git a/django/template/loader.py b/django/template/loader.py
index cfffb40..8678164 100644
a
|
b
|
|
27 | 27 | |
28 | 28 | from django.core.exceptions import ImproperlyConfigured |
29 | 29 | from django.template.base import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins |
30 | | from django.utils.importlib import import_module |
31 | 30 | from django.conf import settings |
| 31 | from django.utils.module_loading import import_module_from_path |
32 | 32 | from django.utils import six |
33 | 33 | |
34 | 34 | template_source_loaders = None |
… |
… |
def find_template_loader(loader):
|
91 | 91 | else: |
92 | 92 | args = [] |
93 | 93 | if isinstance(loader, six.string_types): |
94 | | module, attr = loader.rsplit('.', 1) |
95 | | try: |
96 | | mod = import_module(module) |
97 | | except ImportError as e: |
98 | | raise ImproperlyConfigured('Error importing template source loader %s: "%s"' % (loader, e)) |
99 | | try: |
100 | | TemplateLoader = getattr(mod, attr) |
101 | | except AttributeError as e: |
102 | | raise ImproperlyConfigured('Error importing template source loader %s: "%s"' % (loader, e)) |
| 94 | TemplateLoader = import_module_from_path(loader) |
103 | 95 | |
104 | 96 | if hasattr(TemplateLoader, 'load_template_source'): |
105 | 97 | func = TemplateLoader(*args) |
-
diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py
index f8aadb3..e5a8555 100644
a
|
b
|
import imp
|
2 | 2 | import os |
3 | 3 | import sys |
4 | 4 | |
| 5 | from django.core.exceptions import ImproperlyConfigured |
| 6 | from django.utils.importlib import import_module |
| 7 | |
| 8 | |
| 9 | def import_module_from_path(dotted_path, error_prefix=''): |
| 10 | """ |
| 11 | Import a dotted module path and return the attribute/class designated by the |
| 12 | last name in the path. Raise ImproperlyConfigured if something goes wrong. |
| 13 | """ |
| 14 | try: |
| 15 | module_path, class_name = dotted_path.rsplit('.', 1) |
| 16 | except ValueError: |
| 17 | raise ImproperlyConfigured("%s%s doesn't look like a module path" % ( |
| 18 | error_prefix, dotted_path)) |
| 19 | try: |
| 20 | module = import_module(module_path) |
| 21 | except ImportError as e: |
| 22 | raise ImproperlyConfigured('%sError importing module %s: "%s"' % ( |
| 23 | error_prefix, module_path, e)) |
| 24 | try: |
| 25 | attr = getattr(module, class_name) |
| 26 | except AttributeError: |
| 27 | raise ImproperlyConfigured('%sModule "%s" does not define a "%s" attribute/class' % ( |
| 28 | error_prefix, module_path, class_name)) |
| 29 | return attr |
| 30 | |
5 | 31 | |
6 | 32 | def module_has_submodule(package, module_name): |
7 | 33 | """See if 'module' is in 'package'.""" |
-
diff --git a/django/views/debug.py b/django/views/debug.py
index e5f4c70..a586f16 100644
a
|
b
|
from django.http import (HttpResponse, HttpResponseServerError,
|
13 | 13 | from django.template import Template, Context, TemplateDoesNotExist |
14 | 14 | from django.template.defaultfilters import force_escape, pprint |
15 | 15 | from django.utils.html import escape |
16 | | from django.utils.importlib import import_module |
17 | 16 | from django.utils.encoding import force_bytes, smart_text |
| 17 | from django.utils.module_loading import import_module_from_path |
18 | 18 | from django.utils import six |
19 | 19 | |
20 | 20 | HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|PROFANITIES_LIST|SIGNATURE') |
… |
… |
def get_exception_reporter_filter(request):
|
76 | 76 | global default_exception_reporter_filter |
77 | 77 | if default_exception_reporter_filter is None: |
78 | 78 | # Load the default filter for the first time and cache it. |
79 | | modpath = settings.DEFAULT_EXCEPTION_REPORTER_FILTER |
80 | | modname, classname = modpath.rsplit('.', 1) |
81 | | try: |
82 | | mod = import_module(modname) |
83 | | except ImportError as e: |
84 | | raise ImproperlyConfigured( |
85 | | 'Error importing default exception reporter filter %s: "%s"' % (modpath, e)) |
86 | | try: |
87 | | default_exception_reporter_filter = getattr(mod, classname)() |
88 | | except AttributeError: |
89 | | raise ImproperlyConfigured('Default exception reporter filter module "%s" does not define a "%s" class' % (modname, classname)) |
| 79 | default_exception_reporter_filter = import_module_from_path( |
| 80 | settings.DEFAULT_EXCEPTION_REPORTER_FILTER)() |
90 | 81 | if request: |
91 | 82 | return getattr(request, 'exception_reporter_filter', default_exception_reporter_filter) |
92 | 83 | else: |
-
diff --git a/tests/regressiontests/file_storage/tests.py b/tests/regressiontests/file_storage/tests.py
index 4872ce8..6ab7f90 100644
a
|
b
|
class GetStorageClassTests(SimpleTestCase):
|
57 | 57 | """ |
58 | 58 | self.assertRaisesMessage( |
59 | 59 | ImproperlyConfigured, |
60 | | "NonExistingStorage isn't a storage module.", |
| 60 | "Error importing module storage: \"No module named storage\"", |
61 | 61 | get_storage_class, |
62 | | 'NonExistingStorage') |
| 62 | 'storage.NonExistingStorage') |
63 | 63 | |
64 | 64 | def test_get_nonexisting_storage_class(self): |
65 | 65 | """ |
… |
… |
class GetStorageClassTests(SimpleTestCase):
|
67 | 67 | """ |
68 | 68 | self.assertRaisesMessage( |
69 | 69 | ImproperlyConfigured, |
70 | | 'Storage module "django.core.files.storage" does not define a '\ |
71 | | '"NonExistingStorage" class.', |
| 70 | 'Module "django.core.files.storage" does not define a ' |
| 71 | '"NonExistingStorage" attribute/class', |
72 | 72 | get_storage_class, |
73 | 73 | 'django.core.files.storage.NonExistingStorage') |
74 | 74 | |
… |
… |
class GetStorageClassTests(SimpleTestCase):
|
79 | 79 | # Error message may or may not be the fully qualified path. |
80 | 80 | six.assertRaisesRegex(self, |
81 | 81 | ImproperlyConfigured, |
82 | | ('Error importing storage module django.core.files.non_existing_' |
83 | | 'storage: "No module named .*non_existing_storage'), |
| 82 | 'Error importing module django.core.files.non_existing_storage: ' |
| 83 | '"No module named non_existing_storage"', |
84 | 84 | get_storage_class, |
85 | 85 | 'django.core.files.non_existing_storage.NonExistingStorage' |
86 | 86 | ) |
-
diff --git a/tests/regressiontests/utils/module_loading.py b/tests/regressiontests/utils/module_loading.py
index 3fc92b0..2e8df65 100644
a
|
b
|
import sys
|
3 | 3 | import imp |
4 | 4 | from zipimport import zipimporter |
5 | 5 | |
| 6 | from django.core.exceptions import ImproperlyConfigured |
6 | 7 | from django.utils import unittest |
7 | 8 | from django.utils.importlib import import_module |
8 | | from django.utils.module_loading import module_has_submodule |
| 9 | from django.utils.module_loading import import_module_from_path, module_has_submodule |
9 | 10 | from django.utils._os import upath |
10 | 11 | |
11 | 12 | |
… |
… |
class EggLoader(unittest.TestCase):
|
103 | 104 | self.assertFalse(module_has_submodule(egg_module, 'no_such_module')) |
104 | 105 | self.assertRaises(ImportError, import_module, 'egg_module.sub1.sub2.no_such_module') |
105 | 106 | |
| 107 | |
| 108 | class ModuleImportTestCase(unittest.TestCase): |
| 109 | def test_import_from_path(self): |
| 110 | cls = import_module_from_path( |
| 111 | 'django.utils.module_loading.import_module_from_path') |
| 112 | self.assertEqual(cls, import_module_from_path) |
| 113 | |
| 114 | # Test exceptions raised |
| 115 | for path in ('no_dots_in_path', 'unexistent.path', |
| 116 | 'tests.regressiontests.utils.unexistent'): |
| 117 | self.assertRaises(ImproperlyConfigured, import_module_from_path, path) |
| 118 | |
| 119 | with self.assertRaises(ImproperlyConfigured) as cm: |
| 120 | import_module_from_path('unexistent.module.path', error_prefix="Foo") |
| 121 | self.assertTrue(str(cm.exception).startswith('Foo')) |
| 122 | |
| 123 | |
106 | 124 | class ProxyFinder(object): |
107 | 125 | def __init__(self): |
108 | 126 | self._cache = {} |
-
diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py
index 11dd7c3..726df3d 100644
a
|
b
|
from .html import TestUtilsHtml
|
20 | 20 | from .http import TestUtilsHttp, ETagProcessingTests, HttpDateProcessingTests |
21 | 21 | from .ipv6 import TestUtilsIPv6 |
22 | 22 | from .jslex import JsToCForGettextTest, JsTokensTest |
23 | | from .module_loading import CustomLoader, DefaultLoader, EggLoader |
| 23 | from .module_loading import (CustomLoader, DefaultLoader, EggLoader, |
| 24 | ModuleImportTestCase) |
24 | 25 | from .numberformat import TestNumberFormat |
25 | 26 | from .os_utils import SafeJoinTests |
26 | 27 | from .regex_helper import NormalizeTests |
-
diff --git a/tests/regressiontests/wsgi/tests.py b/tests/regressiontests/wsgi/tests.py
index 6c1483d..0b8c9d2 100644
a
|
b
|
class GetInternalWSGIApplicationTest(unittest.TestCase):
|
85 | 85 | def test_bad_module(self): |
86 | 86 | with six.assertRaisesRegex(self, |
87 | 87 | ImproperlyConfigured, |
88 | | r"^WSGI application 'regressiontests.wsgi.noexist.app' could not be loaded; could not import module 'regressiontests.wsgi.noexist':"): |
| 88 | r"^WSGI application 'regressiontests.wsgi.noexist.app' could not be loaded; Error importing.*"): |
89 | 89 | |
90 | 90 | get_internal_wsgi_application() |
91 | 91 | |
… |
… |
class GetInternalWSGIApplicationTest(unittest.TestCase):
|
94 | 94 | def test_bad_name(self): |
95 | 95 | with six.assertRaisesRegex(self, |
96 | 96 | ImproperlyConfigured, |
97 | | r"^WSGI application 'regressiontests.wsgi.wsgi.noexist' could not be loaded; can't find 'noexist' in module 'regressiontests.wsgi.wsgi':"): |
| 97 | r"^WSGI application 'regressiontests.wsgi.wsgi.noexist' could not be loaded; Module.*"): |
98 | 98 | |
99 | 99 | get_internal_wsgi_application() |