-
diff --git a/django/conf/__init__.py b/django/conf/__init__.py
index 4e6f0f9..01624c9 100644
a
|
b
|
from django.conf import global_settings
|
14 | 14 | from django.core.exceptions import ImproperlyConfigured |
15 | 15 | from django.utils.functional import LazyObject, empty |
16 | 16 | from django.utils import importlib |
| 17 | from django.utils.module_loading import import_module_from_path |
17 | 18 | from django.utils import six |
18 | 19 | |
19 | 20 | ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" |
… |
… |
class LazySettings(LazyObject):
|
58 | 59 | if self.LOGGING_CONFIG: |
59 | 60 | from django.utils.log import DEFAULT_LOGGING |
60 | 61 | # First find the logging configuration function ... |
61 | | logging_config_path, logging_config_func_name = self.LOGGING_CONFIG.rsplit('.', 1) |
62 | | logging_config_module = importlib.import_module(logging_config_path) |
63 | | logging_config_func = getattr(logging_config_module, logging_config_func_name) |
| 62 | logging_config_func = import_module_from_path(self.LOGGING_CONFIG) |
64 | 63 | |
65 | 64 | logging_config_func(DEFAULT_LOGGING) |
66 | 65 | |
-
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 dd4a848..e6ae03d 100644
a
|
b
|
|
1 | 1 | import re |
2 | 2 | |
3 | | from django.core.exceptions import ImproperlyConfigured |
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 |
| 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 c628059..980cc72 100644
a
|
b
|
from django.utils.encoding import force_bytes
|
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 d1a02a9..bf2be06 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 06e8952..25f3615 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 | class InvalidCacheBackendError(ImproperlyConfigured): |
10 | 10 | pass |
… |
… |
def get_key_func(key_func):
|
35 | 35 | if callable(key_func): |
36 | 36 | return key_func |
37 | 37 | else: |
38 | | key_func_module_path, key_func_name = key_func.rsplit('.', 1) |
39 | | key_func_module = import_module(key_func_module_path) |
40 | | return getattr(key_func_module, key_func_name) |
| 38 | return import_module_from_path(key_func) |
41 | 39 | return default_key_func |
42 | 40 | |
43 | 41 | class BaseCache(object): |
-
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 2357246..da72258 100644
a
|
b
|
import types
|
6 | 6 | |
7 | 7 | from django import http |
8 | 8 | from django.core import signals |
| 9 | from django.core.exceptions import MiddlewareNotUsed, PermissionDenied |
9 | 10 | from django.utils.encoding import force_text |
10 | | from django.utils.importlib import import_module |
| 11 | from django.utils.module_loading import import_module_from_path |
11 | 12 | from django.utils import six |
12 | 13 | |
13 | 14 | logger = logging.getLogger('django.request') |
… |
… |
class BaseHandler(object):
|
33 | 34 | Must be called after the environment is fixed (see __call__ in subclasses). |
34 | 35 | """ |
35 | 36 | from django.conf import settings |
36 | | from django.core import exceptions |
37 | 37 | self._view_middleware = [] |
38 | 38 | self._template_response_middleware = [] |
39 | 39 | self._response_middleware = [] |
… |
… |
class BaseHandler(object):
|
41 | 41 | |
42 | 42 | request_middleware = [] |
43 | 43 | for middleware_path in settings.MIDDLEWARE_CLASSES: |
44 | | try: |
45 | | mw_module, mw_classname = middleware_path.rsplit('.', 1) |
46 | | except ValueError: |
47 | | raise exceptions.ImproperlyConfigured('%s isn\'t a middleware module' % middleware_path) |
48 | | try: |
49 | | mod = import_module(mw_module) |
50 | | except ImportError as e: |
51 | | raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e)) |
52 | | try: |
53 | | mw_class = getattr(mod, mw_classname) |
54 | | except AttributeError: |
55 | | raise exceptions.ImproperlyConfigured('Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)) |
| 44 | mw_class = import_module_from_path(middleware_path) |
56 | 45 | try: |
57 | 46 | mw_instance = mw_class() |
58 | | except exceptions.MiddlewareNotUsed: |
| 47 | except MiddlewareNotUsed: |
59 | 48 | continue |
60 | 49 | |
61 | 50 | if hasattr(mw_instance, 'process_request'): |
… |
… |
class BaseHandler(object):
|
75 | 64 | |
76 | 65 | def get_response(self, request): |
77 | 66 | "Returns an HttpResponse object for the given HttpRequest" |
78 | | from django.core import exceptions, urlresolvers |
| 67 | from django.core import urlresolvers |
79 | 68 | from django.conf import settings |
80 | 69 | |
81 | 70 | try: |
… |
… |
class BaseHandler(object):
|
156 | 145 | except: |
157 | 146 | signals.got_request_exception.send(sender=self.__class__, request=request) |
158 | 147 | response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) |
159 | | except exceptions.PermissionDenied: |
| 148 | except PermissionDenied: |
160 | 149 | logger.warning( |
161 | 150 | 'Forbidden (Permission denied): %s', request.path, |
162 | 151 | 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 7387d13..5b1b6f5 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 a912986..49b871e 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 import six |
9 | 10 | |
10 | 11 | |
… |
… |
class ConnectionRouter(object):
|
109 | 110 | self.routers = [] |
110 | 111 | for r in routers: |
111 | 112 | if isinstance(r, six.string_types): |
112 | | try: |
113 | | module_name, klass_name = r.rsplit('.', 1) |
114 | | module = import_module(module_name) |
115 | | except ImportError as e: |
116 | | raise ImproperlyConfigured('Error importing database router %s: "%s"' % (klass_name, e)) |
117 | | try: |
118 | | router_class = getattr(module, klass_name) |
119 | | except AttributeError: |
120 | | raise ImproperlyConfigured('Module "%s" does not define a database router name "%s"' % (module, klass_name)) |
121 | | else: |
122 | | router = router_class() |
| 113 | router = import_module_from_path(r)() |
123 | 114 | else: |
124 | 115 | router = r |
125 | 116 | 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 aaa7e40..6016e57 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 595b65d..b782c4f 100644
a
|
b
|
class GetStorageClassTests(SimpleTestCase):
|
55 | 55 | """ |
56 | 56 | self.assertRaisesMessage( |
57 | 57 | ImproperlyConfigured, |
58 | | "NonExistingStorage isn't a storage module.", |
| 58 | "Error importing module storage: \"No module named storage\"", |
59 | 59 | get_storage_class, |
60 | | 'NonExistingStorage') |
| 60 | 'storage.NonExistingStorage') |
61 | 61 | |
62 | 62 | def test_get_nonexisting_storage_class(self): |
63 | 63 | """ |
… |
… |
class GetStorageClassTests(SimpleTestCase):
|
65 | 65 | """ |
66 | 66 | self.assertRaisesMessage( |
67 | 67 | ImproperlyConfigured, |
68 | | 'Storage module "django.core.files.storage" does not define a '\ |
69 | | '"NonExistingStorage" class.', |
| 68 | 'Module "django.core.files.storage" does not define a ' |
| 69 | '"NonExistingStorage" attribute/class', |
70 | 70 | get_storage_class, |
71 | 71 | 'django.core.files.storage.NonExistingStorage') |
72 | 72 | |
… |
… |
class GetStorageClassTests(SimpleTestCase):
|
77 | 77 | # Error message may or may not be the fully qualified path. |
78 | 78 | six.assertRaisesRegex(self, |
79 | 79 | ImproperlyConfigured, |
80 | | ('Error importing storage module django.core.files.non_existing_' |
81 | | 'storage: "No module named .*non_existing_storage'), |
| 80 | 'Error importing module django.core.files.non_existing_storage: ' |
| 81 | '"No module named non_existing_storage"', |
82 | 82 | get_storage_class, |
83 | 83 | 'django.core.files.non_existing_storage.NonExistingStorage' |
84 | 84 | ) |
-
diff --git a/tests/regressiontests/utils/module_loading.py b/tests/regressiontests/utils/module_loading.py
index dffb519..2385fc5 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 | |
10 | 11 | |
11 | 12 | class DefaultLoader(unittest.TestCase): |
… |
… |
class EggLoader(unittest.TestCase):
|
102 | 103 | self.assertFalse(module_has_submodule(egg_module, 'no_such_module')) |
103 | 104 | self.assertRaises(ImportError, import_module, 'egg_module.sub1.sub2.no_such_module') |
104 | 105 | |
| 106 | |
| 107 | class ModuleImportTestCase(unittest.TestCase): |
| 108 | def test_import_from_path(self): |
| 109 | cls = import_module_from_path( |
| 110 | 'django.utils.module_loading.import_module_from_path') |
| 111 | self.assertEqual(cls, import_module_from_path) |
| 112 | |
| 113 | # Test exceptions raised |
| 114 | for path in ('no_dots_in_path', 'unexistent.path', |
| 115 | 'tests.regressiontests.utils.unexistent'): |
| 116 | self.assertRaises(ImproperlyConfigured, import_module_from_path, path) |
| 117 | |
| 118 | with self.assertRaises(ImproperlyConfigured) as cm: |
| 119 | import_module_from_path('unexistent.module.path', error_prefix="Foo") |
| 120 | self.assertTrue(str(cm.exception).startswith('Foo')) |
| 121 | |
| 122 | |
105 | 123 | class ProxyFinder(object): |
106 | 124 | def __init__(self): |
107 | 125 | 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() |