Fixed #17061 -- Factored out importing object from a dotted path

Thanks Carl Meyer for the report.
This commit is contained in:
Claude Paroz 2013-02-02 22:58:02 +01:00
parent 3f1c7b7053
commit 7c5b244826
26 changed files with 116 additions and 255 deletions

View File

@ -15,6 +15,7 @@ from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.functional import LazyObject, empty
from django.utils import importlib
from django.utils.module_loading import import_by_path
from django.utils import six
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
@ -68,9 +69,7 @@ class LazySettings(LazyObject):
if self.LOGGING_CONFIG:
from django.utils.log import DEFAULT_LOGGING
# First find the logging configuration function ...
logging_config_path, logging_config_func_name = self.LOGGING_CONFIG.rsplit('.', 1)
logging_config_module = importlib.import_module(logging_config_path)
logging_config_func = getattr(logging_config_module, logging_config_func_name)
logging_config_func = import_by_path(self.LOGGING_CONFIG)
logging_config_func(DEFAULT_LOGGING)

View File

@ -1,5 +1,5 @@
from django.test import LiveServerTestCase
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
from django.utils.unittest import SkipTest
from django.utils.translation import ugettext as _
@ -9,11 +9,7 @@ class AdminSeleniumWebDriverTestCase(LiveServerTestCase):
@classmethod
def setUpClass(cls):
try:
# Import and start the WebDriver class.
module, attr = cls.webdriver_class.rsplit('.', 1)
mod = import_module(module)
WebDriver = getattr(mod, attr)
cls.selenium = WebDriver()
cls.selenium = import_by_path(cls.webdriver_class)()
except Exception as e:
raise SkipTest('Selenium webdriver "%s" not installed or not '
'operational: %s' % (cls.webdriver_class, str(e)))

View File

@ -1,8 +1,8 @@
import re
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.utils.importlib import import_module
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.utils.module_loading import import_by_path
SESSION_KEY = '_auth_user_id'
BACKEND_SESSION_KEY = '_auth_user_backend'
@ -10,19 +10,7 @@ REDIRECT_FIELD_NAME = 'next'
def load_backend(path):
i = path.rfind('.')
module, attr = path[:i], path[i + 1:]
try:
mod = import_module(module)
except ImportError as e:
raise ImproperlyConfigured('Error importing authentication backend %s: "%s"' % (path, e))
except ValueError:
raise ImproperlyConfigured('Error importing authentication backends. Is AUTHENTICATION_BACKENDS a correctly defined list or tuple?')
try:
cls = getattr(mod, attr)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a "%s" authentication backend' % (module, attr))
return cls()
return import_by_path(path)()
def get_backends():

View File

@ -12,6 +12,7 @@ from django.utils.encoding import force_bytes, force_str
from django.core.exceptions import ImproperlyConfigured
from django.utils.crypto import (
pbkdf2, constant_time_compare, get_random_string)
from django.utils.module_loading import import_by_path
from django.utils.translation import ugettext_noop as _
@ -84,13 +85,7 @@ def load_hashers(password_hashers=None):
if not password_hashers:
password_hashers = settings.PASSWORD_HASHERS
for backend in password_hashers:
try:
mod_path, cls_name = backend.rsplit('.', 1)
mod = importlib.import_module(mod_path)
hasher_cls = getattr(mod, cls_name)
except (AttributeError, ImportError, ValueError):
raise ImproperlyConfigured("hasher not found: %s" % backend)
hasher = hasher_cls()
hasher = import_by_path(backend)()
if not getattr(hasher, 'algorithm'):
raise ImproperlyConfigured("hasher doesn't specify an "
"algorithm name: %s" % backend)

View File

@ -1,8 +1,6 @@
from django.test import TestCase
from django.contrib.formtools.wizard.storage import (get_storage,
MissingStorageModule,
MissingStorageClass)
from django.contrib.formtools.wizard.storage import get_storage, MissingStorage
from django.contrib.formtools.wizard.storage.base import BaseStorage
@ -12,11 +10,9 @@ class TestLoadStorage(TestCase):
type(get_storage('django.contrib.formtools.wizard.storage.base.BaseStorage', 'wizard1')),
BaseStorage)
def test_missing_module(self):
self.assertRaises(MissingStorageModule, get_storage,
def test_missing_storage(self):
self.assertRaises(MissingStorage, get_storage,
'django.contrib.formtools.wizard.storage.idontexist.IDontExistStorage', 'wizard1')
def test_missing_class(self):
self.assertRaises(MissingStorageClass, get_storage,
self.assertRaises(MissingStorage, get_storage,
'django.contrib.formtools.wizard.storage.base.IDontExistStorage', 'wizard1')

View File

@ -1,22 +1,14 @@
from django.utils.importlib import import_module
from django.core.exceptions import ImproperlyConfigured
from django.utils.module_loading import import_by_path
from django.contrib.formtools.wizard.storage.base import BaseStorage
from django.contrib.formtools.wizard.storage.exceptions import (
MissingStorageModule, MissingStorageClass, NoFileStorageConfigured)
MissingStorage, NoFileStorageConfigured)
def get_storage(path, *args, **kwargs):
i = path.rfind('.')
module, attr = path[:i], path[i+1:]
try:
mod = import_module(module)
except ImportError as e:
raise MissingStorageModule(
'Error loading storage %s: "%s"' % (module, e))
try:
storage_class = getattr(mod, attr)
except AttributeError:
raise MissingStorageClass(
'Module "%s" does not define a storage named "%s"' % (module, attr))
storage_class = import_by_path(path)
except ImproperlyConfigured as e:
raise MissingStorage('Error loading storage: %s' % e)
return storage_class(*args, **kwargs)

View File

@ -1,9 +1,6 @@
from django.core.exceptions import ImproperlyConfigured
class MissingStorageModule(ImproperlyConfigured):
pass
class MissingStorageClass(ImproperlyConfigured):
class MissingStorage(ImproperlyConfigured):
pass
class NoFileStorageConfigured(ImproperlyConfigured):

View File

@ -1,28 +1,5 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
def get_storage(import_path):
"""
Imports the message storage class described by import_path, where
import_path is the full Python path to the class.
"""
try:
dot = import_path.rindex('.')
except ValueError:
raise ImproperlyConfigured("%s isn't a Python path." % import_path)
module, classname = import_path[:dot], import_path[dot + 1:]
try:
mod = import_module(module)
except ImportError as e:
raise ImproperlyConfigured('Error importing module %s: "%s"' %
(module, e))
try:
return getattr(mod, classname)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a "%s" '
'class.' % (module, classname))
from django.utils.module_loading import import_by_path as get_storage
# Callable with the same interface as the storage classes i.e. accepts a

View File

@ -4,7 +4,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.core.files.storage import default_storage, Storage, FileSystemStorage
from django.utils.datastructures import SortedDict
from django.utils.functional import empty, memoize, LazyObject
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
from django.utils._os import safe_join
from django.utils import six
@ -258,17 +258,7 @@ def _get_finder(import_path):
Imports the staticfiles finder class described by import_path, where
import_path is the full Python path to the class.
"""
module, attr = import_path.rsplit('.', 1)
try:
mod = import_module(module)
except ImportError as e:
raise ImproperlyConfigured('Error importing module %s: "%s"' %
(module, e))
try:
Finder = getattr(mod, attr)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a "%s" '
'class.' % (module, attr))
Finder = import_by_path(import_path)
if not issubclass(Finder, BaseFinder):
raise ImproperlyConfigured('Finder "%s" is not a subclass of "%s"' %
(Finder, BaseFinder))

View File

@ -25,6 +25,8 @@ from django.core.cache.backends.base import (
InvalidCacheBackendError, CacheKeyWarning, BaseCache)
from django.core.exceptions import ImproperlyConfigured
from django.utils import importlib
from django.utils.module_loading import import_by_path
__all__ = [
'get_cache', 'cache', 'DEFAULT_CACHE_ALIAS'
@ -86,11 +88,10 @@ def parse_backend_conf(backend, **kwargs):
else:
try:
# Trying to import the given backend, in case it's a dotted path
mod_path, cls_name = backend.rsplit('.', 1)
mod = importlib.import_module(mod_path)
backend_cls = getattr(mod, cls_name)
except (AttributeError, ImportError, ValueError):
raise InvalidCacheBackendError("Could not find backend '%s'" % backend)
backend_cls = import_by_path(backend)
except ImproperlyConfigured as e:
raise InvalidCacheBackendError("Could not find backend '%s': %s" % (
backend, e))
location = kwargs.pop('LOCATION', '')
return backend, location, kwargs
@ -126,10 +127,8 @@ def get_cache(backend, **kwargs):
backend_cls = mod.CacheClass
else:
backend, location, params = parse_backend_conf(backend, **kwargs)
mod_path, cls_name = backend.rsplit('.', 1)
mod = importlib.import_module(mod_path)
backend_cls = getattr(mod, cls_name)
except (AttributeError, ImportError) as e:
backend_cls = import_by_path(backend)
except (AttributeError, ImportError, ImproperlyConfigured) as e:
raise InvalidCacheBackendError(
"Could not find backend '%s': %s" % (backend, e))
cache = backend_cls(location, params)

View File

@ -4,7 +4,7 @@ from __future__ import unicode_literals
import warnings
from django.core.exceptions import ImproperlyConfigured, DjangoRuntimeWarning
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
class InvalidCacheBackendError(ImproperlyConfigured):
@ -40,9 +40,7 @@ def get_key_func(key_func):
if callable(key_func):
return key_func
else:
key_func_module_path, key_func_name = key_func.rsplit('.', 1)
key_func_module = import_module(key_func_module_path)
return getattr(key_func_module, key_func_name)
return import_by_path(key_func)
return default_key_func

View File

@ -8,12 +8,12 @@ import itertools
from datetime import datetime
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
from django.core.exceptions import SuspiciousOperation
from django.core.files import locks, File
from django.core.files.move import file_move_safe
from django.utils.encoding import force_text, filepath_to_uri
from django.utils.functional import LazyObject
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
from django.utils.text import get_valid_filename
from django.utils._os import safe_join, abspathu
@ -277,21 +277,7 @@ class FileSystemStorage(Storage):
return datetime.fromtimestamp(os.path.getmtime(self.path(name)))
def get_storage_class(import_path=None):
if import_path is None:
import_path = settings.DEFAULT_FILE_STORAGE
try:
dot = import_path.rindex('.')
except ValueError:
raise ImproperlyConfigured("%s isn't a storage module." % import_path)
module, classname = import_path[:dot], import_path[dot+1:]
try:
mod = import_module(module)
except ImportError as e:
raise ImproperlyConfigured('Error importing storage module %s: "%s"' % (module, e))
try:
return getattr(mod, classname)
except AttributeError:
raise ImproperlyConfigured('Storage module "%s" does not define a "%s" class.' % (module, classname))
return import_by_path(import_path or settings.DEFAULT_FILE_STORAGE)
class DefaultStorage(LazyObject):
def _setup(self):

View File

@ -7,10 +7,9 @@ from __future__ import unicode_literals
from io import BytesIO
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile
from django.utils import importlib
from django.utils.encoding import python_2_unicode_compatible
from django.utils.module_loading import import_by_path
__all__ = ['UploadFileException','StopUpload', 'SkipFile', 'FileUploadHandler',
'TemporaryFileUploadHandler', 'MemoryFileUploadHandler',
@ -201,17 +200,4 @@ def load_handler(path, *args, **kwargs):
<TemporaryFileUploadHandler object at 0x...>
"""
i = path.rfind('.')
module, attr = path[:i], path[i+1:]
try:
mod = importlib.import_module(module)
except ImportError as e:
raise ImproperlyConfigured('Error importing upload handler module %s: "%s"' % (module, e))
except ValueError:
raise ImproperlyConfigured('Error importing upload handler module.'
'Is FILE_UPLOAD_HANDLERS a correctly defined list or tuple?')
try:
cls = getattr(mod, attr)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a "%s" upload handler backend' % (module, attr))
return cls(*args, **kwargs)
return import_by_path(path)(*args, **kwargs)

View File

@ -9,8 +9,9 @@ from django.conf import settings
from django.core import exceptions
from django.core import urlresolvers
from django.core import signals
from django.core.exceptions import MiddlewareNotUsed, PermissionDenied
from django.utils.encoding import force_text
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
from django.utils import six
from django.views import debug
@ -43,21 +44,10 @@ class BaseHandler(object):
request_middleware = []
for middleware_path in settings.MIDDLEWARE_CLASSES:
try:
mw_module, mw_classname = middleware_path.rsplit('.', 1)
except ValueError:
raise exceptions.ImproperlyConfigured('%s isn\'t a middleware module' % middleware_path)
try:
mod = import_module(mw_module)
except ImportError as e:
raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
try:
mw_class = getattr(mod, mw_classname)
except AttributeError:
raise exceptions.ImproperlyConfigured('Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname))
mw_class = import_by_path(middleware_path)
try:
mw_instance = mw_class()
except exceptions.MiddlewareNotUsed:
except MiddlewareNotUsed:
continue
if hasattr(mw_instance, 'process_request'):
@ -154,7 +144,7 @@ class BaseHandler(object):
except:
signals.got_request_exception.send(sender=self.__class__, request=request)
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
except exceptions.PermissionDenied:
except PermissionDenied:
logger.warning(
'Forbidden (Permission denied): %s', request.path,
extra={

View File

@ -4,8 +4,7 @@ Tools for sending email.
from __future__ import unicode_literals
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
# Imported for backwards compatibility, and for the sake
# of a cleaner namespace. These symbols used to be in
@ -27,18 +26,7 @@ def get_connection(backend=None, fail_silently=False, **kwds):
Both fail_silently and other keyword arguments are used in the
constructor of the backend.
"""
path = backend or settings.EMAIL_BACKEND
try:
mod_name, klass_name = path.rsplit('.', 1)
mod = import_module(mod_name)
except ImportError as e:
raise ImproperlyConfigured(('Error importing email backend module %s: "%s"'
% (mod_name, e)))
try:
klass = getattr(mod, klass_name)
except AttributeError:
raise ImproperlyConfigured(('Module "%s" does not define a '
'"%s" class' % (mod_name, klass_name)))
klass = import_by_path(backend or settings.EMAIL_BACKEND)
return klass(fail_silently=fail_silently, **kwds)

View File

@ -21,11 +21,9 @@ from django.utils.six.moves import socketserver
from wsgiref import simple_server
from wsgiref.util import FileWrapper # for backwards compatibility
import django
from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style
from django.core.wsgi import get_wsgi_application
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
__all__ = ['WSGIServer', 'WSGIRequestHandler']
@ -49,22 +47,11 @@ def get_internal_wsgi_application():
app_path = getattr(settings, 'WSGI_APPLICATION')
if app_path is None:
return get_wsgi_application()
module_name, attr = app_path.rsplit('.', 1)
try:
mod = import_module(module_name)
except ImportError as e:
raise ImproperlyConfigured(
"WSGI application '%s' could not be loaded; "
"could not import module '%s': %s" % (app_path, module_name, e))
try:
app = getattr(mod, attr)
except AttributeError as e:
raise ImproperlyConfigured(
"WSGI application '%s' could not be loaded; "
"can't find '%s' in module '%s': %s"
% (app_path, attr, module_name, e))
return app
return import_by_path(
app_path,
error_prefix="WSGI application '%s' could not be loaded; " % app_path
)
class WSGIServerException(Exception):

View File

@ -41,11 +41,10 @@ import time
import zlib
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils import baseconv
from django.utils.crypto import constant_time_compare, salted_hmac
from django.utils.encoding import force_bytes, force_str, force_text
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
class BadSignature(Exception):
@ -76,18 +75,7 @@ def base64_hmac(salt, value, key):
def get_cookie_signer(salt='django.core.signing.get_cookie_signer'):
modpath = settings.SIGNING_BACKEND
module, attr = modpath.rsplit('.', 1)
try:
mod = import_module(module)
except ImportError as e:
raise ImproperlyConfigured(
'Error importing cookie signer %s: "%s"' % (modpath, e))
try:
Signer = getattr(mod, attr)
except AttributeError as e:
raise ImproperlyConfigured(
'Error importing cookie signer %s: "%s"' % (modpath, e))
Signer = import_by_path(settings.SIGNING_BACKEND)
return Signer('django.http.cookies' + settings.SECRET_KEY, salt=salt)

View File

@ -5,6 +5,7 @@ from threading import local
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
from django.utils._os import upath
from django.utils import six
@ -110,17 +111,7 @@ class ConnectionRouter(object):
self.routers = []
for r in routers:
if isinstance(r, six.string_types):
try:
module_name, klass_name = r.rsplit('.', 1)
module = import_module(module_name)
except ImportError as e:
raise ImproperlyConfigured('Error importing database router %s: "%s"' % (klass_name, e))
try:
router_class = getattr(module, klass_name)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a database router name "%s"' % (module, klass_name))
else:
router = router_class()
router = import_by_path(r)()
else:
router = r
self.routers.append(router)

View File

@ -1,6 +1,5 @@
from copy import copy
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path
# Cache of actual callables.
_standard_context_processors = None
@ -146,16 +145,7 @@ def get_standard_processors():
collect.extend(_builtin_context_processors)
collect.extend(settings.TEMPLATE_CONTEXT_PROCESSORS)
for path in collect:
i = path.rfind('.')
module, attr = path[:i], path[i+1:]
try:
mod = import_module(module)
except ImportError as e:
raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e))
try:
func = getattr(mod, attr)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr))
func = import_by_path(path)
processors.append(func)
_standard_context_processors = tuple(processors)
return _standard_context_processors

View File

@ -27,8 +27,8 @@
from django.core.exceptions import ImproperlyConfigured
from django.template.base import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins
from django.utils.importlib import import_module
from django.conf import settings
from django.utils.module_loading import import_by_path
from django.utils import six
template_source_loaders = None
@ -91,15 +91,7 @@ def find_template_loader(loader):
else:
args = []
if isinstance(loader, six.string_types):
module, attr = loader.rsplit('.', 1)
try:
mod = import_module(module)
except ImportError as e:
raise ImproperlyConfigured('Error importing template source loader %s: "%s"' % (loader, e))
try:
TemplateLoader = getattr(mod, attr)
except AttributeError as e:
raise ImproperlyConfigured('Error importing template source loader %s: "%s"' % (loader, e))
TemplateLoader = import_by_path(loader)
if hasattr(TemplateLoader, 'load_template_source'):
func = TemplateLoader(*args)

View File

@ -2,6 +2,32 @@ import imp
import os
import sys
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
def import_by_path(dotted_path, error_prefix=''):
"""
Import a dotted module path and return the attribute/class designated by the
last name in the path. Raise ImproperlyConfigured if something goes wrong.
"""
try:
module_path, class_name = dotted_path.rsplit('.', 1)
except ValueError:
raise ImproperlyConfigured("%s%s doesn't look like a module path" % (
error_prefix, dotted_path))
try:
module = import_module(module_path)
except ImportError as e:
raise ImproperlyConfigured('%sError importing module %s: "%s"' % (
error_prefix, module_path, e))
try:
attr = getattr(module, class_name)
except AttributeError:
raise ImproperlyConfigured('%sModule "%s" does not define a "%s" attribute/class' % (
error_prefix, module_path, class_name))
return attr
def module_has_submodule(package, module_name):
"""See if 'module' is in 'package'."""

View File

@ -13,8 +13,8 @@ from django.http import (HttpResponse, HttpResponseServerError,
from django.template import Template, Context, TemplateDoesNotExist
from django.template.defaultfilters import force_escape, pprint
from django.utils.html import escape
from django.utils.importlib import import_module
from django.utils.encoding import force_bytes, smart_text
from django.utils.module_loading import import_by_path
from django.utils import six
HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|PROFANITIES_LIST|SIGNATURE')
@ -76,17 +76,8 @@ def get_exception_reporter_filter(request):
global default_exception_reporter_filter
if default_exception_reporter_filter is None:
# Load the default filter for the first time and cache it.
modpath = settings.DEFAULT_EXCEPTION_REPORTER_FILTER
modname, classname = modpath.rsplit('.', 1)
try:
mod = import_module(modname)
except ImportError as e:
raise ImproperlyConfigured(
'Error importing default exception reporter filter %s: "%s"' % (modpath, e))
try:
default_exception_reporter_filter = getattr(mod, classname)()
except AttributeError:
raise ImproperlyConfigured('Default exception reporter filter module "%s" does not define a "%s" class' % (modname, classname))
default_exception_reporter_filter = import_by_path(
settings.DEFAULT_EXCEPTION_REPORTER_FILTER)()
if request:
return getattr(request, 'exception_reporter_filter', default_exception_reporter_filter)
else:

View File

@ -57,9 +57,9 @@ class GetStorageClassTests(SimpleTestCase):
"""
self.assertRaisesMessage(
ImproperlyConfigured,
"NonExistingStorage isn't a storage module.",
"Error importing module storage: \"No module named storage\"",
get_storage_class,
'NonExistingStorage')
'storage.NonExistingStorage')
def test_get_nonexisting_storage_class(self):
"""
@ -67,8 +67,8 @@ class GetStorageClassTests(SimpleTestCase):
"""
self.assertRaisesMessage(
ImproperlyConfigured,
'Storage module "django.core.files.storage" does not define a '\
'"NonExistingStorage" class.',
'Module "django.core.files.storage" does not define a '
'"NonExistingStorage" attribute/class',
get_storage_class,
'django.core.files.storage.NonExistingStorage')
@ -79,8 +79,8 @@ class GetStorageClassTests(SimpleTestCase):
# Error message may or may not be the fully qualified path.
six.assertRaisesRegex(self,
ImproperlyConfigured,
('Error importing storage module django.core.files.non_existing_'
'storage: "No module named .*non_existing_storage'),
'Error importing module django.core.files.non_existing_storage: '
'"No module named non_existing_storage"',
get_storage_class,
'django.core.files.non_existing_storage.NonExistingStorage'
)

View File

@ -3,9 +3,10 @@ import sys
import imp
from zipimport import zipimporter
from django.core.exceptions import ImproperlyConfigured
from django.utils import unittest
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
from django.utils.module_loading import import_by_path, module_has_submodule
from django.utils._os import upath
@ -103,6 +104,23 @@ class EggLoader(unittest.TestCase):
self.assertFalse(module_has_submodule(egg_module, 'no_such_module'))
self.assertRaises(ImportError, import_module, 'egg_module.sub1.sub2.no_such_module')
class ModuleImportTestCase(unittest.TestCase):
def test_import_by_path(self):
cls = import_by_path(
'django.utils.module_loading.import_by_path')
self.assertEqual(cls, import_by_path)
# Test exceptions raised
for path in ('no_dots_in_path', 'unexistent.path',
'tests.regressiontests.utils.unexistent'):
self.assertRaises(ImproperlyConfigured, import_by_path, path)
with self.assertRaises(ImproperlyConfigured) as cm:
import_by_path('unexistent.module.path', error_prefix="Foo")
self.assertTrue(str(cm.exception).startswith('Foo'))
class ProxyFinder(object):
def __init__(self):
self._cache = {}

View File

@ -20,7 +20,8 @@ from .html import TestUtilsHtml
from .http import TestUtilsHttp, ETagProcessingTests, HttpDateProcessingTests
from .ipv6 import TestUtilsIPv6
from .jslex import JsToCForGettextTest, JsTokensTest
from .module_loading import CustomLoader, DefaultLoader, EggLoader
from .module_loading import (CustomLoader, DefaultLoader, EggLoader,
ModuleImportTestCase)
from .numberformat import TestNumberFormat
from .os_utils import SafeJoinTests
from .regex_helper import NormalizeTests

View File

@ -85,7 +85,7 @@ class GetInternalWSGIApplicationTest(unittest.TestCase):
def test_bad_module(self):
with six.assertRaisesRegex(self,
ImproperlyConfigured,
r"^WSGI application 'regressiontests.wsgi.noexist.app' could not be loaded; could not import module 'regressiontests.wsgi.noexist':"):
r"^WSGI application 'regressiontests.wsgi.noexist.app' could not be loaded; Error importing.*"):
get_internal_wsgi_application()
@ -94,6 +94,6 @@ class GetInternalWSGIApplicationTest(unittest.TestCase):
def test_bad_name(self):
with six.assertRaisesRegex(self,
ImproperlyConfigured,
r"^WSGI application 'regressiontests.wsgi.wsgi.noexist' could not be loaded; can't find 'noexist' in module 'regressiontests.wsgi.wsgi':"):
r"^WSGI application 'regressiontests.wsgi.wsgi.noexist' could not be loaded; Module.*"):
get_internal_wsgi_application()