Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Factor out some common pieces of django.conf.LazySettings.

This is in preparation for some reuse elsewhere in the core code.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9945 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit cf3071242a289e20526ade81021b1f895fde706d 1 parent ec71022
Malcolm Tredinnick malcolmt authored
35 django/conf/__init__.py
View
@@ -8,40 +8,19 @@
import os
import time # Needed for Windows
+
from django.conf import global_settings
+from django.utils.functional import LazyObject
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
-class LazySettings(object):
+class LazySettings(LazyObject):
"""
A lazy proxy for either global Django settings or a custom settings object.
The user can manually configure settings prior to using them. Otherwise,
Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
"""
- def __init__(self):
- # _target must be either None or something that supports attribute
- # access (getattr, hasattr, etc).
- self._target = None
-
- def __getattr__(self, name):
- if self._target is None:
- self._import_settings()
- if name == '__members__':
- # Used to implement dir(obj), for example.
- return self._target.get_all_members()
- return getattr(self._target, name)
-
- def __setattr__(self, name, value):
- if name == '_target':
- # Assign directly to self.__dict__, because otherwise we'd call
- # __setattr__(), which would be an infinite loop.
- self.__dict__['_target'] = value
- else:
- if self._target is None:
- self._import_settings()
- setattr(self._target, name, value)
-
- def _import_settings(self):
+ def _setup(self):
"""
Load the settings module pointed to by the environment variable. This
is used the first time we need any settings at all, if the user has not
@@ -56,7 +35,7 @@ def _import_settings(self):
# problems with Python's interactive help.
raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE)
- self._target = Settings(settings_module)
+ self._wrapped = Settings(settings_module)
def configure(self, default_settings=global_settings, **options):
"""
@@ -69,13 +48,13 @@ def configure(self, default_settings=global_settings, **options):
holder = UserSettingsHolder(default_settings)
for name, value in options.items():
setattr(holder, name, value)
- self._target = holder
+ self._wrapped = holder
def configured(self):
"""
Returns True if the settings have already been configured.
"""
- return bool(self._target)
+ return bool(self._wrapped)
configured = property(configured)
class Settings(object):
36 django/utils/functional.py
View
@@ -251,3 +251,39 @@ def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return lazy(func, *resultclasses)(*args, **kwargs)
return wraps(func)(wrapper)
+
+class LazyObject(object):
+ """
+ A wrapper for another class that can be used to delay instantiation of the
+ wrapped class.
+
+ This is useful, for example, if the wrapped class needs to use Django
+ settings at creation time: we want to permit it to be imported without
+ accessing settings.
+ """
+ def __init__(self):
+ self._wrapped = None
+
+ def __getattr__(self, name):
+ if self._wrapped is None:
+ self._setup()
+ if name == "__members__":
+ # Used to implement dir(obj)
+ return self._wrapped.get_all_members()
+ return getattr(self._wrapped, name)
+
+ def __setattr__(self, name, value):
+ if name == "_wrapped":
+ # Assign to __dict__ to avoid infinite __setattr__ loops.
+ self.__dict__["_wrapped"] = value
+ else:
+ if self._wrapped is None:
+ self._setup()
+ setattr(self._wrapped, name, value)
+
+ def _setup(self):
+ """
+ Must be implemented by subclasses to initialise the wrapped object.
+ """
+ raise NotImplementedError
+
2  tests/regressiontests/comment_tests/tests/app_api_tests.py
View
@@ -41,7 +41,7 @@ def tearDown(self):
del settings.INSTALLED_APPS[-1]
settings.COMMENTS_APP = self.old_comments_app
if settings.COMMENTS_APP is None:
- delattr(settings._target, 'COMMENTS_APP')
+ delattr(settings._wrapped, 'COMMENTS_APP')
def testGetCommentApp(self):
from regressiontests.comment_tests import custom_comments
Please sign in to comment.
Something went wrong with that request. Please try again.