Permalink
Browse files

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
  • Loading branch information...
1 parent ee2f04d commit c485e236bd7e5ea40c64b2fe54d85dbb15b2fd39 @jacobian jacobian committed Mar 18, 2009
View
@@ -75,6 +75,7 @@ answer newbie questions, and generally made Django that much better:
Chris Cahoon <chris.cahoon@gmail.com>
Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com>
Trevor Caira <trevor@caira.com>
+ Brett Cannon <brett@python.org>
Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
Jeremy Carbaugh <jcarbaugh@gmail.com>
carljm <carl@dirtcircle.com>
View
@@ -12,6 +12,7 @@
from django.conf import global_settings
from django.utils.functional import LazyObject
+from django.utils import importlib
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
@@ -69,7 +70,7 @@ def __init__(self, settings_module):
self.SETTINGS_MODULE = settings_module
try:
- mod = __import__(self.SETTINGS_MODULE, {}, {}, [''])
+ mod = importlib.import_module(self.SETTINGS_MODULE)
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)
@@ -89,7 +90,8 @@ def __init__(self, settings_module):
new_installed_apps = []
for app in self.INSTALLED_APPS:
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.sort()
name_pattern = re.compile(r'[a-zA-Z]\w*')
@@ -1,6 +1,7 @@
from django.contrib.admin.options import ModelAdmin, HORIZONTAL, VERTICAL
from django.contrib.admin.options import StackedInline, TabularInline
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
# True while running, and False when it finishes.
@@ -36,7 +37,7 @@ def autodiscover():
# fails silently -- apps that do weird things with __path__ might
# need to roll their own admin registration.
try:
- app_path = __import__(app, {}, {}, [app.split('.')[-1]]).__path__
+ app_path = import_module(app).__path__
except AttributeError:
continue
@@ -51,6 +52,6 @@ def autodiscover():
# Step 3: import the app's admin file. If this has errors we want them
# to bubble up.
- __import__("%s.admin" % app)
+ import_module("%s.admin" % app)
# autodiscover was successful, reset loading flag.
LOADING = False
@@ -4,6 +4,7 @@
from django.shortcuts import render_to_response
from django.contrib.sites.models import Site
from django.conf import settings
+from django.utils.importlib import import_module
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
settings_modules = {}
for mod in settings.ADMIN_FOR:
- settings_module = __import__(mod, {}, {}, [''])
+ settings_module = import_module(mod)
settings_modules[settings_module.SITE_ID] = settings_module
site_list = Site.objects.in_bulk(settings_modules.keys()).values()
if request.POST:
@@ -9,6 +9,7 @@
from django.core import urlresolvers
from django.contrib.admindocs import utils
from django.contrib.sites.models import Site
+from django.utils.importlib import import_module
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
import inspect, os, re
@@ -114,13 +115,13 @@ def view_index(request):
return missing_docutils_page(request)
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:
settings_modules = [settings]
views = []
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)
if Site._meta.installed:
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)
try:
- view_func = getattr(__import__(mod, {}, {}, ['']), func)
+ view_func = getattr(import_module(mod), func)
except (ImportError, AttributeError):
raise Http404
title, body, metadata = utils.parse_docstring(view_func.__doc__)
@@ -257,7 +258,7 @@ def model_detail(request, app_label, model_name):
def template_detail(request, template):
templates = []
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:
site_obj = Site.objects.get(pk=settings_mod.SITE_ID)
else:
@@ -1,5 +1,6 @@
import datetime
from django.core.exceptions import ImproperlyConfigured
+from django.utils.importlib import import_module
SESSION_KEY = '_auth_user_id'
BACKEND_SESSION_KEY = '_auth_user_backend'
@@ -9,7 +10,7 @@ def load_backend(path):
i = path.rfind('.')
module, attr = path[:i], path[i+1:]
try:
- mod = __import__(module, {}, {}, [attr])
+ mod = import_module(module)
except ImportError, e:
raise ImproperlyConfigured, 'Error importing authentication backend %s: "%s"' % (module, e)
except ValueError, e:
@@ -3,6 +3,7 @@
from django.core.exceptions import ImproperlyConfigured
from django.contrib.comments.models import Comment
from django.contrib.comments.forms import CommentForm
+from django.utils.importlib import import_module
DEFAULT_COMMENTS_APP = 'django.contrib.comments'
@@ -18,7 +19,7 @@ def get_comment_app():
# Try to import the package
try:
- package = __import__(comments_app, '', '', [''])
+ package = import_module(comments_app)
except ImportError:
raise ImproperlyConfigured("The COMMENTS_APP setting refers to "\
"a non-existing package.")
@@ -3,10 +3,11 @@
from django.conf import settings
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date
+from django.utils.importlib import import_module
class SessionMiddleware(object):
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)
request.session = engine.SessionStore(session_key)
@@ -19,6 +19,7 @@
from django.conf import settings
from django.core import signals
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.
# 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):
scheme, host, params = parse_backend_uri(backend_uri)
if scheme in BACKENDS:
- module = __import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, [''])
+ name = 'django.core.cache.backends.%s' % BACKENDS[scheme]
else:
- module = __import__(scheme, {}, {}, [''])
+ name = scheme
+ module = importlib.import_module(name)
return getattr(module, 'CacheClass')(host, params)
cache = get_cache(settings.CACHE_BACKEND)
@@ -8,6 +8,7 @@
from django.core.files.move import file_move_safe
from django.utils.encoding import force_unicode
from django.utils.functional import LazyObject
+from django.utils.importlib import import_module
from django.utils.text import get_valid_filename
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)
module, classname = import_path[:dot], import_path[dot+1:]
try:
- mod = __import__(module, {}, {}, [''])
+ mod = import_module(module)
except ImportError, e:
raise ImproperlyConfigured('Error importing storage module %s: "%s"' % (module, e))
try:
@@ -10,6 +10,7 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile
+from django.utils import importlib
__all__ = ['UploadFileException','StopUpload', 'SkipFile', 'FileUploadHandler',
'TemporaryFileUploadHandler', 'MemoryFileUploadHandler',
@@ -201,7 +202,7 @@ def load_handler(path, *args, **kwargs):
i = path.rfind('.')
module, attr = path[:i], path[i+1:]
try:
- mod = __import__(module, {}, {}, [attr])
+ mod = importlib.import_module(module)
except ImportError, e:
raise ImproperlyConfigured('Error importing upload handler module %s: "%s"' % (module, e))
except ValueError, e:
@@ -3,6 +3,7 @@
from django import http
from django.core import signals
from django.utils.encoding import force_unicode
+from django.utils.importlib import import_module
class BaseHandler(object):
# Changes that are always applied to a response (in this order).
@@ -36,7 +37,7 @@ def load_middleware(self):
raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
try:
- mod = __import__(mw_module, {}, {}, [''])
+ mod = import_module(mw_module)
except ImportError, e:
raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
try:
@@ -5,6 +5,7 @@
import django
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.
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
(ImportError, AttributeError) are allowed to propagate.
"""
- return getattr(__import__('%s.management.commands.%s' % (app_name, name),
- {}, {}, ['Command']), 'Command')()
+ module = import_module('%s.management.commands.%s' % (app_name, name))
+ return module.Command()
def get_commands():
"""
@@ -104,12 +105,9 @@ def get_commands():
# Find the project directory
try:
from django.conf import settings
- project_directory = setup_environ(
- __import__(
- settings.SETTINGS_MODULE, {}, {},
- (settings.SETTINGS_MODULE.split(".")[-1],)
- ), settings.SETTINGS_MODULE
- )
+ module = import_module(settings.SETTINGS_MODULE.split('.', 1)[0])
+ project_directory = setup_environ(module,
+ settings.SETTINGS_MODULE)
except (AttributeError, EnvironmentError, ImportError):
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
# avoid some of the path errors new users can have.
sys.path.append(os.path.join(project_directory, os.pardir))
- project_module = __import__(project_name, {}, {}, [''])
+ project_module = import_module(project_name)
sys.path.pop()
return project_directory
@@ -1,5 +1,6 @@
from django.core.management.base import NoArgsCommand, CommandError
from django.core.management.color import no_style
+from django.utils.importlib import import_module
from optparse import make_option
class Command(NoArgsCommand):
@@ -23,7 +24,7 @@ def handle_noargs(self, **options):
# dispatcher events.
for app_name in settings.INSTALLED_APPS:
try:
- __import__(app_name + '.management', {}, {}, [''])
+ import_module('.management', app_name)
except ImportError:
pass
@@ -1,6 +1,7 @@
import os
from django.core.management.base import copy_helper, CommandError, LabelCommand
+from django.utils.importlib import import_module
class Command(LabelCommand):
help = "Creates a Django app directory structure for the given app name in the current directory."
@@ -26,7 +27,7 @@ def handle_label(self, app_name, directory=None, **options):
# Check that the app_name cannot be imported.
try:
- __import__(app_name)
+ import_module(app_name)
except ImportError:
pass
else:
@@ -1,4 +1,5 @@
from django.core.management.base import copy_helper, CommandError, LabelCommand
+from django.utils.importlib import import_module
import os
import re
from random import choice
@@ -20,7 +21,7 @@ def handle_label(self, project_name, **options):
# Check that the project_name cannot be imported.
try:
- __import__(project_name)
+ import_module(project_name)
except ImportError:
pass
else:
@@ -1,5 +1,6 @@
from django.core.management.base import NoArgsCommand
from django.core.management.color import no_style
+from django.utils.importlib import import_module
from optparse import make_option
import sys
@@ -30,7 +31,7 @@ def handle_noargs(self, **options):
# dispatcher events.
for app_name in settings.INSTALLED_APPS:
try:
- __import__(app_name + '.management', {}, {}, [''])
+ import_module('.management', app_name)
except ImportError, exc:
# This is slightly hackish. We want to ignore ImportErrors
# if the "management" module itself is missing -- but we don't
@@ -17,6 +17,7 @@
"""
from django.conf import settings
+from django.utils import importlib
# Built-in 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 is not a thread-safe operation.
"""
- module = __import__(serializer_module, {}, {}, [''])
+ module = importlib.import_module(serializer_module)
if serializers is None:
_serializers[format] = module
else:
@@ -12,6 +12,7 @@
pass to this server.
"""
+from django.utils import importlib
import sys, os
__version__ = "0.1"
@@ -113,7 +114,7 @@ def runfastcgi(argset=[], **kwargs):
'maxSpare': int(options["maxspare"]),
'minSpare': int(options["minspare"]),
'maxChildren': int(options["maxchildren"]),
- 'maxRequests': int(options["maxrequests"]),
+ 'maxRequests': int(options["maxrequests"]),
}
flup_module += '_fork'
elif options['method'] in ('thread', 'threaded'):
@@ -128,7 +129,8 @@ def runfastcgi(argset=[], **kwargs):
wsgi_opts['debug'] = False # Turn off flup tracebacks
try:
- WSGIServer = getattr(__import__('flup.' + flup_module, '', '', flup_module), 'WSGIServer')
+ module = importlib_import_module('.%s' % flup_module, 'flup')
+ WSGIServer = module.WSGIServer
except:
print "Can't import flup." + flup_module
return False
Oops, something went wrong.

0 comments on commit c485e23

Please sign in to comment.