Fixed #8193: all dynamic imports in Django are now done correctly. I know this because Brett Cannon borrowed the time machine and brought Python 2.7's '`importlib` back for inclusion in Django. Thanks for the patch-from-the-future, Brett!

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10088 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2009-03-18 16:55:59 +00:00
parent ee2f04d79e
commit c485e236bd
32 changed files with 128 additions and 71 deletions

View File

@ -75,6 +75,7 @@ answer newbie questions, and generally made Django that much better:
Chris Cahoon <chris.cahoon@gmail.com> Chris Cahoon <chris.cahoon@gmail.com>
Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com> Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com>
Trevor Caira <trevor@caira.com> Trevor Caira <trevor@caira.com>
Brett Cannon <brett@python.org>
Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com> Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
Jeremy Carbaugh <jcarbaugh@gmail.com> Jeremy Carbaugh <jcarbaugh@gmail.com>
carljm <carl@dirtcircle.com> carljm <carl@dirtcircle.com>

View File

@ -12,6 +12,7 @@ import time # Needed for Windows
from django.conf import global_settings from django.conf import global_settings
from django.utils.functional import LazyObject from django.utils.functional import LazyObject
from django.utils import importlib
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
@ -69,7 +70,7 @@ class Settings(object):
self.SETTINGS_MODULE = settings_module self.SETTINGS_MODULE = settings_module
try: try:
mod = __import__(self.SETTINGS_MODULE, {}, {}, ['']) mod = importlib.import_module(self.SETTINGS_MODULE)
except ImportError, e: except ImportError, e:
raise ImportError, "Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e) raise ImportError, "Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e)
@ -89,7 +90,8 @@ class Settings(object):
new_installed_apps = [] new_installed_apps = []
for app in self.INSTALLED_APPS: for app in self.INSTALLED_APPS:
if app.endswith('.*'): if app.endswith('.*'):
appdir = os.path.dirname(__import__(app[:-2], {}, {}, ['']).__file__) app_mod = importlib.import_module(app[:-2])
appdir = os.path.dirname(app_mod.__file__)
app_subdirs = os.listdir(appdir) app_subdirs = os.listdir(appdir)
app_subdirs.sort() app_subdirs.sort()
name_pattern = re.compile(r'[a-zA-Z]\w*') name_pattern = re.compile(r'[a-zA-Z]\w*')

View File

@ -1,6 +1,7 @@
from django.contrib.admin.options import ModelAdmin, HORIZONTAL, VERTICAL from django.contrib.admin.options import ModelAdmin, HORIZONTAL, VERTICAL
from django.contrib.admin.options import StackedInline, TabularInline from django.contrib.admin.options import StackedInline, TabularInline
from django.contrib.admin.sites import AdminSite, site from django.contrib.admin.sites import AdminSite, site
from django.utils.importlib import import_module
# A flag to tell us if autodiscover is running. autodiscover will set this to # A flag to tell us if autodiscover is running. autodiscover will set this to
# True while running, and False when it finishes. # True while running, and False when it finishes.
@ -36,7 +37,7 @@ def autodiscover():
# fails silently -- apps that do weird things with __path__ might # fails silently -- apps that do weird things with __path__ might
# need to roll their own admin registration. # need to roll their own admin registration.
try: try:
app_path = __import__(app, {}, {}, [app.split('.')[-1]]).__path__ app_path = import_module(app).__path__
except AttributeError: except AttributeError:
continue continue
@ -51,6 +52,6 @@ def autodiscover():
# Step 3: import the app's admin file. If this has errors we want them # Step 3: import the app's admin file. If this has errors we want them
# to bubble up. # to bubble up.
__import__("%s.admin" % app) import_module("%s.admin" % app)
# autodiscover was successful, reset loading flag. # autodiscover was successful, reset loading flag.
LOADING = False LOADING = False

View File

@ -4,6 +4,7 @@ from django.template import loader
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.conf import settings from django.conf import settings
from django.utils.importlib import import_module
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -15,7 +16,7 @@ def template_validator(request):
# get a dict of {site_id : settings_module} for the validator # get a dict of {site_id : settings_module} for the validator
settings_modules = {} settings_modules = {}
for mod in settings.ADMIN_FOR: for mod in settings.ADMIN_FOR:
settings_module = __import__(mod, {}, {}, ['']) settings_module = import_module(mod)
settings_modules[settings_module.SITE_ID] = settings_module settings_modules[settings_module.SITE_ID] = settings_module
site_list = Site.objects.in_bulk(settings_modules.keys()).values() site_list = Site.objects.in_bulk(settings_modules.keys()).values()
if request.POST: if request.POST:

View File

@ -9,6 +9,7 @@ from django.http import Http404
from django.core import urlresolvers from django.core import urlresolvers
from django.contrib.admindocs import utils from django.contrib.admindocs import utils
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.utils.importlib import import_module
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
import inspect, os, re import inspect, os, re
@ -114,13 +115,13 @@ def view_index(request):
return missing_docutils_page(request) return missing_docutils_page(request)
if settings.ADMIN_FOR: if settings.ADMIN_FOR:
settings_modules = [__import__(m, {}, {}, ['']) for m in settings.ADMIN_FOR] settings_modules = [import_module(m) for m in settings.ADMIN_FOR]
else: else:
settings_modules = [settings] settings_modules = [settings]
views = [] views = []
for settings_mod in settings_modules: for settings_mod in settings_modules:
urlconf = __import__(settings_mod.ROOT_URLCONF, {}, {}, ['']) urlconf = import_module(settings_mod.ROOT_URLCONF)
view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns) view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
if Site._meta.installed: if Site._meta.installed:
site_obj = Site.objects.get(pk=settings_mod.SITE_ID) site_obj = Site.objects.get(pk=settings_mod.SITE_ID)
@ -146,7 +147,7 @@ def view_detail(request, view):
mod, func = urlresolvers.get_mod_func(view) mod, func = urlresolvers.get_mod_func(view)
try: try:
view_func = getattr(__import__(mod, {}, {}, ['']), func) view_func = getattr(import_module(mod), func)
except (ImportError, AttributeError): except (ImportError, AttributeError):
raise Http404 raise Http404
title, body, metadata = utils.parse_docstring(view_func.__doc__) title, body, metadata = utils.parse_docstring(view_func.__doc__)
@ -257,7 +258,7 @@ model_detail = staff_member_required(model_detail)
def template_detail(request, template): def template_detail(request, template):
templates = [] templates = []
for site_settings_module in settings.ADMIN_FOR: for site_settings_module in settings.ADMIN_FOR:
settings_mod = __import__(site_settings_module, {}, {}, ['']) settings_mod = import_module(site_settings_module)
if Site._meta.installed: if Site._meta.installed:
site_obj = Site.objects.get(pk=settings_mod.SITE_ID) site_obj = Site.objects.get(pk=settings_mod.SITE_ID)
else: else:

View File

@ -1,5 +1,6 @@
import datetime import datetime
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
SESSION_KEY = '_auth_user_id' SESSION_KEY = '_auth_user_id'
BACKEND_SESSION_KEY = '_auth_user_backend' BACKEND_SESSION_KEY = '_auth_user_backend'
@ -9,7 +10,7 @@ def load_backend(path):
i = path.rfind('.') i = path.rfind('.')
module, attr = path[:i], path[i+1:] module, attr = path[:i], path[i+1:]
try: try:
mod = __import__(module, {}, {}, [attr]) mod = import_module(module)
except ImportError, e: except ImportError, e:
raise ImproperlyConfigured, 'Error importing authentication backend %s: "%s"' % (module, e) raise ImproperlyConfigured, 'Error importing authentication backend %s: "%s"' % (module, e)
except ValueError, e: except ValueError, e:

View File

@ -3,6 +3,7 @@ from django.core import urlresolvers
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.contrib.comments.models import Comment from django.contrib.comments.models import Comment
from django.contrib.comments.forms import CommentForm from django.contrib.comments.forms import CommentForm
from django.utils.importlib import import_module
DEFAULT_COMMENTS_APP = 'django.contrib.comments' DEFAULT_COMMENTS_APP = 'django.contrib.comments'
@ -18,7 +19,7 @@ def get_comment_app():
# Try to import the package # Try to import the package
try: try:
package = __import__(comments_app, '', '', ['']) package = import_module(comments_app)
except ImportError: except ImportError:
raise ImproperlyConfigured("The COMMENTS_APP setting refers to "\ raise ImproperlyConfigured("The COMMENTS_APP setting refers to "\
"a non-existing package.") "a non-existing package.")

View File

@ -3,10 +3,11 @@ import time
from django.conf import settings from django.conf import settings
from django.utils.cache import patch_vary_headers from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date from django.utils.http import cookie_date
from django.utils.importlib import import_module
class SessionMiddleware(object): class SessionMiddleware(object):
def process_request(self, request): def process_request(self, request):
engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) engine = import_module(settings.SESSION_ENGINE)
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None) session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
request.session = engine.SessionStore(session_key) request.session = engine.SessionStore(session_key)

View File

@ -19,6 +19,7 @@ from cgi import parse_qsl
from django.conf import settings from django.conf import settings
from django.core import signals from django.core import signals
from django.core.cache.backends.base import InvalidCacheBackendError from django.core.cache.backends.base import InvalidCacheBackendError
from django.utils import importlib
# Name for use in settings file --> name of module in "backends" directory. # Name for use in settings file --> name of module in "backends" directory.
# Any backend scheme that is not in this dictionary is treated as a Python # Any backend scheme that is not in this dictionary is treated as a Python
@ -58,9 +59,10 @@ def parse_backend_uri(backend_uri):
def get_cache(backend_uri): def get_cache(backend_uri):
scheme, host, params = parse_backend_uri(backend_uri) scheme, host, params = parse_backend_uri(backend_uri)
if scheme in BACKENDS: if scheme in BACKENDS:
module = __import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, ['']) name = 'django.core.cache.backends.%s' % BACKENDS[scheme]
else: else:
module = __import__(scheme, {}, {}, ['']) name = scheme
module = importlib.import_module(name)
return getattr(module, 'CacheClass')(host, params) return getattr(module, 'CacheClass')(host, params)
cache = get_cache(settings.CACHE_BACKEND) cache = get_cache(settings.CACHE_BACKEND)

View File

@ -8,6 +8,7 @@ from django.core.files import locks, File
from django.core.files.move import file_move_safe from django.core.files.move import file_move_safe
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
from django.utils.functional import LazyObject from django.utils.functional import LazyObject
from django.utils.importlib import import_module
from django.utils.text import get_valid_filename from django.utils.text import get_valid_filename
from django.utils._os import safe_join from django.utils._os import safe_join
@ -230,7 +231,7 @@ def get_storage_class(import_path=None):
raise ImproperlyConfigured("%s isn't a storage module." % import_path) raise ImproperlyConfigured("%s isn't a storage module." % import_path)
module, classname = import_path[:dot], import_path[dot+1:] module, classname = import_path[:dot], import_path[dot+1:]
try: try:
mod = __import__(module, {}, {}, ['']) mod = import_module(module)
except ImportError, e: except ImportError, e:
raise ImproperlyConfigured('Error importing storage module %s: "%s"' % (module, e)) raise ImproperlyConfigured('Error importing storage module %s: "%s"' % (module, e))
try: try:

View File

@ -10,6 +10,7 @@ except ImportError:
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile
from django.utils import importlib
__all__ = ['UploadFileException','StopUpload', 'SkipFile', 'FileUploadHandler', __all__ = ['UploadFileException','StopUpload', 'SkipFile', 'FileUploadHandler',
'TemporaryFileUploadHandler', 'MemoryFileUploadHandler', 'TemporaryFileUploadHandler', 'MemoryFileUploadHandler',
@ -201,7 +202,7 @@ def load_handler(path, *args, **kwargs):
i = path.rfind('.') i = path.rfind('.')
module, attr = path[:i], path[i+1:] module, attr = path[:i], path[i+1:]
try: try:
mod = __import__(module, {}, {}, [attr]) mod = importlib.import_module(module)
except ImportError, e: except ImportError, e:
raise ImproperlyConfigured('Error importing upload handler module %s: "%s"' % (module, e)) raise ImproperlyConfigured('Error importing upload handler module %s: "%s"' % (module, e))
except ValueError, e: except ValueError, e:

View File

@ -3,6 +3,7 @@ import sys
from django import http from django import http
from django.core import signals from django.core import signals
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
from django.utils.importlib import import_module
class BaseHandler(object): class BaseHandler(object):
# Changes that are always applied to a response (in this order). # Changes that are always applied to a response (in this order).
@ -36,7 +37,7 @@ class BaseHandler(object):
raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:] mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
try: try:
mod = __import__(mw_module, {}, {}, ['']) mod = import_module(mw_module)
except ImportError, e: except ImportError, e:
raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e) raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
try: try:

View File

@ -5,6 +5,7 @@ import imp
import django import django
from django.core.management.base import BaseCommand, CommandError, handle_default_options from django.core.management.base import BaseCommand, CommandError, handle_default_options
from django.utils.importlib import import_module
# For backwards compatibility: get_version() used to be in this module. # For backwards compatibility: get_version() used to be in this module.
get_version = django.get_version get_version = django.get_version
@ -63,8 +64,8 @@ def load_command_class(app_name, name):
class instance. All errors raised by the import process class instance. All errors raised by the import process
(ImportError, AttributeError) are allowed to propagate. (ImportError, AttributeError) are allowed to propagate.
""" """
return getattr(__import__('%s.management.commands.%s' % (app_name, name), module = import_module('%s.management.commands.%s' % (app_name, name))
{}, {}, ['Command']), 'Command')() return module.Command()
def get_commands(): def get_commands():
""" """
@ -104,12 +105,9 @@ def get_commands():
# Find the project directory # Find the project directory
try: try:
from django.conf import settings from django.conf import settings
project_directory = setup_environ( module = import_module(settings.SETTINGS_MODULE.split('.', 1)[0])
__import__( project_directory = setup_environ(module,
settings.SETTINGS_MODULE, {}, {}, settings.SETTINGS_MODULE)
(settings.SETTINGS_MODULE.split(".")[-1],)
), settings.SETTINGS_MODULE
)
except (AttributeError, EnvironmentError, ImportError): except (AttributeError, EnvironmentError, ImportError):
project_directory = None project_directory = None
@ -328,7 +326,7 @@ def setup_environ(settings_mod, original_settings_path=None):
# Import the project module. We add the parent directory to PYTHONPATH to # Import the project module. We add the parent directory to PYTHONPATH to
# avoid some of the path errors new users can have. # avoid some of the path errors new users can have.
sys.path.append(os.path.join(project_directory, os.pardir)) sys.path.append(os.path.join(project_directory, os.pardir))
project_module = __import__(project_name, {}, {}, ['']) project_module = import_module(project_name)
sys.path.pop() sys.path.pop()
return project_directory return project_directory

View File

@ -1,5 +1,6 @@
from django.core.management.base import NoArgsCommand, CommandError from django.core.management.base import NoArgsCommand, CommandError
from django.core.management.color import no_style from django.core.management.color import no_style
from django.utils.importlib import import_module
from optparse import make_option from optparse import make_option
class Command(NoArgsCommand): class Command(NoArgsCommand):
@ -23,7 +24,7 @@ class Command(NoArgsCommand):
# dispatcher events. # dispatcher events.
for app_name in settings.INSTALLED_APPS: for app_name in settings.INSTALLED_APPS:
try: try:
__import__(app_name + '.management', {}, {}, ['']) import_module('.management', app_name)
except ImportError: except ImportError:
pass pass

View File

@ -1,6 +1,7 @@
import os import os
from django.core.management.base import copy_helper, CommandError, LabelCommand from django.core.management.base import copy_helper, CommandError, LabelCommand
from django.utils.importlib import import_module
class Command(LabelCommand): class Command(LabelCommand):
help = "Creates a Django app directory structure for the given app name in the current directory." help = "Creates a Django app directory structure for the given app name in the current directory."
@ -26,7 +27,7 @@ class Command(LabelCommand):
# Check that the app_name cannot be imported. # Check that the app_name cannot be imported.
try: try:
__import__(app_name) import_module(app_name)
except ImportError: except ImportError:
pass pass
else: else:

View File

@ -1,4 +1,5 @@
from django.core.management.base import copy_helper, CommandError, LabelCommand from django.core.management.base import copy_helper, CommandError, LabelCommand
from django.utils.importlib import import_module
import os import os
import re import re
from random import choice from random import choice
@ -20,7 +21,7 @@ class Command(LabelCommand):
# Check that the project_name cannot be imported. # Check that the project_name cannot be imported.
try: try:
__import__(project_name) import_module(project_name)
except ImportError: except ImportError:
pass pass
else: else:

View File

@ -1,5 +1,6 @@
from django.core.management.base import NoArgsCommand from django.core.management.base import NoArgsCommand
from django.core.management.color import no_style from django.core.management.color import no_style
from django.utils.importlib import import_module
from optparse import make_option from optparse import make_option
import sys import sys
@ -30,7 +31,7 @@ class Command(NoArgsCommand):
# dispatcher events. # dispatcher events.
for app_name in settings.INSTALLED_APPS: for app_name in settings.INSTALLED_APPS:
try: try:
__import__(app_name + '.management', {}, {}, ['']) import_module('.management', app_name)
except ImportError, exc: except ImportError, exc:
# This is slightly hackish. We want to ignore ImportErrors # This is slightly hackish. We want to ignore ImportErrors
# if the "management" module itself is missing -- but we don't # if the "management" module itself is missing -- but we don't

View File

@ -17,6 +17,7 @@ To add your own serializers, use the SERIALIZATION_MODULES setting::
""" """
from django.conf import settings from django.conf import settings
from django.utils import importlib
# Built-in serializers # Built-in serializers
BUILTIN_SERIALIZERS = { BUILTIN_SERIALIZERS = {
@ -47,7 +48,7 @@ def register_serializer(format, serializer_module, serializers=None):
directly into the global register of serializers. Adding serializers directly into the global register of serializers. Adding serializers
directly is not a thread-safe operation. directly is not a thread-safe operation.
""" """
module = __import__(serializer_module, {}, {}, ['']) module = importlib.import_module(serializer_module)
if serializers is None: if serializers is None:
_serializers[format] = module _serializers[format] = module
else: else:

View File

@ -12,6 +12,7 @@ Run with the extra option "help" for a list of additional options you can
pass to this server. pass to this server.
""" """
from django.utils import importlib
import sys, os import sys, os
__version__ = "0.1" __version__ = "0.1"
@ -113,7 +114,7 @@ def runfastcgi(argset=[], **kwargs):
'maxSpare': int(options["maxspare"]), 'maxSpare': int(options["maxspare"]),
'minSpare': int(options["minspare"]), 'minSpare': int(options["minspare"]),
'maxChildren': int(options["maxchildren"]), 'maxChildren': int(options["maxchildren"]),
'maxRequests': int(options["maxrequests"]), 'maxRequests': int(options["maxrequests"]),
} }
flup_module += '_fork' flup_module += '_fork'
elif options['method'] in ('thread', 'threaded'): elif options['method'] in ('thread', 'threaded'):
@ -128,7 +129,8 @@ def runfastcgi(argset=[], **kwargs):
wsgi_opts['debug'] = False # Turn off flup tracebacks wsgi_opts['debug'] = False # Turn off flup tracebacks
try: try:
WSGIServer = getattr(__import__('flup.' + flup_module, '', '', flup_module), 'WSGIServer') module = importlib_import_module('.%s' % flup_module, 'flup')
WSGIServer = module.WSGIServer
except: except:
print "Can't import flup." + flup_module print "Can't import flup." + flup_module
return False return False

View File

@ -14,6 +14,7 @@ from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
from django.utils.encoding import iri_to_uri, force_unicode, smart_str from django.utils.encoding import iri_to_uri, force_unicode, smart_str
from django.utils.functional import memoize from django.utils.functional import memoize
from django.utils.importlib import import_module
from django.utils.regex_helper import normalize from django.utils.regex_helper import normalize
from django.utils.thread_support import currentThread from django.utils.thread_support import currentThread
@ -54,7 +55,7 @@ def get_callable(lookup_view, can_fail=False):
lookup_view = lookup_view.encode('ascii') lookup_view = lookup_view.encode('ascii')
mod_name, func_name = get_mod_func(lookup_view) mod_name, func_name = get_mod_func(lookup_view)
if func_name != '': if func_name != '':
lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name) lookup_view = getattr(import_module(mod_name), func_name)
if not callable(lookup_view): if not callable(lookup_view):
raise AttributeError("'%s.%s' is not a callable." % (mod_name, func_name)) raise AttributeError("'%s.%s' is not a callable." % (mod_name, func_name))
except (ImportError, AttributeError): except (ImportError, AttributeError):
@ -199,7 +200,7 @@ class RegexURLResolver(object):
try: try:
return self._urlconf_module return self._urlconf_module
except AttributeError: except AttributeError:
self._urlconf_module = __import__(self.urlconf_name, {}, {}, ['']) self._urlconf_module = import_module(self.urlconf_name)
return self._urlconf_module return self._urlconf_module
urlconf_module = property(_get_urlconf_module) urlconf_module = property(_get_urlconf_module)
@ -217,7 +218,7 @@ class RegexURLResolver(object):
callback = getattr(self.urlconf_module, 'handler%s' % view_type) callback = getattr(self.urlconf_module, 'handler%s' % view_type)
mod_name, func_name = get_mod_func(callback) mod_name, func_name = get_mod_func(callback)
try: try:
return getattr(__import__(mod_name, {}, {}, ['']), func_name), {} return getattr(import_module(mod_name), func_name), {}
except (ImportError, AttributeError), e: except (ImportError, AttributeError), e:
raise ViewDoesNotExist, "Tried %s. Error was: %s" % (callback, str(e)) raise ViewDoesNotExist, "Tried %s. Error was: %s" % (callback, str(e))

View File

@ -3,6 +3,7 @@ from django.conf import settings
from django.core import signals from django.core import signals
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.functional import curry from django.utils.functional import curry
from django.utils.importlib import import_module
__all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError') __all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
@ -13,12 +14,12 @@ def load_backend(backend_name):
try: try:
# Most of the time, the database backend will be one of the official # Most of the time, the database backend will be one of the official
# backends that ships with Django, so look there first. # backends that ships with Django, so look there first.
return __import__('django.db.backends.%s.base' % backend_name, {}, {}, ['']) return import_module('.base', 'django.db.backends.%s' % settings.DATABASE_ENGINE)
except ImportError, e: except ImportError, e:
# If the import failed, we might be looking for a database backend # If the import failed, we might be looking for a database backend
# distributed external to Django. So we'll try that next. # distributed external to Django. So we'll try that next.
try: try:
return __import__('%s.base' % backend_name, {}, {}, ['']) return import_module('.base', backend_name)
except ImportError, e_user: except ImportError, e_user:
# The database backend wasn't found. Display a helpful error message # The database backend wasn't found. Display a helpful error message
# listing all possible (built-in) database backends. # listing all possible (built-in) database backends.

View File

@ -3,6 +3,7 @@
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from django.utils.importlib import import_module
import sys import sys
import os import os
@ -69,9 +70,10 @@ class AppCache(object):
""" """
self.handled[app_name] = None self.handled[app_name] = None
self.nesting_level += 1 self.nesting_level += 1
mod = __import__(app_name, {}, {}, ['models']) try:
self.nesting_level -= 1 models = import_module('.models', app_name)
if not hasattr(mod, 'models'): except ImportError:
self.nesting_level -= 1
if can_postpone: if can_postpone:
# Either the app has no models, or the package is still being # Either the app has no models, or the package is still being
# imported by Python and the model module isn't available yet. # imported by Python and the model module isn't available yet.
@ -79,9 +81,10 @@ class AppCache(object):
# populate). # populate).
self.postponed.append(app_name) self.postponed.append(app_name)
return None return None
if mod.models not in self.app_store: self.nesting_level -= 1
self.app_store[mod.models] = len(self.app_store) if models not in self.app_store:
return mod.models self.app_store[models] = len(self.app_store)
return models
def app_cache_ready(self): def app_cache_ready(self):
""" """

View File

@ -52,6 +52,7 @@ import re
from inspect import getargspec from inspect import getargspec
from django.conf import settings from django.conf import settings
from django.template.context import Context, RequestContext, ContextPopException from django.template.context import Context, RequestContext, ContextPopException
from django.utils.importlib import import_module
from django.utils.itercompat import is_iterable from django.utils.itercompat import is_iterable
from django.utils.functional import curry, Promise from django.utils.functional import curry, Promise
from django.utils.text import smart_split from django.utils.text import smart_split
@ -935,7 +936,7 @@ def get_library(module_name):
lib = libraries.get(module_name, None) lib = libraries.get(module_name, None)
if not lib: if not lib:
try: try:
mod = __import__(module_name, {}, {}, ['']) mod = import_module(module_name)
except ImportError, e: except ImportError, e:
raise InvalidTemplateLibrary("Could not load template library from %s, %s" % (module_name, e)) raise InvalidTemplateLibrary("Could not load template library from %s, %s" % (module_name, e))
try: try:

View File

@ -1,5 +1,6 @@
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
_standard_context_processors = None _standard_context_processors = None
@ -62,7 +63,7 @@ class Context(object):
def update(self, other_dict): def update(self, other_dict):
"Like dict.update(). Pushes an entire dictionary's keys and values onto the context." "Like dict.update(). Pushes an entire dictionary's keys and values onto the context."
if not hasattr(other_dict, '__getitem__'): if not hasattr(other_dict, '__getitem__'):
raise TypeError('other_dict must be a mapping (dictionary-like) object.') raise TypeError('other_dict must be a mapping (dictionary-like) object.')
self.dicts = [other_dict] + self.dicts self.dicts = [other_dict] + self.dicts
return other_dict return other_dict
@ -77,7 +78,7 @@ def get_standard_processors():
i = path.rfind('.') i = path.rfind('.')
module, attr = path[:i], path[i+1:] module, attr = path[:i], path[i+1:]
try: try:
mod = __import__(module, {}, {}, [attr]) mod = import_module(module)
except ImportError, e: except ImportError, e:
raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e)) raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e))
try: try:

View File

@ -22,6 +22,7 @@
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.template import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins from django.template import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins
from django.utils.importlib import import_module
from django.conf import settings from django.conf import settings
template_source_loaders = None template_source_loaders = None
@ -51,7 +52,7 @@ def find_template_source(name, dirs=None):
i = path.rfind('.') i = path.rfind('.')
module, attr = path[:i], path[i+1:] module, attr = path[:i], path[i+1:]
try: try:
mod = __import__(module, globals(), locals(), [attr]) mod = import_module(module)
except ImportError, e: except ImportError, e:
raise ImproperlyConfigured, 'Error importing template source loader %s: "%s"' % (module, e) raise ImproperlyConfigured, 'Error importing template source loader %s: "%s"' % (module, e)
try: try:

View File

@ -10,21 +10,14 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.template import TemplateDoesNotExist from django.template import TemplateDoesNotExist
from django.utils._os import safe_join from django.utils._os import safe_join
from django.utils.importlib import import_module
# At compile time, cache the directories to search. # At compile time, cache the directories to search.
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
app_template_dirs = [] app_template_dirs = []
for app in settings.INSTALLED_APPS: for app in settings.INSTALLED_APPS:
i = app.rfind('.')
if i == -1:
m, a = app, None
else:
m, a = app[:i], app[i+1:]
try: try:
if a is None: mod = import_module(app)
mod = __import__(m, {}, {}, [])
else:
mod = getattr(__import__(m, {}, {}, [a]), a)
except ImportError, e: except ImportError, e:
raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0]) raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0])
template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates') template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')

View File

@ -1,7 +1,8 @@
from django.conf import settings from django.conf import settings
from django.utils import importlib
for a in settings.INSTALLED_APPS: for a in settings.INSTALLED_APPS:
try: try:
__path__.extend(__import__(a + '.templatetags', {}, {}, ['']).__path__) __path__.extend(importlib.import_module('.templatetags', a).__path__)
except ImportError: except ImportError:
pass pass

View File

@ -18,6 +18,7 @@ from django.test import signals
from django.utils.functional import curry from django.utils.functional import curry
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils.importlib import import_module
from django.utils.itercompat import is_iterable from django.utils.itercompat import is_iterable
from django.db import transaction, close_connection from django.db import transaction, close_connection
from django.test.utils import ContextList from django.test.utils import ContextList
@ -176,7 +177,7 @@ class Client(object):
Obtains the current session variables. Obtains the current session variables.
""" """
if 'django.contrib.sessions' in settings.INSTALLED_APPS: if 'django.contrib.sessions' in settings.INSTALLED_APPS:
engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) engine = import_module(settings.SESSION_ENGINE)
cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None) cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
if cookie: if cookie:
return engine.SessionStore(cookie.value) return engine.SessionStore(cookie.value)
@ -399,7 +400,7 @@ class Client(object):
user = authenticate(**credentials) user = authenticate(**credentials)
if user and user.is_active \ if user and user.is_active \
and 'django.contrib.sessions' in settings.INSTALLED_APPS: and 'django.contrib.sessions' in settings.INSTALLED_APPS:
engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) engine = import_module(settings.SESSION_ENGINE)
# Create a fake request to store login details. # Create a fake request to store login details.
request = HttpRequest() request = HttpRequest()
@ -434,7 +435,7 @@ class Client(object):
Causes the authenticated user to be logged out. Causes the authenticated user to be logged out.
""" """
session = __import__(settings.SESSION_ENGINE, {}, {}, ['']).SessionStore() session = import_module(settings.SESSION_ENGINE).SessionStore()
session.delete(session_key=self.cookies[settings.SESSION_COOKIE_NAME].value) session.delete(session_key=self.cookies[settings.SESSION_COOKIE_NAME].value)
self.cookies = SimpleCookie() self.cookies = SimpleCookie()

36
django/utils/importlib.py Normal file
View File

@ -0,0 +1,36 @@
# Taken from Python 2.7 with permission from/by the original author.
import sys
def _resolve_name(name, package, level):
"""Return the absolute name of the module to be imported."""
if not hasattr(package, 'rindex'):
raise ValueError("'package' not set to a string")
dot = len(package)
for x in xrange(level, 1, -1):
try:
dot = package.rindex('.', 0, dot)
except ValueError:
raise ValueError("attempted relative import beyond top-level "
"package")
return "%s.%s" % (package[:dot], name)
def import_module(name, package=None):
"""Import a module.
The 'package' argument is required when performing a relative import. It
specifies the package to use as the anchor point from which to resolve the
relative import to an absolute import.
"""
if name.startswith('.'):
if not package:
raise TypeError("relative imports require the 'package' argument")
level = 0
for character in name:
if character != '.':
break
level += 1
name = _resolve_name(name[level:], package, level)
__import__(name)
return sys.modules[name]

View File

@ -7,6 +7,7 @@ import sys
import gettext as gettext_module import gettext as gettext_module
from cStringIO import StringIO from cStringIO import StringIO
from django.utils.importlib import import_module
from django.utils.safestring import mark_safe, SafeData from django.utils.safestring import mark_safe, SafeData
from django.utils.thread_support import currentThread from django.utils.thread_support import currentThread
@ -125,7 +126,7 @@ def translation(language):
if settings.SETTINGS_MODULE is not None: if settings.SETTINGS_MODULE is not None:
parts = settings.SETTINGS_MODULE.split('.') parts = settings.SETTINGS_MODULE.split('.')
project = __import__(parts[0], {}, {}, []) project = import_module(parts[0])
projectpath = os.path.join(os.path.dirname(project.__file__), 'locale') projectpath = os.path.join(os.path.dirname(project.__file__), 'locale')
else: else:
projectpath = None projectpath = None
@ -176,12 +177,7 @@ def translation(language):
res = _merge(projectpath) res = _merge(projectpath)
for appname in settings.INSTALLED_APPS: for appname in settings.INSTALLED_APPS:
p = appname.rfind('.') app = import_module(appname)
if p >= 0:
app = getattr(__import__(appname[:p], {}, {}, [appname[p+1:]]), appname[p+1:])
else:
app = __import__(appname, {}, {}, [])
apppath = os.path.join(os.path.dirname(app.__file__), 'locale') apppath = os.path.join(os.path.dirname(app.__file__), 'locale')
if os.path.isdir(apppath): if os.path.isdir(apppath):

View File

@ -6,6 +6,7 @@ import datetime
from django.conf import settings from django.conf import settings
from django.template import Template, Context, TemplateDoesNotExist from django.template import Template, Context, TemplateDoesNotExist
from django.utils.html import escape from django.utils.html import escape
from django.utils.importlib import import_module
from django.http import HttpResponse, HttpResponseServerError, HttpResponseNotFound from django.http import HttpResponse, HttpResponseServerError, HttpResponseNotFound
from django.utils.encoding import smart_unicode, smart_str from django.utils.encoding import smart_unicode, smart_str
@ -67,7 +68,8 @@ class ExceptionReporter:
self.loader_debug_info = [] self.loader_debug_info = []
for loader in template_source_loaders: for loader in template_source_loaders:
try: try:
source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources') module = import_module(loader.__module__)
source_list_func = module.get_template_sources
# NOTE: This assumes exc_value is the name of the template that # NOTE: This assumes exc_value is the name of the template that
# the loader attempted to load. # the loader attempted to load.
template_list = [{'name': t, 'exists': os.path.exists(t)} \ template_list = [{'name': t, 'exists': os.path.exists(t)} \

View File

@ -1,7 +1,8 @@
from django import http from django import http
from django.conf import settings
from django.utils import importlib
from django.utils.translation import check_for_language, activate, to_locale, get_language from django.utils.translation import check_for_language, activate, to_locale, get_language
from django.utils.text import javascript_quote from django.utils.text import javascript_quote
from django.conf import settings
import os import os
import gettext as gettext_module import gettext as gettext_module
@ -128,7 +129,7 @@ def javascript_catalog(request, domain='djangojs', packages=None):
paths = [] paths = []
# first load all english languages files for defaults # first load all english languages files for defaults
for package in packages: for package in packages:
p = __import__(package, {}, {}, ['']) p = importlib.import_module(package)
path = os.path.join(os.path.dirname(p.__file__), 'locale') path = os.path.join(os.path.dirname(p.__file__), 'locale')
paths.append(path) paths.append(path)
try: try: